/*
 * 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, 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>

//#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(&dev->link);
	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);
