/*
 * ocp.c
 *
 *      (c) Benjamin Herrenschmidt (benh@kernel.crashing.org)
 *          Mipsys - France
 *
 *          Derived from work (c) Armin Kuster akuster@pacbell.net
 *
 *          Additional support and port to 2.6 LDM/sysfs by
 *          Matt Porter <mporter@kernel.crashing.org>
 *          Copyright 2004 MontaVista Software, Inc.
 *
 *  This program is free software; you can redistribute  it and/or modify it
 *  under  the terms of  the GNU General Public License as published by the
 *  Free Software Foundation;  either version 2 of the  License, or (at your
 *  option) any later version.
 *
 *  OCP (On Chip Peripheral) is a software emulated "bus" with a
 *  pseudo discovery method for dumb peripherals. Usually these type
 *  of peripherals are found on embedded SoC (System On a Chip)
 *  processors or highly integrated system controllers that have
 *  a host bridge and many peripherals.  Common examples where
 *  this is already used include the PPC4xx, PPC85xx, MPC52xx,
 *  and MV64xxx parts.
 *
 *  This subsystem creates a standard OCP bus type within the
 *  device model.  The devices on the OCP bus are seeded by an
 *  an initial OCP device array created by the arch-specific
 *  Device entries can be added/removed/modified through OCP
 *  helper functions to accommodate system and  board-specific
 *  parameters commonly found in embedded systems. OCP also
 *  provides a standard method for devices to describe extended
 *  attributes about themselves to the system.  A standard access
 *  method allows OCP drivers to obtain the information, both
 *  SoC-specific and system/board-specific, needed for operation.
 */

#include <linux/module.h>
#include <linux/list.h>
#include <linux/miscdevice.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/init.h>
#include <linux/pm.h>
#include <linux/bootmem.h>
#include <linux/device.h>
#include <linux/rwsem.h>

#include <asm/io.h>
#include <asm/ocp.h>
#include <asm/errno.h>
#include <asm/semaphore.h>

//#define DBG(x)	printk x
#define DBG(x)

extern int mem_init_done;

extern struct ocp_def core_ocp[];	/* Static list of devices, provided by
					   CPU core */

LIST_HEAD(ocp_devices);			/* List of all OCP devices */
DECLARE_RWSEM(ocp_devices_sem);		/* Global semaphores for those lists */

static int ocp_inited;

/* Sysfs support */
#define OCP_DEF_ATTR(field, format_string)				\
static ssize_t								\
show_##field(struct device *dev, struct device_attribute *attr, char *buf)				\
{									\
	struct ocp_device *odev = to_ocp_dev(dev);			\
									\
	return sprintf(buf, format_string, odev->def->field);		\
}									\
static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL);

OCP_DEF_ATTR(vendor, "0x%04x\n");
OCP_DEF_ATTR(function, "0x%04x\n");
OCP_DEF_ATTR(index, "0x%04x\n");
#ifdef CONFIG_PTE_64BIT
OCP_DEF_ATTR(paddr, "0x%016Lx\n");
#else
OCP_DEF_ATTR(paddr, "0x%08lx\n");
#endif
OCP_DEF_ATTR(irq, "%d\n");
OCP_DEF_ATTR(pm, "%lu\n");

void ocp_create_sysfs_dev_files(struct ocp_device *odev)
{
	struct device *dev = &odev->dev;

	/* Current OCP device def attributes */
	device_create_file(dev, &dev_attr_vendor);
	device_create_file(dev, &dev_attr_function);
	device_create_file(dev, &dev_attr_index);
	device_create_file(dev, &dev_attr_paddr);
	device_create_file(dev, &dev_attr_irq);
	device_create_file(dev, &dev_attr_pm);
	/* Current OCP device additions attributes */
	if (odev->def->additions && odev->def->show)
		odev->def->show(dev);
}

/**
 *	ocp_device_match	-	Match one driver to one device
 *	@drv: driver to match
 *	@dev: device to match
 *
 *	This function returns 0 if the driver and device don't match
 */
static int
ocp_device_match(struct device *dev, struct device_driver *drv)
{
	struct ocp_device *ocp_dev = to_ocp_dev(dev);
	struct ocp_driver *ocp_drv = to_ocp_drv(drv);
	const struct ocp_device_id *ids = ocp_drv->id_table;

	if (!ids)
		return 0;

	while (ids->vendor || ids->function) {
		if ((ids->vendor == OCP_ANY_ID
		     || ids->vendor == ocp_dev->def->vendor)
		    && (ids->function == OCP_ANY_ID
			|| ids->function == ocp_dev->def->function))
		        return 1;
		ids++;
	}
	return 0;
}

static int
ocp_device_probe(struct device *dev)
{
	int error = 0;
	struct ocp_driver *drv;
	struct ocp_device *ocp_dev;

	drv = to_ocp_drv(dev->driver);
	ocp_dev = to_ocp_dev(dev);

	if (drv->probe) {
		error = drv->probe(ocp_dev);
		if (error >= 0) {
			ocp_dev->driver = drv;
			error = 0;
		}
	}
	return error;
}

static int
ocp_device_remove(struct device *dev)
{
	struct ocp_device *ocp_dev = to_ocp_dev(dev);

	if (ocp_dev->driver) {
		if (ocp_dev->driver->remove)
			ocp_dev->driver->remove(ocp_dev);
		ocp_dev->driver = NULL;
	}
	return 0;
}

static int
ocp_device_suspend(struct device *dev, pm_message_t state)
{
	struct ocp_device *ocp_dev = to_ocp_dev(dev);
	struct ocp_driver *ocp_drv = to_ocp_drv(dev->driver);

	if (dev->driver && ocp_drv->suspend)
		return ocp_drv->suspend(ocp_dev, state);
	return 0;
}

static int
ocp_device_resume(struct device *dev)
{
	struct ocp_device *ocp_dev = to_ocp_dev(dev);
	struct ocp_driver *ocp_drv = to_ocp_drv(dev->driver);

	if (dev->driver && ocp_drv->resume)
		return ocp_drv->resume(ocp_dev);
	return 0;
}

struct bus_type ocp_bus_type = {
	.name = "ocp",
	.match = ocp_device_match,
	.probe = ocp_device_probe,
	.remove = ocp_device_remove,
	.suspend = ocp_device_suspend,
	.resume = ocp_device_resume,
};

/**
 *	ocp_register_driver	-	Register an OCP driver
 *	@drv: pointer to statically defined ocp_driver structure
 *
 *	The driver's probe() callback is called either recursively
 *	by this function or upon later call of ocp_driver_init
 *
 *	NOTE: Detection of devices is a 2 pass step on this implementation,
 *	hotswap isn't supported. First, all OCP devices are put in the device
 *	list, _then_ all drivers are probed on each match.
 */
int
ocp_register_driver(struct ocp_driver *drv)
{
	/* initialize common driver fields */
	drv->driver.name = drv->name;
	drv->driver.bus = &ocp_bus_type;

	/* register with core */
	return driver_register(&drv->driver);
}

/**
 *	ocp_unregister_driver	-	Unregister an OCP driver
 *	@drv: pointer to statically defined ocp_driver structure
 *
 *	The driver's remove() callback is called recursively
 *	by this function for any device already registered
 */
void
ocp_unregister_driver(struct ocp_driver *drv)
{
	DBG(("ocp: ocp_unregister_driver(%s)...\n", drv->name));

	driver_unregister(&drv->driver);

	DBG(("ocp: ocp_unregister_driver(%s)... done.\n", drv->name));
}

/* Core of ocp_find_device(). Caller must hold ocp_devices_sem */
static struct ocp_device *
__ocp_find_device(unsigned int vendor, unsigned int function, int index)
{
	struct list_head	*entry;
	struct ocp_device	*dev, *found = NULL;

	DBG(("ocp: __ocp_find_device(vendor: %x, function: %x, index: %d)...\n", vendor, function, index));

	list_for_each(entry, &ocp_devices) {
		dev = list_entry(entry, struct ocp_device, link);
		if (vendor != OCP_ANY_ID && vendor != dev->def->vendor)
			continue;
		if (function != OCP_ANY_ID && function != dev->def->function)
			continue;
		if (index != OCP_ANY_INDEX && index != dev->def->index)
			continue;
		found = dev;
		break;
	}

	DBG(("ocp: __ocp_find_device(vendor: %x, function: %x, index: %d)... done\n", vendor, function, index));

	return found;
}

/**
 *	ocp_find_device	-	Find a device by function & index
 *      @vendor: vendor ID of the device (or OCP_ANY_ID)
 *	@function: function code of the device (or OCP_ANY_ID)
 *	@idx: index of the device (or OCP_ANY_INDEX)
 *
 *	This function allows a lookup of a given function by it's
 *	index, it's typically used to find the MAL or ZMII associated
 *	with an EMAC or similar horrors.
 *      You can pass vendor, though you usually want OCP_ANY_ID there...
 */
struct ocp_device *
ocp_find_device(unsigned int vendor, unsigned int function, int index)
{
	struct ocp_device	*dev;

	down_read(&ocp_devices_sem);
	dev = __ocp_find_device(vendor, function, index);
	up_read(&ocp_devices_sem);

	return dev;
}

/**
 *	ocp_get_one_device -	Find a def by function & index
 *      @vendor: vendor ID of the device (or OCP_ANY_ID)
 *	@function: function code of the device (or OCP_ANY_ID)
 *	@idx: index of the device (or OCP_ANY_INDEX)
 *
 *	This function allows a lookup of a given ocp_def by it's
 *	vendor, function, and index.  The main purpose for is to
 *	allow modification of the def before binding to the driver
 */
struct ocp_def *
ocp_get_one_device(unsigned int vendor, unsigned int function, int index)
{
	struct ocp_device	*dev;
	struct ocp_def		*found = NULL;

	DBG(("ocp: ocp_get_one_device(vendor: %x, function: %x, index: %d)...\n",
		vendor, function, index));

	dev = ocp_find_device(vendor, function, index);

	if (dev)
		found = dev->def;

	DBG(("ocp: ocp_get_one_device(vendor: %x, function: %x, index: %d)... done.\n",
		vendor, function, index));

	return found;
}

/**
 *	ocp_add_one_device	-	Add a device
 *	@def: static device definition structure
 *
 *	This function adds a device definition to the
 *	device list. It may only be called before
 *	ocp_driver_init() and will return an error
 *	otherwise.
 */
int
ocp_add_one_device(struct ocp_def *def)
{
	struct	ocp_device	*dev;

	DBG(("ocp: ocp_add_one_device()...\n"));

	/* Can't be called after ocp driver init */
	if (ocp_inited)
		return 1;

	if (mem_init_done)
		dev = kmalloc(sizeof(*dev), GFP_KERNEL);
	else
		dev = alloc_bootmem(sizeof(*dev));

	if (dev == NULL)
		return 1;
	memset(dev, 0, sizeof(*dev));
	dev->def = def;
	dev->current_state = 4;
	sprintf(dev->name, "OCP device %04x:%04x:%04x",
		dev->def->vendor, dev->def->function, dev->def->index);
	down_write(&ocp_devices_sem);
	list_add_tail(&dev->link, &ocp_devices);
	up_write(&ocp_devices_sem);

	DBG(("ocp: ocp_add_one_device()...done\n"));

	return 0;
}

/**
 *	ocp_remove_one_device -	Remove a device by function & index
 *      @vendor: vendor ID of the device (or OCP_ANY_ID)
 *	@function: function code of the device (or OCP_ANY_ID)
 *	@idx: index of the device (or OCP_ANY_INDEX)
 *
 *	This function allows removal of a given function by its
 *	index. It may only be called before ocp_driver_init()
 *	and will return an error otherwise.
 */
int
ocp_remove_one_device(unsigned int vendor, unsigned int function, int index)
{
	struct ocp_device *dev;

	DBG(("ocp: ocp_remove_one_device(vendor: %x, function: %x, index: %d)...\n", vendor, function, index));

	/* Can't be called after ocp driver init */
	if (ocp_inited)
		return 1;

	down_write(&ocp_devices_sem);
	dev = __ocp_find_device(vendor, function, index);
	list_del((struct list_head *)dev);
	up_write(&ocp_devices_sem);

	DBG(("ocp: ocp_remove_one_device(vendor: %x, function: %x, index: %d)... done.\n", vendor, function, index));

	return 0;
}

/**
 *	ocp_for_each_device	-	Iterate over OCP devices
 *	@callback: routine to execute for each ocp device.
 *	@arg: user data to be passed to callback routine.
 *
 *	This routine holds the ocp_device semaphore, so the
 *	callback routine cannot modify the ocp_device list.
 */
void
ocp_for_each_device(void(*callback)(struct ocp_device *, void *arg), void *arg)
{
	struct list_head *entry;

	if (callback) {
		down_read(&ocp_devices_sem);
		list_for_each(entry, &ocp_devices)
			callback(list_entry(entry, struct ocp_device, link),
				arg);
		up_read(&ocp_devices_sem);
	}
}

/**
 *	ocp_early_init	-	Init OCP device management
 *
 *	This function builds the list of devices before setup_arch.
 *	This allows platform code to modify the device lists before
 *	they are bound to drivers (changes to paddr, removing devices
 *	etc)
 */
int __init
ocp_early_init(void)
{
	struct ocp_def	*def;

	DBG(("ocp: ocp_early_init()...\n"));

	/* Fill the devices list */
	for (def = core_ocp; def->vendor != OCP_VENDOR_INVALID; def++)
		ocp_add_one_device(def);

	DBG(("ocp: ocp_early_init()... done.\n"));

	return 0;
}

/**
 *	ocp_driver_init	-	Init OCP device management
 *
 *	This function is meant to be called via OCP bus registration.
 */
static int __init
ocp_driver_init(void)
{
	int ret = 0, index = 0;
	struct device *ocp_bus;
	struct list_head *entry;
	struct ocp_device *dev;

	if (ocp_inited)
		return ret;
	ocp_inited = 1;

	DBG(("ocp: ocp_driver_init()...\n"));

	/* Allocate/register primary OCP bus */
	ocp_bus = kzalloc(sizeof(struct device), GFP_KERNEL);
	if (ocp_bus == NULL)
		return 1;
	strcpy(ocp_bus->bus_id, "ocp");

	bus_register(&ocp_bus_type);

	device_register(ocp_bus);

	/* Put each OCP device into global device list */
	list_for_each(entry, &ocp_devices) {
		dev = list_entry(entry, struct ocp_device, link);
		sprintf(dev->dev.bus_id, "%2.2x", index);
		dev->dev.parent = ocp_bus;
		dev->dev.bus = &ocp_bus_type;
		device_register(&dev->dev);
		ocp_create_sysfs_dev_files(dev);
		index++;
	}

	DBG(("ocp: ocp_driver_init()... done.\n"));

	return 0;
}

postcore_initcall(ocp_driver_init);

EXPORT_SYMBOL(ocp_bus_type);
EXPORT_SYMBOL(ocp_find_device);
EXPORT_SYMBOL(ocp_register_driver);
EXPORT_SYMBOL(ocp_unregister_driver);
