/*
 * Bus driver for MIPS Common Device Memory Map (CDMM).
 *
 * Copyright (C) 2014-2015 Imagination Technologies Ltd.
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 */

#include <linux/atomic.h>
#include <linux/err.h>
#include <linux/cpu.h>
#include <linux/cpumask.h>
#include <linux/io.h>
#include <linux/of_address.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/smp.h>
#include <asm/cdmm.h>
#include <asm/hazards.h>
#include <asm/mipsregs.h>

/* Access control and status register fields */
#define CDMM_ACSR_DEVTYPE_SHIFT	24
#define CDMM_ACSR_DEVTYPE	(255ul << CDMM_ACSR_DEVTYPE_SHIFT)
#define CDMM_ACSR_DEVSIZE_SHIFT	16
#define CDMM_ACSR_DEVSIZE	(31ul << CDMM_ACSR_DEVSIZE_SHIFT)
#define CDMM_ACSR_DEVREV_SHIFT	12
#define CDMM_ACSR_DEVREV	(15ul << CDMM_ACSR_DEVREV_SHIFT)
#define CDMM_ACSR_UW		(1ul << 3)
#define CDMM_ACSR_UR		(1ul << 2)
#define CDMM_ACSR_SW		(1ul << 1)
#define CDMM_ACSR_SR		(1ul << 0)

/* Each block of device registers is 64 bytes */
#define CDMM_DRB_SIZE		64

#define to_mips_cdmm_driver(d)	container_of_const(d, struct mips_cdmm_driver, drv)

/* Default physical base address */
static phys_addr_t mips_cdmm_default_base;

/* Bus operations */

static const struct mips_cdmm_device_id *
mips_cdmm_lookup(const struct mips_cdmm_device_id *table,
		 struct mips_cdmm_device *dev)
{
	int ret = 0;

	for (; table->type; ++table) {
		ret = (dev->type == table->type);
		if (ret)
			break;
	}

	return ret ? table : NULL;
}

static int mips_cdmm_match(struct device *dev, const struct device_driver *drv)
{
	struct mips_cdmm_device *cdev = to_mips_cdmm_device(dev);
	const struct mips_cdmm_driver *cdrv = to_mips_cdmm_driver(drv);

	return mips_cdmm_lookup(cdrv->id_table, cdev) != NULL;
}

static int mips_cdmm_uevent(const struct device *dev, struct kobj_uevent_env *env)
{
	const struct mips_cdmm_device *cdev = to_mips_cdmm_device(dev);
	int retval = 0;

	retval = add_uevent_var(env, "CDMM_CPU=%u", cdev->cpu);
	if (retval)
		return retval;

	retval = add_uevent_var(env, "CDMM_TYPE=0x%02x", cdev->type);
	if (retval)
		return retval;

	retval = add_uevent_var(env, "CDMM_REV=%u", cdev->rev);
	if (retval)
		return retval;

	retval = add_uevent_var(env, "MODALIAS=mipscdmm:t%02X", cdev->type);
	return retval;
}

/* Device attributes */

#define CDMM_ATTR(name, fmt, arg...)					\
static ssize_t name##_show(struct device *_dev,				\
			   struct device_attribute *attr, char *buf)	\
{									\
	struct mips_cdmm_device *dev = to_mips_cdmm_device(_dev);	\
	return sprintf(buf, fmt, arg);					\
}									\
static DEVICE_ATTR_RO(name);

CDMM_ATTR(cpu, "%u\n", dev->cpu);
CDMM_ATTR(type, "0x%02x\n", dev->type);
CDMM_ATTR(revision, "%u\n", dev->rev);
CDMM_ATTR(modalias, "mipscdmm:t%02X\n", dev->type);
CDMM_ATTR(resource, "\t%016llx\t%016llx\t%016lx\n",
	  (unsigned long long)dev->res.start,
	  (unsigned long long)dev->res.end,
	  dev->res.flags);

static struct attribute *mips_cdmm_dev_attrs[] = {
	&dev_attr_cpu.attr,
	&dev_attr_type.attr,
	&dev_attr_revision.attr,
	&dev_attr_modalias.attr,
	&dev_attr_resource.attr,
	NULL,
};
ATTRIBUTE_GROUPS(mips_cdmm_dev);

const struct bus_type mips_cdmm_bustype = {
	.name		= "cdmm",
	.dev_groups	= mips_cdmm_dev_groups,
	.match		= mips_cdmm_match,
	.uevent		= mips_cdmm_uevent,
};
EXPORT_SYMBOL_GPL(mips_cdmm_bustype);

/*
 * Standard driver callback helpers.
 *
 * All the CDMM driver callbacks need to be executed on the appropriate CPU from
 * workqueues. For the standard driver callbacks we need a work function
 * (mips_cdmm_{void,int}_work()) to do the actual call from the right CPU, and a
 * wrapper function (generated with BUILD_PERCPU_HELPER) to arrange for the work
 * function to be called on that CPU.
 */

/**
 * struct mips_cdmm_work_dev - Data for per-device call work.
 * @fn:		CDMM driver callback function to call for the device.
 * @dev:	CDMM device to pass to @fn.
 */
struct mips_cdmm_work_dev {
	void			*fn;
	struct mips_cdmm_device *dev;
};

/**
 * mips_cdmm_void_work() - Call a void returning CDMM driver callback.
 * @data:	struct mips_cdmm_work_dev pointer.
 *
 * A work_on_cpu() callback function to call an arbitrary CDMM driver callback
 * function which doesn't return a value.
 */
static long mips_cdmm_void_work(void *data)
{
	struct mips_cdmm_work_dev *work = data;
	void (*fn)(struct mips_cdmm_device *) = work->fn;

	fn(work->dev);
	return 0;
}

/**
 * mips_cdmm_int_work() - Call an int returning CDMM driver callback.
 * @data:	struct mips_cdmm_work_dev pointer.
 *
 * A work_on_cpu() callback function to call an arbitrary CDMM driver callback
 * function which returns an int.
 */
static long mips_cdmm_int_work(void *data)
{
	struct mips_cdmm_work_dev *work = data;
	int (*fn)(struct mips_cdmm_device *) = work->fn;

	return fn(work->dev);
}

#define _BUILD_RET_void
#define _BUILD_RET_int	return

/**
 * BUILD_PERCPU_HELPER() - Helper to call a CDMM driver callback on right CPU.
 * @_ret:	Return type (void or int).
 * @_name:	Name of CDMM driver callback function.
 *
 * Generates a specific device callback function to call a CDMM driver callback
 * function on the appropriate CPU for the device, and if applicable return the
 * result.
 */
#define BUILD_PERCPU_HELPER(_ret, _name)				\
static _ret mips_cdmm_##_name(struct device *dev)			\
{									\
	struct mips_cdmm_device *cdev = to_mips_cdmm_device(dev);	\
	struct mips_cdmm_driver *cdrv = to_mips_cdmm_driver(dev->driver); \
	struct mips_cdmm_work_dev work = {				\
		.fn	= cdrv->_name,					\
		.dev	= cdev,						\
	};								\
									\
	_BUILD_RET_##_ret work_on_cpu(cdev->cpu,			\
				      mips_cdmm_##_ret##_work, &work);	\
}

/* Driver callback functions */
BUILD_PERCPU_HELPER(int, probe)     /* int mips_cdmm_probe(struct device) */
BUILD_PERCPU_HELPER(int, remove)    /* int mips_cdmm_remove(struct device) */
BUILD_PERCPU_HELPER(void, shutdown) /* void mips_cdmm_shutdown(struct device) */


/* Driver registration */

/**
 * mips_cdmm_driver_register() - Register a CDMM driver.
 * @drv:	CDMM driver information.
 *
 * Register a CDMM driver with the CDMM subsystem. The driver will be informed
 * of matching devices which are discovered.
 *
 * Returns:	0 on success.
 */
int mips_cdmm_driver_register(struct mips_cdmm_driver *drv)
{
	drv->drv.bus = &mips_cdmm_bustype;

	if (drv->probe)
		drv->drv.probe = mips_cdmm_probe;
	if (drv->remove)
		drv->drv.remove = mips_cdmm_remove;
	if (drv->shutdown)
		drv->drv.shutdown = mips_cdmm_shutdown;

	return driver_register(&drv->drv);
}
EXPORT_SYMBOL_GPL(mips_cdmm_driver_register);

/**
 * mips_cdmm_driver_unregister() - Unregister a CDMM driver.
 * @drv:	CDMM driver information.
 *
 * Unregister a CDMM driver from the CDMM subsystem.
 */
void mips_cdmm_driver_unregister(struct mips_cdmm_driver *drv)
{
	driver_unregister(&drv->drv);
}
EXPORT_SYMBOL_GPL(mips_cdmm_driver_unregister);


/* CDMM initialisation and bus discovery */

/**
 * struct mips_cdmm_bus - Info about CDMM bus.
 * @phys:		Physical address at which it is mapped.
 * @regs:		Virtual address where registers can be accessed.
 * @drbs:		Total number of DRBs.
 * @drbs_reserved:	Number of DRBs reserved.
 * @discovered:		Whether the devices on the bus have been discovered yet.
 * @offline:		Whether the CDMM bus is going offline (or very early
 *			coming back online), in which case it should be
 *			reconfigured each time.
 */
struct mips_cdmm_bus {
	phys_addr_t	 phys;
	void __iomem	*regs;
	unsigned int	 drbs;
	unsigned int	 drbs_reserved;
	bool		 discovered;
	bool		 offline;
};

static struct mips_cdmm_bus mips_cdmm_boot_bus;
static DEFINE_PER_CPU(struct mips_cdmm_bus *, mips_cdmm_buses);
static atomic_t mips_cdmm_next_id = ATOMIC_INIT(-1);

/**
 * mips_cdmm_get_bus() - Get the per-CPU CDMM bus information.
 *
 * Get information about the per-CPU CDMM bus, if the bus is present.
 *
 * The caller must prevent migration to another CPU, either by disabling
 * pre-emption or by running from a pinned kernel thread.
 *
 * Returns:	Pointer to CDMM bus information for the current CPU.
 *		May return ERR_PTR(-errno) in case of error, so check with
 *		IS_ERR().
 */
static struct mips_cdmm_bus *mips_cdmm_get_bus(void)
{
	struct mips_cdmm_bus *bus, **bus_p;
	unsigned long flags;
	unsigned int cpu;

	if (!cpu_has_cdmm)
		return ERR_PTR(-ENODEV);

	cpu = smp_processor_id();
	/* Avoid early use of per-cpu primitives before initialised */
	if (cpu == 0)
		return &mips_cdmm_boot_bus;

	/* Get bus pointer */
	bus_p = per_cpu_ptr(&mips_cdmm_buses, cpu);
	local_irq_save(flags);
	bus = *bus_p;
	/* Attempt allocation if NULL */
	if (unlikely(!bus)) {
		bus = kzalloc(sizeof(*bus), GFP_ATOMIC);
		if (unlikely(!bus))
			bus = ERR_PTR(-ENOMEM);
		else
			*bus_p = bus;
	}
	local_irq_restore(flags);
	return bus;
}

/**
 * mips_cdmm_cur_base() - Find current physical base address of CDMM region.
 *
 * Returns:	Physical base address of CDMM region according to cdmmbase CP0
 *		register, or 0 if the CDMM region is disabled.
 */
static phys_addr_t mips_cdmm_cur_base(void)
{
	unsigned long cdmmbase = read_c0_cdmmbase();

	if (!(cdmmbase & MIPS_CDMMBASE_EN))
		return 0;

	return (cdmmbase >> MIPS_CDMMBASE_ADDR_SHIFT)
		<< MIPS_CDMMBASE_ADDR_START;
}

/**
 * mips_cdmm_phys_base() - Choose a physical base address for CDMM region.
 *
 * Picking a suitable physical address at which to map the CDMM region is
 * platform specific, so this weak function can be overridden by platform
 * code to pick a suitable value if none is configured by the bootloader.
 * By default this method tries to find a CDMM-specific node in the system
 * dtb. Note that this won't work for early serial console.
 */
phys_addr_t __weak mips_cdmm_phys_base(void)
{
	struct device_node *np;
	struct resource res;
	int err;

	np = of_find_compatible_node(NULL, NULL, "mti,mips-cdmm");
	if (np) {
		err = of_address_to_resource(np, 0, &res);
		of_node_put(np);
		if (!err)
			return res.start;
	}

	return 0;
}

/**
 * mips_cdmm_setup() - Ensure the CDMM bus is initialised and usable.
 * @bus:	Pointer to bus information for current CPU.
 *		IS_ERR(bus) is checked, so no need for caller to check.
 *
 * The caller must prevent migration to another CPU, either by disabling
 * pre-emption or by running from a pinned kernel thread.
 *
 * Returns	0 on success, -errno on failure.
 */
static int mips_cdmm_setup(struct mips_cdmm_bus *bus)
{
	unsigned long cdmmbase, flags;
	int ret = 0;

	if (IS_ERR(bus))
		return PTR_ERR(bus);

	local_irq_save(flags);
	/* Don't set up bus a second time unless marked offline */
	if (bus->offline) {
		/* If CDMM region is still set up, nothing to do */
		if (bus->phys == mips_cdmm_cur_base())
			goto out;
		/*
		 * The CDMM region isn't set up as expected, so it needs
		 * reconfiguring, but then we can stop checking it.
		 */
		bus->offline = false;
	} else if (bus->phys > 1) {
		goto out;
	}

	/* If the CDMM region is already configured, inherit that setup */
	if (!bus->phys)
		bus->phys = mips_cdmm_cur_base();
	/* Otherwise, ask platform code for suggestions */
	if (!bus->phys)
		bus->phys = mips_cdmm_phys_base();
	/* Otherwise, copy what other CPUs have done */
	if (!bus->phys)
		bus->phys = mips_cdmm_default_base;
	/* Otherwise, complain once */
	if (!bus->phys) {
		bus->phys = 1;
		/*
		 * If you hit this, either your bootloader needs to set up the
		 * CDMM on the boot CPU, or else you need to implement
		 * mips_cdmm_phys_base() for your platform (see asm/cdmm.h).
		 */
		pr_err("cdmm%u: Failed to choose a physical base\n",
		       smp_processor_id());
	}
	/* Already complained? */
	if (bus->phys == 1) {
		ret = -ENOMEM;
		goto out;
	}
	/* Record our success for other CPUs to copy */
	mips_cdmm_default_base = bus->phys;

	pr_debug("cdmm%u: Enabling CDMM region at %pa\n",
		 smp_processor_id(), &bus->phys);

	/* Enable CDMM */
	cdmmbase = read_c0_cdmmbase();
	cdmmbase &= (1ul << MIPS_CDMMBASE_ADDR_SHIFT) - 1;
	cdmmbase |= (bus->phys >> MIPS_CDMMBASE_ADDR_START)
			<< MIPS_CDMMBASE_ADDR_SHIFT;
	cdmmbase |= MIPS_CDMMBASE_EN;
	write_c0_cdmmbase(cdmmbase);
	tlbw_use_hazard();

	bus->regs = (void __iomem *)CKSEG1ADDR(bus->phys);
	bus->drbs = 1 + ((cdmmbase & MIPS_CDMMBASE_SIZE) >>
			 MIPS_CDMMBASE_SIZE_SHIFT);
	bus->drbs_reserved = !!(cdmmbase & MIPS_CDMMBASE_CI);

out:
	local_irq_restore(flags);
	return ret;
}

/**
 * mips_cdmm_early_probe() - Minimally probe for a specific device on CDMM.
 * @dev_type:	CDMM type code to look for.
 *
 * Minimally configure the in-CPU Common Device Memory Map (CDMM) and look for a
 * specific device. This can be used to find a device very early in boot for
 * example to configure an early FDC console device.
 *
 * The caller must prevent migration to another CPU, either by disabling
 * pre-emption or by running from a pinned kernel thread.
 *
 * Returns:	MMIO pointer to device memory. The caller can read the ACSR
 *		register to find more information about the device (such as the
 *		version number or the number of blocks).
 *		May return IOMEM_ERR_PTR(-errno) in case of error, so check with
 *		IS_ERR().
 */
void __iomem *mips_cdmm_early_probe(unsigned int dev_type)
{
	struct mips_cdmm_bus *bus;
	void __iomem *cdmm;
	u32 acsr;
	unsigned int drb, type, size;
	int err;

	if (WARN_ON(!dev_type))
		return IOMEM_ERR_PTR(-ENODEV);

	bus = mips_cdmm_get_bus();
	err = mips_cdmm_setup(bus);
	if (err)
		return IOMEM_ERR_PTR(err);

	/* Skip the first block if it's reserved for more registers */
	drb = bus->drbs_reserved;
	cdmm = bus->regs;

	/* Look for a specific device type */
	for (; drb < bus->drbs; drb += size + 1) {
		acsr = __raw_readl(cdmm + drb * CDMM_DRB_SIZE);
		type = (acsr & CDMM_ACSR_DEVTYPE) >> CDMM_ACSR_DEVTYPE_SHIFT;
		if (type == dev_type)
			return cdmm + drb * CDMM_DRB_SIZE;
		size = (acsr & CDMM_ACSR_DEVSIZE) >> CDMM_ACSR_DEVSIZE_SHIFT;
	}

	return IOMEM_ERR_PTR(-ENODEV);
}
EXPORT_SYMBOL_GPL(mips_cdmm_early_probe);

/**
 * mips_cdmm_release() - Release a removed CDMM device.
 * @dev:	Device object
 *
 * Clean up the struct mips_cdmm_device for an unused CDMM device. This is
 * called automatically by the driver core when a device is removed.
 */
static void mips_cdmm_release(struct device *dev)
{
	struct mips_cdmm_device *cdev = to_mips_cdmm_device(dev);

	kfree(cdev);
}

/**
 * mips_cdmm_bus_discover() - Discover the devices on the CDMM bus.
 * @bus:	CDMM bus information, must already be set up.
 */
static void mips_cdmm_bus_discover(struct mips_cdmm_bus *bus)
{
	void __iomem *cdmm;
	u32 acsr;
	unsigned int drb, type, size, rev;
	struct mips_cdmm_device *dev;
	unsigned int cpu = smp_processor_id();
	int ret = 0;
	int id = 0;

	/* Skip the first block if it's reserved for more registers */
	drb = bus->drbs_reserved;
	cdmm = bus->regs;

	/* Discover devices */
	bus->discovered = true;
	pr_info("cdmm%u discovery (%u blocks)\n", cpu, bus->drbs);
	for (; drb < bus->drbs; drb += size + 1) {
		acsr = __raw_readl(cdmm + drb * CDMM_DRB_SIZE);
		type = (acsr & CDMM_ACSR_DEVTYPE) >> CDMM_ACSR_DEVTYPE_SHIFT;
		size = (acsr & CDMM_ACSR_DEVSIZE) >> CDMM_ACSR_DEVSIZE_SHIFT;
		rev  = (acsr & CDMM_ACSR_DEVREV)  >> CDMM_ACSR_DEVREV_SHIFT;

		if (!type)
			continue;

		pr_info("cdmm%u-%u: @%u (%#x..%#x), type 0x%02x, rev %u\n",
			cpu, id, drb, drb * CDMM_DRB_SIZE,
			(drb + size + 1) * CDMM_DRB_SIZE - 1,
			type, rev);

		dev = kzalloc(sizeof(*dev), GFP_KERNEL);
		if (!dev)
			break;

		dev->cpu = cpu;
		dev->res.start = bus->phys + drb * CDMM_DRB_SIZE;
		dev->res.end = bus->phys +
				(drb + size + 1) * CDMM_DRB_SIZE - 1;
		dev->res.flags = IORESOURCE_MEM;
		dev->type = type;
		dev->rev = rev;
		dev->dev.parent = get_cpu_device(cpu);
		dev->dev.bus = &mips_cdmm_bustype;
		dev->dev.id = atomic_inc_return(&mips_cdmm_next_id);
		dev->dev.release = mips_cdmm_release;

		dev_set_name(&dev->dev, "cdmm%u-%u", cpu, id);
		++id;
		ret = device_register(&dev->dev);
		if (ret)
			put_device(&dev->dev);
	}
}


/*
 * CPU hotplug and initialisation
 *
 * All the CDMM driver callbacks need to be executed on the appropriate CPU from
 * workqueues. For the CPU callbacks, they need to be called for all devices on
 * that CPU, so the work function calls bus_for_each_dev, using a helper
 * (generated with BUILD_PERDEV_HELPER) to call the driver callback if the
 * device's CPU matches.
 */

/**
 * BUILD_PERDEV_HELPER() - Helper to call a CDMM driver callback if CPU matches.
 * @_name:	Name of CDMM driver callback function.
 *
 * Generates a bus_for_each_dev callback function to call a specific CDMM driver
 * callback function for the device if the device's CPU matches that pointed to
 * by the data argument.
 *
 * This is used for informing drivers for all devices on a given CPU of some
 * event (such as the CPU going online/offline).
 *
 * It is expected to already be called from the appropriate CPU.
 */
#define BUILD_PERDEV_HELPER(_name)					\
static int mips_cdmm_##_name##_helper(struct device *dev, void *data)	\
{									\
	struct mips_cdmm_device *cdev = to_mips_cdmm_device(dev);	\
	struct mips_cdmm_driver *cdrv;					\
	unsigned int cpu = *(unsigned int *)data;			\
									\
	if (cdev->cpu != cpu || !dev->driver)				\
		return 0;						\
									\
	cdrv = to_mips_cdmm_driver(dev->driver);			\
	if (!cdrv->_name)						\
		return 0;						\
	return cdrv->_name(cdev);					\
}

/* bus_for_each_dev callback helper functions */
BUILD_PERDEV_HELPER(cpu_down)       /* int mips_cdmm_cpu_down_helper(...) */
BUILD_PERDEV_HELPER(cpu_up)         /* int mips_cdmm_cpu_up_helper(...) */

/**
 * mips_cdmm_cpu_down_prep() - Callback for CPUHP DOWN_PREP:
 *			       Tear down the CDMM bus.
 * @cpu:	unsigned int CPU number.
 *
 * This function is executed on the hotplugged CPU and calls the CDMM
 * driver cpu_down callback for all devices on that CPU.
 */
static int mips_cdmm_cpu_down_prep(unsigned int cpu)
{
	struct mips_cdmm_bus *bus;
	long ret;

	/* Inform all the devices on the bus */
	ret = bus_for_each_dev(&mips_cdmm_bustype, NULL, &cpu,
			       mips_cdmm_cpu_down_helper);

	/*
	 * While bus is offline, each use of it should reconfigure it just in
	 * case it is first use when coming back online again.
	 */
	bus = mips_cdmm_get_bus();
	if (!IS_ERR(bus))
		bus->offline = true;

	return ret;
}

/**
 * mips_cdmm_cpu_online() - Callback for CPUHP ONLINE: Bring up the CDMM bus.
 * @cpu:	unsigned int CPU number.
 *
 * This work_on_cpu callback function is executed on a given CPU to discover
 * CDMM devices on that CPU, or to call the CDMM driver cpu_up callback for all
 * devices already discovered on that CPU.
 *
 * It is used as work_on_cpu callback function during
 * initialisation. When CPUs are brought online the function is
 * invoked directly on the hotplugged CPU.
 */
static int mips_cdmm_cpu_online(unsigned int cpu)
{
	struct mips_cdmm_bus *bus;
	long ret;

	bus = mips_cdmm_get_bus();
	ret = mips_cdmm_setup(bus);
	if (ret)
		return ret;

	/* Bus now set up, so we can drop the offline flag if still set */
	bus->offline = false;

	if (!bus->discovered)
		mips_cdmm_bus_discover(bus);
	else
		/* Inform all the devices on the bus */
		ret = bus_for_each_dev(&mips_cdmm_bustype, NULL, &cpu,
				       mips_cdmm_cpu_up_helper);

	return ret;
}

/**
 * mips_cdmm_init() - Initialise CDMM bus.
 *
 * Initialise CDMM bus, discover CDMM devices for online CPUs, and arrange for
 * hotplug notifications so the CDMM drivers can be kept up to date.
 */
static int __init mips_cdmm_init(void)
{
	int ret;

	/* Register the bus */
	ret = bus_register(&mips_cdmm_bustype);
	if (ret)
		return ret;

	/* We want to be notified about new CPUs */
	ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "bus/cdmm:online",
				mips_cdmm_cpu_online, mips_cdmm_cpu_down_prep);
	if (ret < 0)
		pr_warn("cdmm: Failed to register CPU notifier\n");

	return ret;
}
subsys_initcall(mips_cdmm_init);
