/*
 * 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 <asm/io.h>
#include <asm/ocp.h>
#include <asm/errno.h>
#include <asm/rwsem.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);
