// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2021 Intel Corporation
 * Author: Johannes Berg <johannes@sipsolutions.net>
 */
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/logic_iomem.h>
#include <asm/io.h>

struct logic_iomem_region {
	const struct resource *res;
	const struct logic_iomem_region_ops *ops;
	struct list_head list;
};

struct logic_iomem_area {
	const struct logic_iomem_ops *ops;
	void *priv;
};

#define AREA_SHIFT	24
#define MAX_AREA_SIZE	(1 << AREA_SHIFT)
#define MAX_AREAS	((1U << 31) / MAX_AREA_SIZE)
#define AREA_BITS	((MAX_AREAS - 1) << AREA_SHIFT)
#define AREA_MASK	(MAX_AREA_SIZE - 1)
#ifdef CONFIG_64BIT
#define IOREMAP_BIAS	0xDEAD000000000000UL
#define IOREMAP_MASK	0xFFFFFFFF00000000UL
#else
#define IOREMAP_BIAS	0x80000000UL
#define IOREMAP_MASK	0x80000000UL
#endif

static DEFINE_MUTEX(regions_mtx);
static LIST_HEAD(regions_list);
static struct logic_iomem_area mapped_areas[MAX_AREAS];

int logic_iomem_add_region(struct resource *resource,
			   const struct logic_iomem_region_ops *ops)
{
	struct logic_iomem_region *rreg;
	int err;

	if (WARN_ON(!resource || !ops))
		return -EINVAL;

	if (WARN_ON((resource->flags & IORESOURCE_TYPE_BITS) != IORESOURCE_MEM))
		return -EINVAL;

	rreg = kzalloc_obj(*rreg);
	if (!rreg)
		return -ENOMEM;

	err = request_resource(&iomem_resource, resource);
	if (err) {
		kfree(rreg);
		return -ENOMEM;
	}

	mutex_lock(&regions_mtx);
	rreg->res = resource;
	rreg->ops = ops;
	list_add_tail(&rreg->list, &regions_list);
	mutex_unlock(&regions_mtx);

	return 0;
}
EXPORT_SYMBOL(logic_iomem_add_region);

#ifndef CONFIG_INDIRECT_IOMEM_FALLBACK
static void __iomem *real_ioremap(phys_addr_t offset, size_t size)
{
	WARN(1, "invalid ioremap(0x%llx, 0x%zx)\n",
	     (unsigned long long)offset, size);
	return NULL;
}

static void real_iounmap(volatile void __iomem *addr)
{
	WARN(1, "invalid iounmap for addr 0x%llx\n",
	     (unsigned long long)(uintptr_t __force)addr);
}
#endif /* CONFIG_INDIRECT_IOMEM_FALLBACK */

void __iomem *ioremap(phys_addr_t offset, size_t size)
{
	void __iomem *ret = NULL;
	struct logic_iomem_region *rreg, *found = NULL;
	int i;

	mutex_lock(&regions_mtx);
	list_for_each_entry(rreg, &regions_list, list) {
		if (rreg->res->start > offset)
			continue;
		if (rreg->res->end < offset + size - 1)
			continue;
		found = rreg;
		break;
	}

	if (!found)
		goto out;

	for (i = 0; i < MAX_AREAS; i++) {
		long offs;

		if (mapped_areas[i].ops)
			continue;

		offs = rreg->ops->map(offset - found->res->start,
				      size, &mapped_areas[i].ops,
				      &mapped_areas[i].priv);
		if (offs < 0) {
			mapped_areas[i].ops = NULL;
			break;
		}

		if (WARN_ON(!mapped_areas[i].ops)) {
			mapped_areas[i].ops = NULL;
			break;
		}

		ret = (void __iomem *)(IOREMAP_BIAS + (i << AREA_SHIFT) + offs);
		break;
	}
out:
	mutex_unlock(&regions_mtx);
	if (ret)
		return ret;
	return real_ioremap(offset, size);
}
EXPORT_SYMBOL(ioremap);

static inline struct logic_iomem_area *
get_area(const volatile void __iomem *addr)
{
	unsigned long a = (unsigned long)addr;
	unsigned int idx;

	if (WARN_ON((a & IOREMAP_MASK) != IOREMAP_BIAS))
		return NULL;

	idx = (a & AREA_BITS) >> AREA_SHIFT;

	if (mapped_areas[idx].ops)
		return &mapped_areas[idx];

	return NULL;
}

void iounmap(volatile void __iomem *addr)
{
	struct logic_iomem_area *area = get_area(addr);

	if (!area) {
		real_iounmap(addr);
		return;
	}

	if (area->ops->unmap)
		area->ops->unmap(area->priv);

	mutex_lock(&regions_mtx);
	area->ops = NULL;
	area->priv = NULL;
	mutex_unlock(&regions_mtx);
}
EXPORT_SYMBOL(iounmap);

#ifndef CONFIG_INDIRECT_IOMEM_FALLBACK
#define MAKE_FALLBACK(op, sz) 						\
static u##sz real_raw_read ## op(const volatile void __iomem *addr)	\
{									\
	WARN(1, "Invalid read" #op " at address %llx\n",		\
	     (unsigned long long)(uintptr_t __force)addr);		\
	return (u ## sz)~0ULL;						\
}									\
									\
static void real_raw_write ## op(u ## sz val,				\
				 volatile void __iomem *addr)		\
{									\
	WARN(1, "Invalid writeq" #op " of 0x%llx at address %llx\n",	\
	     (unsigned long long)val,					\
	     (unsigned long long)(uintptr_t __force)addr);\
}									\

MAKE_FALLBACK(b, 8);
MAKE_FALLBACK(w, 16);
MAKE_FALLBACK(l, 32);
#ifdef CONFIG_64BIT
MAKE_FALLBACK(q, 64);
#endif

static void real_memset_io(volatile void __iomem *addr, int value, size_t size)
{
	WARN(1, "Invalid memset_io at address 0x%llx\n",
	     (unsigned long long)(uintptr_t __force)addr);
}

static void real_memcpy_fromio(void *buffer, const volatile void __iomem *addr,
			       size_t size)
{
	WARN(1, "Invalid memcpy_fromio at address 0x%llx\n",
	     (unsigned long long)(uintptr_t __force)addr);

	memset(buffer, 0xff, size);
}

static void real_memcpy_toio(volatile void __iomem *addr, const void *buffer,
			     size_t size)
{
	WARN(1, "Invalid memcpy_toio at address 0x%llx\n",
	     (unsigned long long)(uintptr_t __force)addr);
}
#endif /* CONFIG_INDIRECT_IOMEM_FALLBACK */

#define MAKE_OP(op, sz) 						\
u##sz __raw_read ## op(const volatile void __iomem *addr)		\
{									\
	struct logic_iomem_area *area = get_area(addr);			\
									\
	if (!area)							\
		return real_raw_read ## op(addr);			\
									\
	return (u ## sz) area->ops->read(area->priv,			\
					 (unsigned long)addr & AREA_MASK,\
					 sz / 8);			\
}									\
EXPORT_SYMBOL(__raw_read ## op);					\
									\
void __raw_write ## op(u ## sz val, volatile void __iomem *addr)	\
{									\
	struct logic_iomem_area *area = get_area(addr);			\
									\
	if (!area) {							\
		real_raw_write ## op(val, addr);			\
		return;							\
	}								\
									\
	area->ops->write(area->priv,					\
			 (unsigned long)addr & AREA_MASK,		\
			 sz / 8, val);					\
}									\
EXPORT_SYMBOL(__raw_write ## op)

MAKE_OP(b, 8);
MAKE_OP(w, 16);
MAKE_OP(l, 32);
#ifdef CONFIG_64BIT
MAKE_OP(q, 64);
#endif

void memset_io(volatile void __iomem *addr, int value, size_t size)
{
	struct logic_iomem_area *area = get_area(addr);
	unsigned long offs, start;

	if (!area) {
		real_memset_io(addr, value, size);
		return;
	}

	start = (unsigned long)addr & AREA_MASK;

	if (area->ops->set) {
		area->ops->set(area->priv, start, value, size);
		return;
	}

	for (offs = 0; offs < size; offs++)
		area->ops->write(area->priv, start + offs, 1, value);
}
EXPORT_SYMBOL(memset_io);

void memcpy_fromio(void *buffer, const volatile void __iomem *addr,
                   size_t size)
{
	struct logic_iomem_area *area = get_area(addr);
	u8 *buf = buffer;
	unsigned long offs, start;

	if (!area) {
		real_memcpy_fromio(buffer, addr, size);
		return;
	}

	start = (unsigned long)addr & AREA_MASK;

	if (area->ops->copy_from) {
		area->ops->copy_from(area->priv, buffer, start, size);
		return;
	}

	for (offs = 0; offs < size; offs++)
		buf[offs] = area->ops->read(area->priv, start + offs, 1);
}
EXPORT_SYMBOL(memcpy_fromio);

void memcpy_toio(volatile void __iomem *addr, const void *buffer, size_t size)
{
	struct logic_iomem_area *area = get_area(addr);
	const u8 *buf = buffer;
	unsigned long offs, start;

	if (!area) {
		real_memcpy_toio(addr, buffer, size);
		return;
	}

	start = (unsigned long)addr & AREA_MASK;

	if (area->ops->copy_to) {
		area->ops->copy_to(area->priv, start, buffer, size);
		return;
	}

	for (offs = 0; offs < size; offs++)
		area->ops->write(area->priv, start + offs, 1, buf[offs]);
}
EXPORT_SYMBOL(memcpy_toio);
