/*
 * 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/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(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, struct device_driver *drv)
{
	struct mips_cdmm_device *cdev = to_mips_cdmm_device(dev);
	struct mips_cdmm_driver *cdrv = to_mips_cdmm_driver(drv);

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

static int mips_cdmm_uevent(struct device *dev, struct kobj_uevent_env *env)
{
	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);

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_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 && mips_cdmm_phys_base)
		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 = 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 = 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);
			kfree(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_bus_down() - Tear down the CDMM bus.
 * @data:	Pointer to unsigned int CPU number.
 *
 * This work_on_cpu callback function is executed on a given CPU to call the
 * CDMM driver cpu_down callback for all devices on that CPU.
 */
static long mips_cdmm_bus_down(void *data)
{
	struct mips_cdmm_bus *bus;
	long ret;

	/* Inform all the devices on the bus */
	ret = bus_for_each_dev(&mips_cdmm_bustype, NULL, data,
			       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_bus_up() - Bring up the CDMM bus.
 * @data:	Pointer to 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 during initialisation and when CPUs are brought online.
 */
static long mips_cdmm_bus_up(void *data)
{
	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, data,
				       mips_cdmm_cpu_up_helper);

	return ret;
}

/**
 * mips_cdmm_cpu_notify() - Take action when a CPU is going online or offline.
 * @nb:		CPU notifier block .
 * @action:	Event that has taken place (CPU_*).
 * @data:	CPU number.
 *
 * This notifier is used to keep the CDMM buses updated as CPUs are offlined and
 * onlined. When CPUs go offline or come back online, so does their CDMM bus, so
 * devices must be informed. Also when CPUs come online for the first time the
 * devices on the CDMM bus need discovering.
 *
 * Returns:	NOTIFY_OK if event was used.
 *		NOTIFY_DONE if we didn't care.
 */
static int mips_cdmm_cpu_notify(struct notifier_block *nb,
				unsigned long action, void *data)
{
	unsigned int cpu = (unsigned int)data;

	switch (action & ~CPU_TASKS_FROZEN) {
	case CPU_ONLINE:
	case CPU_DOWN_FAILED:
		work_on_cpu(cpu, mips_cdmm_bus_up, &cpu);
		break;
	case CPU_DOWN_PREPARE:
		work_on_cpu(cpu, mips_cdmm_bus_down, &cpu);
		break;
	default:
		return NOTIFY_DONE;
	}

	return NOTIFY_OK;
}

static struct notifier_block mips_cdmm_cpu_nb = {
	.notifier_call = mips_cdmm_cpu_notify,
};

/**
 * 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)
{
	unsigned int cpu;
	int ret;

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

	/* We want to be notified about new CPUs */
	ret = register_cpu_notifier(&mips_cdmm_cpu_nb);
	if (ret) {
		pr_warn("cdmm: Failed to register CPU notifier\n");
		goto out;
	}

	/* Discover devices on CDMM of online CPUs */
	for_each_online_cpu(cpu)
		work_on_cpu(cpu, mips_cdmm_bus_up, &cpu);

	return 0;
out:
	bus_unregister(&mips_cdmm_bustype);
	return ret;
}
subsys_initcall(mips_cdmm_init);
