public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] PPC32: New OCP core support
@ 2004-05-12  0:01 Matt Porter
  2004-05-12  0:39 ` Valdis.Kletnieks
                   ` (7 more replies)
  0 siblings, 8 replies; 21+ messages in thread
From: Matt Porter @ 2004-05-12  0:01 UTC (permalink / raw)
  To: akpm; +Cc: benh, linux-kernel, linuxppc-dev

New OCP infrastructure ported from 2.4 along with several
enhancements. Please apply.

-Matt

diff -Nru a/arch/ppc/Kconfig b/arch/ppc/Kconfig
--- a/arch/ppc/Kconfig	Tue May 11 14:56:45 2004
+++ b/arch/ppc/Kconfig	Tue May 11 14:56:45 2004
@@ -1238,7 +1238,7 @@
 	bool "Support for early boot texts over serial port"
 	depends on 4xx || GT64260 || LOPEC || PPLUS || PRPMC800 || PPC_GEN550
 
-config OCP
+config PPC_OCP
 	bool
 	depends on IBM_OCP
 	default y
diff -Nru a/arch/ppc/Makefile b/arch/ppc/Makefile
--- a/arch/ppc/Makefile	Tue May 11 14:56:45 2004
+++ b/arch/ppc/Makefile	Tue May 11 14:56:45 2004
@@ -43,7 +43,6 @@
 drivers-$(CONFIG_8xx)		+= arch/ppc/8xx_io/
 drivers-$(CONFIG_4xx)		+= arch/ppc/4xx_io/
 drivers-$(CONFIG_8260)		+= arch/ppc/8260_io/
-drivers-$(CONFIG_OCP)		+= arch/ppc/ocp/
 
 BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd vmlinux.sm
 
diff -Nru a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c
--- a/arch/ppc/kernel/setup.c	Tue May 11 14:56:45 2004
+++ b/arch/ppc/kernel/setup.c	Tue May 11 14:56:45 2004
@@ -37,6 +37,7 @@
 #include <asm/sections.h>
 #include <asm/nvram.h>
 #include <asm/xmon.h>
+#include <asm/ocp.h>
 
 #if defined CONFIG_KGDB
 #include <asm/kgdb.h>
@@ -682,6 +683,12 @@
 	/* set up the bootmem stuff with available memory */
 	do_init_bootmem();
 	if ( ppc_md.progress ) ppc_md.progress("setup_arch: bootmem", 0x3eab);
+
+#ifdef CONFIG_PPC_OCP
+	/* Initialize OCP device list */
+	ocp_early_init();
+	if ( ppc_md.progress ) ppc_md.progress("ocp: exit", 0x3eab);
+#endif
 
 	ppc_md.setup_arch();
 	if ( ppc_md.progress ) ppc_md.progress("arch: exit", 0x3eab);
diff -Nru a/arch/ppc/ocp/Makefile b/arch/ppc/ocp/Makefile
--- a/arch/ppc/ocp/Makefile	Tue May 11 14:56:45 2004
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,6 +0,0 @@
-#
-# Makefile for the linux kernel.
-#
-
-obj-y   	:= ocp.o ocp-driver.o ocp-probe.o
-
diff -Nru a/arch/ppc/ocp/ocp-driver.c b/arch/ppc/ocp/ocp-driver.c
--- a/arch/ppc/ocp/ocp-driver.c	Tue May 11 14:56:45 2004
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,195 +0,0 @@
-/*
- * FILE NAME: ocp-driver.c
- *
- * BRIEF MODULE DESCRIPTION:
- * driver callback, id matching and registration
- * Based on drivers/pci/pci-driver, Copyright (c) 1997--1999 Martin Mares
- *
- * Maintained by: Armin <akuster@mvista.com>
- *
- *
- *  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.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <asm/ocp.h>
-#include <linux/module.h>
-#include <linux/init.h>
-
-/*
- *  Registration of OCP drivers and handling of hot-pluggable devices.
- */
-
-static int
-ocp_device_probe(struct device *dev)
-{
-	int error = 0;
-	struct ocp_driver *drv;
-	struct ocp_device *ocp_dev;
-
-	drv = to_ocp_driver(dev->driver);
-	ocp_dev = to_ocp_dev(dev);
-
-	if (drv->probe) {
-		error = drv->probe(ocp_dev);
-		DBG("probe return code %d\n", error);
-		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, u32 state, u32 level)
-{
-	struct ocp_device *ocp_dev = to_ocp_dev(dev);
-
-	int error = 0;
-
-	if (ocp_dev->driver) {
-		if (level == SUSPEND_SAVE_STATE && ocp_dev->driver->save_state)
-			error = ocp_dev->driver->save_state(ocp_dev, state);
-		else if (level == SUSPEND_POWER_DOWN
-			 && ocp_dev->driver->suspend)
-			error = ocp_dev->driver->suspend(ocp_dev, state);
-	}
-	return error;
-}
-
-static int
-ocp_device_resume(struct device *dev, u32 level)
-{
-	struct ocp_device *ocp_dev = to_ocp_dev(dev);
-
-	if (ocp_dev->driver) {
-		if (level == RESUME_POWER_ON && ocp_dev->driver->resume)
-			ocp_dev->driver->resume(ocp_dev);
-	}
-	return 0;
-}
-
-/**
- * ocp_bus_match - Works out whether an OCP device matches any
- * of the IDs listed for a given OCP driver.
- * @dev: the generic device struct for the OCP device
- * @drv: the generic driver struct for the OCP driver
- *
- * Used by a driver to check whether a OCP device present in the
- * system is in its list of supported devices.  Returns 1 for a
- * match, or 0 if there is no match.
- */
-static int
-ocp_bus_match(struct device *dev, struct device_driver *drv)
-{
-	struct ocp_device *ocp_dev = to_ocp_dev(dev);
-	struct ocp_driver *ocp_drv = to_ocp_driver(drv);
-	const struct ocp_device_id *ids = ocp_drv->id_table;
-
-	if (!ids)
-		return 0;
-
-	while (ids->vendor || ids->device) {
-		if ((ids->vendor == OCP_ANY_ID
-		     || ids->vendor == ocp_dev->vendor)
-		    && (ids->device == OCP_ANY_ID
-			|| ids->device == ocp_dev->device)) {
-			DBG("Bus match -vendor:%x device:%x\n", ids->vendor,
-			    ids->device);
-			return 1;
-		}
-		ids++;
-	}
-	return 0;
-}
-
-struct bus_type ocp_bus_type = {
-	.name = "ocp",
-	.match = ocp_bus_match,
-};
-
-static int __init
-ocp_driver_init(void)
-{
-	return bus_register(&ocp_bus_type);
-}
-
-postcore_initcall(ocp_driver_init);
-
-/**
- * ocp_register_driver - register a new ocp driver
- * @drv: the driver structure to register
- *
- * Adds the driver structure to the list of registered drivers
- * Returns the number of ocp devices which were claimed by the driver
- * during registration.  The driver remains registered even if the
- * return value is zero.
- */
-int
-ocp_register_driver(struct ocp_driver *drv)
-{
-	int count = 0;
-
-	/* initialize common driver fields */
-	drv->driver.name = drv->name;
-	drv->driver.bus = &ocp_bus_type;
-	drv->driver.probe = ocp_device_probe;
-	drv->driver.resume = ocp_device_resume;
-	drv->driver.suspend = ocp_device_suspend;
-	drv->driver.remove = ocp_device_remove;
-
-	/* register with core */
-	count = driver_register(&drv->driver);
-	return count ? count : 1;
-}
-
-/**
- * ocp_unregister_driver - unregister a ocp driver
- * @drv: the driver structure to unregister
- *
- * Deletes the driver structure from the list of registered OCP drivers,
- * gives it a chance to clean up by calling its remove() function for
- * each device it was responsible for, and marks those devices as
- * driverless.
- */
-
-void
-ocp_unregister_driver(struct ocp_driver *drv)
-{
-	driver_unregister(&drv->driver);
-}
-
-EXPORT_SYMBOL(ocp_register_driver);
-EXPORT_SYMBOL(ocp_unregister_driver);
-EXPORT_SYMBOL(ocp_bus_type);
diff -Nru a/arch/ppc/ocp/ocp-probe.c b/arch/ppc/ocp/ocp-probe.c
--- a/arch/ppc/ocp/ocp-probe.c	Tue May 11 14:56:45 2004
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,113 +0,0 @@
-/*
- * FILE NAME: ocp-probe.c
- *
- * BRIEF MODULE DESCRIPTION:
- * Device scanning & bus set routines
- * Based on drivers/pci/probe, Copyright (c) 1997--1999 Martin Mares
- *
- * Maintained by: Armin <akuster@mvista.com>
- *
- *
- *  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.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/device.h>
-#include <asm/ocp.h>
-
-LIST_HEAD(ocp_devices);
-struct device *ocp_bus;
-
-static struct ocp_device * __devinit
-ocp_setup_dev(struct ocp_def *odef, unsigned int index)
-{
-	struct ocp_device *dev;
-
-	dev = kmalloc(sizeof(*dev), GFP_KERNEL);
-	if (!dev)
-		return NULL;
-	memset(dev, 0, sizeof(*dev));
-
-	dev->vendor = odef->vendor;
-	dev->device = odef->device;
-	dev->num = ocp_get_num(dev->device);
-	dev->paddr = odef->paddr;
-	dev->irq = odef->irq;
-	dev->pm = odef->pm;
-	dev->current_state = 4;
-
-	sprintf(dev->name, "OCP device %04x:%04x", dev->vendor, dev->device);
-
-	DBG("%s %s 0x%lx irq:%d pm:0x%lx \n", dev->slot_name, dev->name,
-	    (unsigned long) dev->paddr, dev->irq, dev->pm);
-
-	/* now put in global tree */
-	sprintf(dev->dev.bus_id, "%d", index);
-	dev->dev.parent = ocp_bus;
-	dev->dev.bus = &ocp_bus_type;
-	device_register(&dev->dev);
-
-	return dev;
-}
-
-static struct device * __devinit ocp_alloc_primary_bus(void)
-{
-	struct device *b;
-
-	b = kmalloc(sizeof(struct device), GFP_KERNEL);
-	if (b == NULL)
-		return NULL;
-	memset(b, 0, sizeof(struct device));
-	strcpy(b->bus_id, "ocp");
-
-	device_register(b);
-
-	return b;
-}
-
-void __devinit ocp_setup_devices(struct ocp_def *odef)
-{
-	int index;
-	struct ocp_device *dev;
-
-	if (ocp_bus == NULL)
-		ocp_bus = ocp_alloc_primary_bus();
-	for (index = 0; odef->vendor != OCP_VENDOR_INVALID; ++index, ++odef) {
-		dev = ocp_setup_dev(odef, index);
-		if (dev != NULL)
-			list_add_tail(&dev->global_list, &ocp_devices);
-	}
-}
-
-extern struct ocp_def core_ocp[];
-
-static int __init
-ocparch_init(void)
-{
-	ocp_setup_devices(core_ocp);
-	return 0;
-}
-
-subsys_initcall(ocparch_init);
-
-EXPORT_SYMBOL(ocp_devices);
diff -Nru a/arch/ppc/ocp/ocp.c b/arch/ppc/ocp/ocp.c
--- a/arch/ppc/ocp/ocp.c	Tue May 11 14:56:45 2004
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,109 +0,0 @@
-/*
- * ocp.c
- *
- *	The is drived from pci.c
- *
- * 	Current Maintainer
- *      Armin Kuster akuster@dslextreme.com
- *      Jan, 2002
- *
- *
- *
- * 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.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR   IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/list.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/config.h>
-#include <linux/stddef.h>
-#include <linux/slab.h>
-#include <linux/types.h>
-#include <asm/io.h>
-#include <asm/ocp.h>
-#include <asm/errno.h>
-
-/**
- * ocp_get_num - This determines how many OCP devices of a given
- * device are registered
- * @device: OCP device such as HOST, PCI, GPT, UART, OPB, IIC, GPIO, EMAC, ZMII,
- *
- * The routine returns the number that devices which is registered
- */
-unsigned int ocp_get_num(unsigned int device)
-{
-	unsigned int count = 0;
-	struct ocp_device *ocp;
-	struct list_head *ocp_l;
-
-	list_for_each(ocp_l, &ocp_devices) {
-		ocp = list_entry(ocp_l, struct ocp_device, global_list);
-		if (device == ocp->device)
-			count++;
-	}
-	return count;
-}
-
-/**
- * ocp_get_dev - get ocp driver pointer for ocp device and instance of it
- * @device: OCP device such as PCI, GPT, UART, OPB, IIC, GPIO, EMAC, ZMII
- * @dev_num: ocp device number whos paddr you want
- *
- * The routine returns ocp device pointer
- * in list based on device and instance of that device
- *
- */
-struct ocp_device *
-ocp_get_dev(unsigned int device, int dev_num)
-{
-	struct ocp_device *ocp;
-	struct list_head *ocp_l;
-	int count = 0;
-
-	list_for_each(ocp_l, &ocp_devices) {
-		ocp = list_entry(ocp_l, struct ocp_device, global_list);
-		if (device == ocp->device) {
-			if (dev_num == count)
-				return ocp;
-			count++;
-		}
-	}
-	return NULL;
-}
-
-EXPORT_SYMBOL(ocp_get_dev);
-EXPORT_SYMBOL(ocp_get_num);
-
-#ifdef CONFIG_PM
-int ocp_generic_suspend(struct ocp_device *pdev, u32 state)
-{
-	ocp_force_power_off(pdev);
-	return 0;
-}
-
-int ocp_generic_resume(struct ocp_device *pdev)
-{
-	ocp_force_power_on(pdev);
-}
-
-EXPORT_SYMBOL(ocp_generic_suspend);
-EXPORT_SYMBOL(ocp_generic_resume);
-#endif /* CONFIG_PM */
diff -Nru a/arch/ppc/syslib/Makefile b/arch/ppc/syslib/Makefile
--- a/arch/ppc/syslib/Makefile	Tue May 11 14:56:45 2004
+++ b/arch/ppc/syslib/Makefile	Tue May 11 14:56:45 2004
@@ -13,6 +13,7 @@
 CFLAGS_btext.o          += -mrelocatable-lib
 
 obj-$(CONFIG_PPCBUG_NVRAM)	+= prep_nvram.o
+obj-$(CONFIG_PPC_OCP)		+= ocp.o
 obj-$(CONFIG_44x)		+= ibm44x_common.o
 obj-$(CONFIG_440GP)		+= ibm440gp_common.o
 ifeq ($(CONFIG_4xx),y)
diff -Nru a/arch/ppc/syslib/ocp.c b/arch/ppc/syslib/ocp.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/ppc/syslib/ocp.c	Tue May 11 14:56:45 2004
@@ -0,0 +1,584 @@
+/*
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/config.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, 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%16Lx\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, u32 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,
+	.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.
+ *
+ *	This function returns a count of how many devices actually matched
+ *	(whether the probe routine returned 0 or -ENODEV, a different error
+ *	code isn't considered as a match).
+ */
+int
+ocp_register_driver(struct ocp_driver *drv)
+{
+	int count = 0;
+
+	/* initialize common driver fields */
+	drv->driver.name = drv->name;
+	drv->driver.bus = &ocp_bus_type;
+	drv->driver.probe = ocp_device_probe;
+	drv->driver.remove = ocp_device_remove;
+
+	/* register with core */
+	count = driver_register(&drv->driver);
+
+	return count ? count : 1;
+}
+
+/**
+ *	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);
+	}
+}
+
+#ifdef CONFIG_PM
+/**
+ * OCP Power management..
+ *
+ * This needs to be done centralized, so that we power manage PCI
+ * devices in the right order: we should not shut down PCI bridges
+ * before we've shut down the devices behind them, and we should
+ * not wake up devices before we've woken up the bridge to the
+ * device.. Eh?
+ *
+ * We do not touch devices that don't have a driver that exports
+ * a suspend/resume function. That is just too dangerous. If the default
+ * PCI suspend/resume functions work for a device, the driver can
+ * easily implement them (ie just have a suspend function that calls
+ * the pci_set_power_state() function).
+ *
+ * BenH: Implementation here couldn't work properly. This version
+ *       slightly modified and _might_ be more useable, but real
+ *       PM support will probably have to wait for 2.5
+ */
+
+static int ocp_pm_save_state_device(struct ocp_device *dev, u32 state)
+{
+	int error = 0;
+	if (dev) {
+		struct ocp_driver *driver = dev->driver;
+		if (driver && driver->save_state)
+			error = driver->save_state(dev,state);
+	}
+	return error;
+}
+
+static int ocp_pm_suspend_device(struct ocp_device *dev, u32 state)
+{
+	int error = 0;
+	if (dev) {
+		struct ocp_driver *driver = dev->driver;
+		if (driver && driver->suspend)
+			error = driver->suspend(dev,state);
+	}
+	return error;
+}
+
+static int ocp_pm_resume_device(struct ocp_device *dev)
+{
+	int error = 0;
+	if (dev) {
+		struct ocp_driver *driver = dev->driver;
+		if (driver && driver->resume)
+			error = driver->resume(dev);
+	}
+	return error;
+}
+
+static int
+ocp_pm_callback(struct pm_dev *pm_device, pm_request_t rqst, void *data)
+{
+	int error = 0;
+	struct list_head	*entry;
+	struct ocp_device	*dev;
+
+	down_read(&ocp_devices_sem);
+
+	list_for_each(entry, &ocp_devices) {
+		dev = list_entry(entry, struct ocp_device, link);
+		switch (rqst) {
+		case PM_SAVE_STATE:
+			error = ocp_pm_save_state_device(dev, 3);
+			break;
+		case PM_SUSPEND:
+			error = ocp_pm_suspend_device(dev, 3);
+			break;
+		case PM_RESUME:
+			error = ocp_pm_resume_device(dev);
+			break;
+		default: break;
+		}
+		if (error)
+			break;
+	}
+
+	up_read(&ocp_devices_sem);
+
+	return error;
+}
+
+/*
+ * Is this ever used ?
+ */
+void
+ppc4xx_cpm_fr(u32 bits, int val)
+{
+	unsigned long flags;
+
+	save_flags(flags);
+	cli();
+
+	if (val)
+		mtdcr(DCRN_CPMFR, mfdcr(DCRN_CPMFR) | bits);
+	else
+		mtdcr(DCRN_CPMFR, mfdcr(DCRN_CPMFR) & ~bits);
+
+	restore_flags(flags);
+}
+#endif /* CONFIG_PM */
+
+/**
+ *	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"));
+
+#ifdef CONFIG_PM
+	pm_register(PM_SYS_DEV, 0, ocp_pm_callback);
+#endif
+
+	/* Allocate/register primary OCP bus */
+	ocp_bus = kmalloc(sizeof(struct device), GFP_KERNEL);
+	if (ocp_bus == NULL)
+		return 1;
+	memset(ocp_bus, 0, sizeof(struct device));
+	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);
diff -Nru a/include/asm-ppc/ocp.h b/include/asm-ppc/ocp.h
--- a/include/asm-ppc/ocp.h	Tue May 11 14:56:45 2004
+++ b/include/asm-ppc/ocp.h	Tue May 11 14:56:45 2004
@@ -1,103 +1,114 @@
 /*
  * ocp.h
  *
+ *      (c) Benjamin Herrenschmidt (benh@kernel.crashing.org)
+ *          Mipsys - France
  *
- * 	Current Maintainer
- *      Armin Kuster akuster@pacbell.net
- *      Jan, 2002
- *
+ *          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 2003-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.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR   IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
+ * 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.
+ *
+ *  TODO: - Add get/put interface & fixup locking to provide same API for
+ *          2.4 and 2.5
+ *	  - Rework PM callbacks
  */
 
 #ifdef __KERNEL__
 #ifndef __OCP_H__
 #define __OCP_H__
 
+#include <linux/init.h>
 #include <linux/list.h>
 #include <linux/config.h>
+#include <linux/devfs_fs_kernel.h>
 #include <linux/device.h>
-#include <linux/errno.h>
 
+#include <asm/mmu.h>
 #include <asm/ocp_ids.h>
-#include <asm/mmu.h>		/* For phys_addr_t */
-#undef DEBUG
-/* #define DEBUG*/
-
-#ifdef DEBUG
-#define DBG(x...) printk(x)
-#else
-#define DBG(x...)
-#endif
+#include <asm/rwsem.h>
+#include <asm/semaphore.h>
 
+#define OCP_MAX_IRQS	7
+#define MAX_EMACS	4
 #define OCP_IRQ_NA	-1	/* used when ocp device does not have an irq */
-#define OCP_IRQ_MUL	-2	/* used for ocp devices with multiple irqs */
-#define OCP_NULL_TYPE	0	/* used to mark end of list */
-#define OCP_DEV_NA	-1
+#define OCP_IRQ_MUL	-2	/* used for ocp devices with multiply irqs */
+#define OCP_NULL_TYPE	-1	/* used to mark end of list */
 #define OCP_CPM_NA	0	/* No Clock or Power Management avaliable */
+#define OCP_PADDR_NA	0	/* No MMIO registers */
 
 #define OCP_ANY_ID	(~0)
+#define OCP_ANY_INDEX	-1
 
-
-extern struct list_head ocp_root_buses;
-extern struct list_head ocp_devices;
+extern struct list_head 	ocp_devices;
+extern struct rw_semaphore	ocp_devices_sem;
 
 struct ocp_device_id {
-	unsigned int vendor, device;		/* Vendor and device ID or PCI_ANY_ID */
-	char name[16];
-	char desc[50];
-	unsigned long driver_data;		/* Data private to the driver */
+	unsigned int	vendor, function;	/* Vendor and function ID or OCP_ANY_ID */
+	unsigned long	driver_data;		/* Data private to the driver */
 };
 
-struct func_info {
-	char name[16];
-	char desc[50];
-};
 
+/*
+ * Static definition of an OCP device.
+ *
+ * @vendor:    Vendor code. It is _STRONGLY_ discouraged to use
+ *             the vendor code as a way to match a unique device,
+ *             though I kept that possibility open, you should
+ *             really define different function codes for different
+ *             device types
+ * @function:  This is the function code for this device.
+ * @index:     This index is used for mapping the Nth function of a
+ *             given core. This is typically used for cross-driver
+ *             matching, like looking for a given MAL or ZMII from
+ *             an EMAC or for getting to the proper set of DCRs.
+ *             Indices are no longer magically calculated based on
+ *             structure ordering, they have to be actually coded
+ *             into the ocp_def to avoid any possible confusion
+ *             I _STRONGLY_ (again ? wow !) encourage anybody relying
+ *             on index mapping to encode the "target" index in an
+ *             associated structure pointed to by "additions", see
+ *             how it's done for the EMAC driver.
+ * @paddr:     Device physical address (may not mean anything...)
+ * @irq:       Interrupt line for this device (TODO: think about making
+ *             an array with this)
+ * @pm:        Currently, contains the bitmask in CPMFR DCR for the device
+ * @additions: Optionally points to a function specific structure
+ *             providing additional informations for a given device
+ *             instance. It's currently used by the EMAC driver for MAL
+ *             channel & ZMII port mapping among others.
+ * @show:      Optionally points to a function specific structure
+ *             providing a sysfs show routine for additions fields.
+ */
 struct ocp_def {
-	unsigned int vendor;
-	unsigned int device;
-	phys_addr_t paddr;
-	int irq;
-	unsigned long pm;
+	unsigned int	vendor;
+	unsigned int	function;
+	int		index;
+	phys_addr_t	paddr;
+	int	  	irq;
+	unsigned long	pm;
+	void		*additions;
+	void		(*show)(struct device *);
 };
 
 
-/* Struct for single ocp device managment */
+/* Struct for a given device instance */
 struct ocp_device {
-	struct list_head global_list;
-	unsigned int	num;		/* instance of device */
-	char		name[80];	/* device name */
-	unsigned int vendor;
-	unsigned int device;
-	phys_addr_t paddr;
-	int irq;
-	unsigned long pm;
-	void *ocpdev;		/* driver data for this device */
-	struct ocp_driver *driver;
-	u32 current_state;	/* Current operating state. In ACPI-speak,
-				   this is D0-D3, D0 being fully functional,
-				   and D3 being off. */
-	struct device dev;
+	struct list_head	link;
+	char			name[80];	/* device name */
+	struct ocp_def		*def;		/* device definition */
+	void			*drvdata;	/* driver data for this device */
+	struct ocp_driver	*driver;
+	u32			current_state;	/* Current operating state. In ACPI-speak,
+						   this is D0-D3, D0 being fully functional,
+						   and D3 being off. */
+	struct			device dev;
 };
 
 struct ocp_driver {
@@ -106,23 +117,13 @@
 	const struct ocp_device_id *id_table;	/* NULL if wants all devices */
 	int  (*probe)  (struct ocp_device *dev);	/* New device inserted */
 	void (*remove) (struct ocp_device *dev);	/* Device removed (NULL if not a hot-plug capable driver) */
-	int  (*save_state) (struct ocp_device *dev, u32 state);    /* Save Device Context */
 	int  (*suspend) (struct ocp_device *dev, u32 state);	/* Device suspended */
 	int  (*resume) (struct ocp_device *dev);	                /* Device woken up */
-	int  (*enable_wake) (struct ocp_device *dev, u32 state, int enable);   /* Enable wake event */
 	struct device_driver driver;
 };
 
-#define	to_ocp_dev(n) container_of(n, struct ocp_device, dev)
-#define	to_ocp_driver(n) container_of(n, struct ocp_driver, driver)
-
-extern int ocp_register_driver(struct ocp_driver *drv);
-extern void ocp_unregister_driver(struct ocp_driver *drv);
-
-#define ocp_dev_g(n) list_entry(n, struct ocp_device, global_list)
-
-#define ocp_for_each_dev(dev) \
-	for(dev = ocp_dev_g(ocp_devices.next); dev != ocp_dev_g(&ocp_devices); dev = ocp_dev_g(dev->global_list.next))
+#define to_ocp_dev(n) container_of(n, struct ocp_device, dev)
+#define to_ocp_drv(n) container_of(n, struct ocp_driver, driver)
 
 /* Similar to the helpers above, these manipulate per-ocp_dev
  * driver-specific data.  Currently stored as ocp_dev::ocpdev,
@@ -131,45 +132,13 @@
 static inline void *
 ocp_get_drvdata(struct ocp_device *pdev)
 {
-	return pdev->ocpdev;
+	return pdev->drvdata;
 }
 
 static inline void
 ocp_set_drvdata(struct ocp_device *pdev, void *data)
 {
-	pdev->ocpdev = data;
-}
-
-/*
- * a helper function which helps ensure correct pci_driver
- * setup and cleanup for commonly-encountered hotplug/modular cases
- *
- * This MUST stay in a header, as it checks for -DMODULE
- */
-static inline int ocp_module_init(struct ocp_driver *drv)
-{
-	int rc = ocp_register_driver(drv);
-
-	if (rc > 0)
-		return 0;
-
-	/* iff CONFIG_HOTPLUG and built into kernel, we should
-	 * leave the driver around for future hotplug events.
-	 * For the module case, a hotplug daemon of some sort
-	 * should load a module in response to an insert event. */
-#if defined(CONFIG_HOTPLUG) && !defined(MODULE)
-	if (rc == 0)
-		return 0;
-#else
-	if (rc == 0)
-		rc = -ENODEV;		
-#endif
-
-	/* if we get here, we need to clean up pci driver instance
-	 * and return some sort of error */
-	ocp_unregister_driver (drv);
-	
-	return rc;
+	pdev->drvdata = data;
 }
 
 #if defined (CONFIG_PM)
@@ -180,26 +149,56 @@
 static inline void
 ocp_force_power_off(struct ocp_device *odev)
 {
-	mtdcr(DCRN_CPMFR, mfdcr(DCRN_CPMFR) | odev->pm);
+	mtdcr(DCRN_CPMFR, mfdcr(DCRN_CPMFR) | odev->def->pm);
 }
 
 static inline void
 ocp_force_power_on(struct ocp_device *odev)
 {
-	mtdcr(DCRN_CPMFR, mfdcr(DCRN_CPMFR) & ~odev->pm);
+	mtdcr(DCRN_CPMFR, mfdcr(DCRN_CPMFR) & ~odev->def->pm);
 }
 #else
 #define ocp_force_power_off(x)	(void)(x)
 #define ocp_force_power_on(x)	(void)(x)
 #endif
 
-extern void ocp_init(void);
-extern struct bus_type ocp_bus_type;
-extern struct ocp_device *ocp_get_dev(unsigned int device, int index);
-extern unsigned int ocp_get_num(unsigned int device);
+/* Register/Unregister an OCP driver */
+extern int ocp_register_driver(struct ocp_driver *drv);
+extern void ocp_unregister_driver(struct ocp_driver *drv);
+
+/* Build list of devices */
+extern int ocp_early_init(void) __init;
 
-extern int ocp_generic_suspend(struct ocp_device *pdev, u32 state);
-extern int ocp_generic_resume(struct ocp_device *pdev);
+/* Find a device by index */
+extern struct ocp_device *ocp_find_device(unsigned int vendor, unsigned int function, int index);
+
+/* Get a def by index */
+extern struct ocp_def *ocp_get_one_device(unsigned int vendor, unsigned int function, int index);
+
+/* Add a device by index */
+extern int ocp_add_one_device(struct ocp_def *def);
+
+/* Remove a device by index */
+extern int ocp_remove_one_device(unsigned int vendor, unsigned int function, int index);
+
+/* Iterate over devices and execute a routine */
+extern void ocp_for_each_device(void(*callback)(struct ocp_device *, void *arg), void *arg);
+
+/* Sysfs support */
+#define OCP_SYSFS_ADDTL(type, format, name, field)			\
+static ssize_t								\
+show_##name##_##field(struct device *dev, char *buf)			\
+{									\
+	struct ocp_device *odev = to_ocp_dev(dev);			\
+	type *add = odev->def->additions;				\
+									\
+	return sprintf(buf, format, add->field);			\
+}									\
+static DEVICE_ATTR(name##_##field, S_IRUGO, show_##name##_##field, NULL);
+
+#ifdef CONFIG_IBM_OCP
+#include <asm/ibm_ocp.h>
+#endif
 
 #endif				/* __OCP_H__ */
 #endif				/* __KERNEL__ */
diff -Nru a/include/asm-ppc/ocp_ids.h b/include/asm-ppc/ocp_ids.h
--- a/include/asm-ppc/ocp_ids.h	Tue May 11 14:56:45 2004
+++ b/include/asm-ppc/ocp_ids.h	Tue May 11 14:56:45 2004
@@ -1,34 +1,15 @@
 /*
- * FILE NAME: ocp_ids.h
+ * ocp_ids.h
  *
- * BRIEF MODULE DESCRIPTION:
  * OCP device ids based on the ideas from PCI
  *
- * Maintained by: Armin <akuster@mvista.com>
+ * The numbers below are almost completely arbitrary, and in fact
+ * strings might work better.  -- paulus
  *
- *
- *  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.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *  Version 1.0 08/22/02 -Armin
- *  	initial release
+ * 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.
  */
 
 /*
@@ -42,8 +23,9 @@
 
 #define	OCP_VENDOR_INVALID	0x0000
 #define	OCP_VENDOR_ARM		0x0004
+#define OCP_VENDOR_FREESCALE	0x1057
 #define OCP_VENDOR_IBM		0x1014
-#define OCP_VENDOR_MOTOROLA	0x1057
+#define OCP_VENDOR_MOTOROLA	OCP_VENDOR_FREESCALE
 #define	OCP_VENDOR_XILINX	0x10ee
 #define	OCP_VENDOR_UNKNOWN	0xFFFF
 
@@ -53,33 +35,20 @@
 #define OCP_FUNC_INVALID	0x0000
 
 /* system 0x0001 - 0x001F */
-#define	OCP_FUNC_UIC		0x0001
 
 /* Timers 0x0020 - 0x002F */
-#define OCP_FUNC_GPT		0x0020 	/* General purpose timers */
-#define OCP_FUNC_RTC		0x0021
 
 /* Serial 0x0030 - 0x006F*/
 #define OCP_FUNC_16550		0x0031
-#define OCP_FUNC_SSP		0x0032 /* sync serial port */
-#define OCP_FUNC_SCP		0x0033 	/* serial controller port */
-#define OCP_FUNC_SCC		0x0034 	/* serial contoller */
-#define OCP_FUNC_SCI		0x0035 	/* Smart card */
-#define OCP_FUNC_IIC		0x0040
-#define OCP_FUNC_USB		0x0050
-#define OCP_FUNC_IR		0x0060	
+#define OCP_FUNC_IIC		0x0032
+#define OCP_FUNC_USB		0x0033
 
 /* Memory devices 0x0090 - 0x009F */
-#define	OCP_FUNC_SDRAM		0x0091
-#define OCP_FUNC_DMA		0x0092
+#define OCP_FUNC_MAL		0x0090
 
 /* Display 0x00A0 - 0x00AF */
-#define OCP_FUNC_VIDEO		0x00A0
-#define OCP_FUNC_LED		0x00A1
-#define	OCP_FUNC_LCD		0x00A2
 
 /* Sound 0x00B0 - 0x00BF */
-#define OCP_FUNC_AUDIO		0x00B0
 
 /* Mass Storage 0x00C0 - 0xxCF */
 #define OCP_FUNC_IDE		0x00C0
@@ -87,17 +56,15 @@
 /* Misc 0x00D0 - 0x00DF*/
 #define OCP_FUNC_GPIO		0x00D0
 #define OCP_FUNC_ZMII		0x00D1
+#define OCP_FUNC_PERFMON	0x00D2	/* Performance Monitor */
+#define OCP_FUNC_RGMII		0x00D3
+#define OCP_FUNC_TAH		0x00D4
 
 /* Network 0x0200 - 0x02FF */
 #define OCP_FUNC_EMAC		0x0200
+#define OCP_FUNC_ENET		0x0201	/* TSEC & FEC */
 
 /* Bridge devices 0xE00 - 0xEFF */
-#define OCP_FUNC_HOST		0x0E00
-#define OCP_FUNC_DCR		0x0E01
-#define OCP_FUNC_OPB		0x0E02
-#define OCP_FUNC_PHY		0x0E03
-#define OCP_FUNC_EXT		0x0E04
-#define	OCP_FUNC_PCI		0x0E05
-#define	OCP_FUNC_PLB		0x0E06
+#define OCP_FUNC_OPB		0x0E00
 
 #define OCP_FUNC_UNKNOWN	0xFFFF

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 1/2] PPC32: New OCP core support
  2004-05-12  0:01 [PATCH 1/2] PPC32: New OCP core support Matt Porter
@ 2004-05-12  0:39 ` Valdis.Kletnieks
  2004-05-12  1:01   ` Matt Porter
                     ` (2 more replies)
  2004-05-12  0:57 ` Andrew Morton
                   ` (6 subsequent siblings)
  7 siblings, 3 replies; 21+ messages in thread
From: Valdis.Kletnieks @ 2004-05-12  0:39 UTC (permalink / raw)
  To: Matt Porter; +Cc: akpm, benh, linux-kernel, linuxppc-dev

[-- Attachment #1: Type: text/plain, Size: 1503 bytes --]

On Tue, 11 May 2004 17:01:50 PDT, Matt Porter said:
> New OCP infrastructure ported from 2.4 along with several
> enhancements. Please apply.

Big honking patch.  Wholesale removal of old code. Wholesale addition of new code.

And this is the closest to a hint of what an OCP in the old code:

- * @device: OCP device such as PCI, GPT, UART, OPB, IIC, GPIO, EMAC, ZMII
- * @dev_num: ocp device number whos paddr you want

And in the new:

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

And some vendor IDs that say that IBM and FreeScale make them, and Motorola
apparently rebadges/clones Freescale's (or vice versa)..

I'm *guessing* that this is some all-in-one integrated north/south/PCI/east bridge
with an APIC or similar and some I/O controllers....  Or maybe it's a board-level
designator like 'ebony' seems to be.. or something.. 

It's a UART... or a Bus-level board.. or both.. ;)

arch/ppc/Kconfig says this:
config OCP
        bool
        depends on IBM_OCP
        default y
that leads to arch/ppc/platforms/4xx/Kconfig:
config IBM_OCP
        bool
        depends on ASH || CPCI405 || EBONY || EP405 || OCOTEA || REDWOOD_5 || REDWOOD_6 || SYCAMOR
E || WALNUT
        default y

Grepping for OCP in arch/ppc/platforms/4xx/* isn't informative either..

Color me mystified.. ;)

(Actually, other than the apparent lack of any comment that says what an OCP
in fact is, I didn't see any really big style problems while scrolling through it..) 

[-- Attachment #2: Type: application/pgp-signature, Size: 226 bytes --]

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 1/2] PPC32: New OCP core support
  2004-05-12  0:01 [PATCH 1/2] PPC32: New OCP core support Matt Porter
  2004-05-12  0:39 ` Valdis.Kletnieks
@ 2004-05-12  0:57 ` Andrew Morton
  2004-05-12  1:06   ` Matt Porter
  2004-05-12  1:45   ` Matt Porter
  2004-05-12  1:30 ` Andrew Morton
                   ` (5 subsequent siblings)
  7 siblings, 2 replies; 21+ messages in thread
From: Andrew Morton @ 2004-05-12  0:57 UTC (permalink / raw)
  To: Matt Porter; +Cc: benh, linux-kernel, linuxppc-dev

Matt Porter <mporter@kernel.crashing.org> wrote:
>
> New OCP infrastructure ported from 2.4 along with several
> enhancements. Please apply.

I only received patch 1/2.

Could you please avoid using the same Subject: for different patches?  It
confuses my auto-subject-to-patch-filename-munger and it's nice to more
specifically identify each patch anwyay.


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 1/2] PPC32: New OCP core support
  2004-05-12  0:39 ` Valdis.Kletnieks
@ 2004-05-12  1:01   ` Matt Porter
  2004-05-12  1:10     ` Valdis.Kletnieks
                       ` (2 more replies)
  2004-05-12  1:45   ` Matt Porter
  2004-05-12  2:00   ` Matt Porter
  2 siblings, 3 replies; 21+ messages in thread
From: Matt Porter @ 2004-05-12  1:01 UTC (permalink / raw)
  To: Valdis.Kletnieks; +Cc: Matt Porter, akpm, benh, linux-kernel, linuxppc-dev

On Tue, May 11, 2004 at 08:39:17PM -0400, Valdis.Kletnieks@vt.edu wrote:
> On Tue, 11 May 2004 17:01:50 PDT, Matt Porter said:
> > New OCP infrastructure ported from 2.4 along with several
> > enhancements. Please apply.
> 
> Big honking patch.  Wholesale removal of old code. Wholesale addition of new code.
 
Yep.

> And this is the closest to a hint of what an OCP in the old code:

<snip>

> I'm *guessing* that this is some all-in-one integrated north/south/PCI/east bridge
> with an APIC or similar and some I/O controllers....  Or maybe it's a board-level
> designator like 'ebony' seems to be.. or something.. 
> 
> It's a UART... or a Bus-level board.. or both.. ;)

Actually, OCP stands for On-Chip Peripheral and is the basic system
we've used in ppc32 for some time now to abstract dumb peripherals
behind a standard API.  BenH did yet another rewrite of OCP in 2.4
sometime ago and I picked up that work to port to 2.6 and the new
device model.  It is a software abstraction, and easily allows us to
plug in SoC descriptors when new chips come out and use standard
apis to modify device entries on a per-board basis during
"setup_arch() time". It used to be PPC4xx-specific, but now is being
used by PPC85xx, MV64xxx, and MPC52xx based PPC systems. "Now", meaning
that the respective developers for those parts are using the OCP
working tree to base their 2.6 ports off of.

> (Actually, other than the apparent lack of any comment that says what an OCP
> in fact is, I didn't see any really big style problems while scrolling through it..) 

Ahh, good.

-Matt

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 1/2] PPC32: New OCP core support
  2004-05-12  0:57 ` Andrew Morton
@ 2004-05-12  1:06   ` Matt Porter
  2004-05-12  1:45   ` Matt Porter
  1 sibling, 0 replies; 21+ messages in thread
From: Matt Porter @ 2004-05-12  1:06 UTC (permalink / raw)
  To: Andrew Morton; +Cc: Matt Porter, benh, linux-kernel, linuxppc-dev

On Tue, May 11, 2004 at 05:57:50PM -0700, Andrew Morton wrote:
> Matt Porter <mporter@kernel.crashing.org> wrote:
> >
> > New OCP infrastructure ported from 2.4 along with several
> > enhancements. Please apply.
> 
> I only received patch 1/2.
> 
> Could you please avoid using the same Subject: for different patches?  It
> confuses my auto-subject-to-patch-filename-munger and it's nice to more
> specifically identify each patch anwyay.

Oddly I sent unique subjects:

	Subject: [PATCH 1/2] PPC32: New OCP core support
	Subject: [PATCH 2/2] PPC32: PPC4xx updates for new OCP

It appears 2/2 at least made it off my system to the remote mailer,
will doublecheck.

-Matt

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 1/2] PPC32: New OCP core support
  2004-05-12  1:01   ` Matt Porter
@ 2004-05-12  1:10     ` Valdis.Kletnieks
  2004-05-12  3:00     ` Valdis.Kletnieks
  2004-05-12  3:15     ` Valdis.Kletnieks
  2 siblings, 0 replies; 21+ messages in thread
From: Valdis.Kletnieks @ 2004-05-12  1:10 UTC (permalink / raw)
  To: Matt Porter; +Cc: akpm, benh, linux-kernel, linuxppc-dev

[-- Attachment #1: Type: text/plain, Size: 867 bytes --]

On Tue, 11 May 2004 18:01:44 PDT, Matt Porter said:

> Actually, OCP stands for On-Chip Peripheral and is the basic system
> we've used in ppc32 for some time now to abstract dumb peripherals
> behind a standard API.  BenH did yet another rewrite of OCP in 2.4
> sometime ago and I picked up that work to port to 2.6 and the new
> device model.  It is a software abstraction, and easily allows us to
> plug in SoC descriptors when new chips come out and use standard
> apis to modify device entries on a per-board basis during
> "setup_arch() time". It used to be PPC4xx-specific, but now is being
> used by PPC85xx, MV64xxx, and MPC52xx based PPC systems. "Now", meaning
> that the respective developers for those parts are using the OCP
> working tree to base their 2.6 ports off of.

Wrap a /* */ around that paragraph and add it to the top of ppc/syslib/ocp.c :)

[-- Attachment #2: Type: application/pgp-signature, Size: 226 bytes --]

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 1/2] PPC32: New OCP core support
  2004-05-12  0:01 [PATCH 1/2] PPC32: New OCP core support Matt Porter
  2004-05-12  0:39 ` Valdis.Kletnieks
  2004-05-12  0:57 ` Andrew Morton
@ 2004-05-12  1:30 ` Andrew Morton
  2004-05-12  3:00 ` Valdis.Kletnieks
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 21+ messages in thread
From: Andrew Morton @ 2004-05-12  1:30 UTC (permalink / raw)
  To: Administrator; +Cc: benh, linux-kernel, linuxppc-dev


Matt Porter <mporter@kernel.crashing.org> wrote:
>
> New OCP infrastructure ported from 2.4 along with several
> enhancements. Please apply.

I only received patch 1/2.

Could you please avoid using the same Subject: for different patches?  It
confuses my auto-subject-to-patch-filename-munger and it's nice to more
specifically identify each patch anwyay.


** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/



^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 1/2] PPC32: New OCP core support
  2004-05-12  0:57 ` Andrew Morton
  2004-05-12  1:06   ` Matt Porter
@ 2004-05-12  1:45   ` Matt Porter
  2004-05-12  2:38     ` Daniel Jacobowitz
  2004-05-12  3:15     ` Daniel Jacobowitz
  1 sibling, 2 replies; 21+ messages in thread
From: Matt Porter @ 2004-05-12  1:45 UTC (permalink / raw)
  To: Administrator; +Cc: Matt Porter, benh, linux-kernel, linuxppc-dev


On Tue, May 11, 2004 at 05:57:50PM -0700, Andrew Morton wrote:
> Matt Porter <mporter@kernel.crashing.org> wrote:
> >
> > New OCP infrastructure ported from 2.4 along with several
> > enhancements. Please apply.
>
> I only received patch 1/2.
>
> Could you please avoid using the same Subject: for different patches?  It
> confuses my auto-subject-to-patch-filename-munger and it's nice to more
> specifically identify each patch anwyay.

Oddly I sent unique subjects:

	Subject: [PATCH 1/2] PPC32: New OCP core support
	Subject: [PATCH 2/2] PPC32: PPC4xx updates for new OCP

It appears 2/2 at least made it off my system to the remote mailer,
will doublecheck.

-Matt

** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/



^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 1/2] PPC32: New OCP core support
  2004-05-12  0:39 ` Valdis.Kletnieks
  2004-05-12  1:01   ` Matt Porter
@ 2004-05-12  1:45   ` Matt Porter
  2004-05-12  2:00   ` Matt Porter
  2 siblings, 0 replies; 21+ messages in thread
From: Matt Porter @ 2004-05-12  1:45 UTC (permalink / raw)
  To: Administrator; +Cc: Matt Porter, akpm, benh, linux-kernel, linuxppc-dev


On Tue, May 11, 2004 at 08:39:17PM -0400, Valdis.Kletnieks@vt.edu wrote:
> On Tue, 11 May 2004 17:01:50 PDT, Matt Porter said:
> > New OCP infrastructure ported from 2.4 along with several
> > enhancements. Please apply.
>
> Big honking patch.  Wholesale removal of old code. Wholesale addition of new code.

Yep.

> And this is the closest to a hint of what an OCP in the old code:

<snip>

> I'm *guessing* that this is some all-in-one integrated north/south/PCI/east bridge
> with an APIC or similar and some I/O controllers....  Or maybe it's a board-level
> designator like 'ebony' seems to be.. or something..
>
> It's a UART... or a Bus-level board.. or both.. ;)

Actually, OCP stands for On-Chip Peripheral and is the basic system
we've used in ppc32 for some time now to abstract dumb peripherals
behind a standard API.  BenH did yet another rewrite of OCP in 2.4
sometime ago and I picked up that work to port to 2.6 and the new
device model.  It is a software abstraction, and easily allows us to
plug in SoC descriptors when new chips come out and use standard
apis to modify device entries on a per-board basis during
"setup_arch() time". It used to be PPC4xx-specific, but now is being
used by PPC85xx, MV64xxx, and MPC52xx based PPC systems. "Now", meaning
that the respective developers for those parts are using the OCP
working tree to base their 2.6 ports off of.

> (Actually, other than the apparent lack of any comment that says what an OCP
> in fact is, I didn't see any really big style problems while scrolling through it..)

Ahh, good.

-Matt

** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/



^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 1/2] PPC32: New OCP core support
  2004-05-12  0:39 ` Valdis.Kletnieks
  2004-05-12  1:01   ` Matt Porter
  2004-05-12  1:45   ` Matt Porter
@ 2004-05-12  2:00   ` Matt Porter
  2 siblings, 0 replies; 21+ messages in thread
From: Matt Porter @ 2004-05-12  2:00 UTC (permalink / raw)
  To: Administrator; +Cc: Matt Porter, akpm, benh, linux-kernel, linuxppc-dev



On Tue, May 11, 2004 at 08:39:17PM -0400, Valdis.Kletnieks@vt.edu wrote:
> On Tue, 11 May 2004 17:01:50 PDT, Matt Porter said:
> > New OCP infrastructure ported from 2.4 along with several
> > enhancements. Please apply.
>
> Big honking patch.  Wholesale removal of old code. Wholesale addition of new code.

Yep.

> And this is the closest to a hint of what an OCP in the old code:

<snip>

> I'm *guessing* that this is some all-in-one integrated north/south/PCI/east bridge
> with an APIC or similar and some I/O controllers....  Or maybe it's a board-level
> designator like 'ebony' seems to be.. or something..
>
> It's a UART... or a Bus-level board.. or both.. ;)

Actually, OCP stands for On-Chip Peripheral and is the basic system
we've used in ppc32 for some time now to abstract dumb peripherals
behind a standard API.  BenH did yet another rewrite of OCP in 2.4
sometime ago and I picked up that work to port to 2.6 and the new
device model.  It is a software abstraction, and easily allows us to
plug in SoC descriptors when new chips come out and use standard
apis to modify device entries on a per-board basis during
"setup_arch() time". It used to be PPC4xx-specific, but now is being
used by PPC85xx, MV64xxx, and MPC52xx based PPC systems. "Now", meaning
that the respective developers for those parts are using the OCP
working tree to base their 2.6 ports off of.

> (Actually, other than the apparent lack of any comment that says what an OCP
> in fact is, I didn't see any really big style problems while scrolling through it..)

Ahh, good.

-Matt

** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/



^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 1/2] PPC32: New OCP core support
  2004-05-12  1:45   ` Matt Porter
@ 2004-05-12  2:38     ` Daniel Jacobowitz
  2004-05-12  3:15     ` Daniel Jacobowitz
  1 sibling, 0 replies; 21+ messages in thread
From: Daniel Jacobowitz @ 2004-05-12  2:38 UTC (permalink / raw)
  To: Matt Porter; +Cc: benh, linux-kernel, linuxppc-dev

On Wed, May 12, 2004 at 02:45:44AM +0100, Matt Porter wrote:
> 
> On Tue, May 11, 2004 at 05:57:50PM -0700, Andrew Morton wrote:
> > Matt Porter <mporter@kernel.crashing.org> wrote:
> > >
> > > New OCP infrastructure ported from 2.4 along with several
> > > enhancements. Please apply.
> >
> > I only received patch 1/2.
> >
> > Could you please avoid using the same Subject: for different patches?  It
> > confuses my auto-subject-to-patch-filename-munger and it's nice to more
> > specifically identify each patch anwyay.
> 
> Oddly I sent unique subjects:
> 
> 	Subject: [PATCH 1/2] PPC32: New OCP core support
> 	Subject: [PATCH 2/2] PPC32: PPC4xx updates for new OCP
> 
> It appears 2/2 at least made it off my system to the remote mailer,
> will doublecheck.

Your mail is being duplicated by what looks like a broken news gateway,
or something similar, on linuxppc-dev:

Received: from host213-123-250-229.in-addr.btopenworld.com ([213.123.250.229]:15149                     
        "EHLO 2003SERVER.sbs2003.local") by vger.kernel.org with ESMTP                                  
        id S264904AbUELBme (ORCPT <rfc822;linux-kernel@vger.kernel.org>);                               
        Tue, 11 May 2004 21:42:34 -0400                                                                 
Received: from mail pickup service by 2003SERVER.sbs2003.local with Microsoft SMTPSVC;                  
         Wed, 12 May 2004 02:45:44 +0100                                                                

> 
> -Matt
> 
> ** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
> 
> 
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
> 

-- 
Daniel Jacobowitz

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 1/2] PPC32: New OCP core support
  2004-05-12  1:01   ` Matt Porter
  2004-05-12  1:10     ` Valdis.Kletnieks
@ 2004-05-12  3:00     ` Valdis.Kletnieks
  2004-05-12 13:32       ` Matt Porter
  2004-05-12  3:15     ` Valdis.Kletnieks
  2 siblings, 1 reply; 21+ messages in thread
From: Valdis.Kletnieks @ 2004-05-12  3:00 UTC (permalink / raw)
  To: Administrator; +Cc: akpm, benh, linux-kernel, linuxppc-dev


On Tue, 11 May 2004 18:01:44 PDT, Matt Porter said:

> Actually, OCP stands for On-Chip Peripheral and is the basic system
> we've used in ppc32 for some time now to abstract dumb peripherals
> behind a standard API. BenH did yet another rewrite of OCP in 2.4
> sometime ago and I picked up that work to port to 2.6 and the new
> device model. It is a software abstraction, and easily allows us to
> plug in SoC descriptors when new chips come out and use standard apis
> to modify device entries on a per-board basis during "setup_arch()
> time". It used to be PPC4xx-specific, but now is being used by
> PPC85xx, MV64xxx, and MPC52xx based PPC systems. "Now", meaning that
> the respective developers for those parts are using the OCP working
> tree to base their 2.6 ports off of.

Wrap a /* */ around that paragraph and add it to the top of ppc/syslib/ocp.c :)

** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/



^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 1/2] PPC32: New OCP core support
  2004-05-12  0:01 [PATCH 1/2] PPC32: New OCP core support Matt Porter
                   ` (2 preceding siblings ...)
  2004-05-12  1:30 ` Andrew Morton
@ 2004-05-12  3:00 ` Valdis.Kletnieks
  2004-05-12  3:15 ` Valdis.Kletnieks
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 21+ messages in thread
From: Valdis.Kletnieks @ 2004-05-12  3:00 UTC (permalink / raw)
  To: Administrator; +Cc: akpm, benh, linux-kernel, linuxppc-dev


On Tue, 11 May 2004 17:01:50 PDT, Matt Porter said:
> New OCP infrastructure ported from 2.4 along with several
> enhancements. Please apply.

Big honking patch. Wholesale removal of old code. Wholesale addition of
new code.

And this is the closest to a hint of what an OCP in the old code:

- * @device: OCP device such as PCI, GPT, UART, OPB, IIC, GPIO, EMAC, ZMII
- * @dev_num: ocp device number whos paddr you want

And in the new:

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

And some vendor IDs that say that IBM and FreeScale make them, and Motorola
apparently rebadges/clones Freescale's (or vice versa)..

I'm *guessing* that this is some all-in-one integrated
north/south/PCI/east bridge with an APIC or similar and some I/O
controllers.... Or maybe it's a board-level designator like 'ebony'
seems to be.. or something..

It's a UART... or a Bus-level board.. or both.. ;)

arch/ppc/Kconfig says this:
config OCP
        bool
        depends on IBM_OCP
        default y
that leads to arch/ppc/platforms/4xx/Kconfig:
config IBM_OCP
        bool
        depends on ASH || CPCI405 || EBONY || EP405 || OCOTEA || REDWOOD_5 || REDWOOD_6 || SYCAMOR
E || WALNUT
        default y

Grepping for OCP in arch/ppc/platforms/4xx/* isn't informative either..

Color me mystified.. ;)

(Actually, other than the apparent lack of any comment that says what
an OCP in fact is, I didn't see any really big style problems while
scrolling through it..)

** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/



^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 1/2] PPC32: New OCP core support
  2004-05-12  1:45   ` Matt Porter
  2004-05-12  2:38     ` Daniel Jacobowitz
@ 2004-05-12  3:15     ` Daniel Jacobowitz
  1 sibling, 0 replies; 21+ messages in thread
From: Daniel Jacobowitz @ 2004-05-12  3:15 UTC (permalink / raw)
  To: Administrator; +Cc: benh, linux-kernel, linuxppc-dev


On Wed, May 12, 2004 at 02:45:44AM +0100, Matt Porter wrote:
>
> On Tue, May 11, 2004 at 05:57:50PM -0700, Andrew Morton wrote:
> > Matt Porter <mporter@kernel.crashing.org> wrote:
> > >
> > > New OCP infrastructure ported from 2.4 along with several
> > > enhancements. Please apply.
> >
> > I only received patch 1/2.
> >
> > Could you please avoid using the same Subject: for different patches?  It
> > confuses my auto-subject-to-patch-filename-munger and it's nice to more
> > specifically identify each patch anwyay.
>
> Oddly I sent unique subjects:
>
> 	Subject: [PATCH 1/2] PPC32: New OCP core support
> 	Subject: [PATCH 2/2] PPC32: PPC4xx updates for new OCP
>
> It appears 2/2 at least made it off my system to the remote mailer,
> will doublecheck.

Your mail is being duplicated by what looks like a broken news gateway,
or something similar, on linuxppc-dev:

Received: from host213-123-250-229.in-addr.btopenworld.com ([213.123.250.229]:15149
        "EHLO 2003SERVER.sbs2003.local") by vger.kernel.org with ESMTP
        id S264904AbUELBme (ORCPT <rfc822;linux-kernel@vger.kernel.org>);
        Tue, 11 May 2004 21:42:34 -0400
Received: from mail pickup service by 2003SERVER.sbs2003.local with Microsoft SMTPSVC;
         Wed, 12 May 2004 02:45:44 +0100

>
> -Matt
>
>
>
>

--
Daniel Jacobowitz

** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/



^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 1/2] PPC32: New OCP core support
  2004-05-12  1:01   ` Matt Porter
  2004-05-12  1:10     ` Valdis.Kletnieks
  2004-05-12  3:00     ` Valdis.Kletnieks
@ 2004-05-12  3:15     ` Valdis.Kletnieks
  2 siblings, 0 replies; 21+ messages in thread
From: Valdis.Kletnieks @ 2004-05-12  3:15 UTC (permalink / raw)
  To: Administrator; +Cc: akpm, benh, linux-kernel, linuxppc-dev



On Tue, 11 May 2004 18:01:44 PDT, Matt Porter said:

> Actually, OCP stands for On-Chip Peripheral and is the basic system
> we've used in ppc32 for some time now to abstract dumb peripherals
> behind a standard API. BenH did yet another rewrite of OCP in 2.4
> sometime ago and I picked up that work to port to 2.6 and the new
> device model. It is a software abstraction, and easily allows us to
> plug in SoC descriptors when new chips come out and use standard apis
> to modify device entries on a per-board basis during "setup_arch()
> time". It used to be PPC4xx-specific, but now is being used by
> PPC85xx, MV64xxx, and MPC52xx based PPC systems. "Now", meaning that
> the respective developers for those parts are using the OCP working
> tree to base their 2.6 ports off of.

Wrap a /* */ around that paragraph and add it to the top of ppc/syslib/ocp.c :)

** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/



^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 1/2] PPC32: New OCP core support
  2004-05-12  0:01 [PATCH 1/2] PPC32: New OCP core support Matt Porter
                   ` (3 preceding siblings ...)
  2004-05-12  3:00 ` Valdis.Kletnieks
@ 2004-05-12  3:15 ` Valdis.Kletnieks
  2004-05-12  5:48 ` Christoph Hellwig
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 21+ messages in thread
From: Valdis.Kletnieks @ 2004-05-12  3:15 UTC (permalink / raw)
  To: Administrator; +Cc: akpm, benh, linux-kernel, linuxppc-dev



On Tue, 11 May 2004 17:01:50 PDT, Matt Porter said:
> New OCP infrastructure ported from 2.4 along with several
> enhancements. Please apply.

Big honking patch. Wholesale removal of old code. Wholesale addition of
new code.

And this is the closest to a hint of what an OCP in the old code:

- * @device: OCP device such as PCI, GPT, UART, OPB, IIC, GPIO, EMAC, ZMII
- * @dev_num: ocp device number whos paddr you want

And in the new:

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

And some vendor IDs that say that IBM and FreeScale make them, and Motorola
apparently rebadges/clones Freescale's (or vice versa)..

I'm *guessing* that this is some all-in-one integrated
north/south/PCI/east bridge with an APIC or similar and some I/O
controllers.... Or maybe it's a board-level designator like 'ebony'
seems to be.. or something..

It's a UART... or a Bus-level board.. or both.. ;)

arch/ppc/Kconfig says this:
config OCP
        bool
        depends on IBM_OCP
        default y
that leads to arch/ppc/platforms/4xx/Kconfig:
config IBM_OCP
        bool
        depends on ASH || CPCI405 || EBONY || EP405 || OCOTEA || REDWOOD_5 || REDWOOD_6 || SYCAMOR
E || WALNUT
        default y

Grepping for OCP in arch/ppc/platforms/4xx/* isn't informative either..

Color me mystified.. ;)

(Actually, other than the apparent lack of any comment that says what
an OCP in fact is, I didn't see any really big style problems while
scrolling through it..)

** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/



^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 1/2] PPC32: New OCP core support
  2004-05-12  0:01 [PATCH 1/2] PPC32: New OCP core support Matt Porter
                   ` (4 preceding siblings ...)
  2004-05-12  3:15 ` Valdis.Kletnieks
@ 2004-05-12  5:48 ` Christoph Hellwig
  2004-05-12  6:15 ` Christoph Hellwig
  2004-05-12  6:30 ` Christoph Hellwig
  7 siblings, 0 replies; 21+ messages in thread
From: Christoph Hellwig @ 2004-05-12  5:48 UTC (permalink / raw)
  To: Matt Porter; +Cc: akpm, benh, linux-kernel, linuxppc-dev

On Tue, May 11, 2004 at 05:01:50PM -0700, Matt Porter wrote:
> New OCP infrastructure ported from 2.4 along with several
> enhancements. Please apply.

The old-style PM callback (using struct pm_dev) is bogus, please kill
that part.


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 1/2] PPC32: New OCP core support
  2004-05-12  0:01 [PATCH 1/2] PPC32: New OCP core support Matt Porter
                   ` (5 preceding siblings ...)
  2004-05-12  5:48 ` Christoph Hellwig
@ 2004-05-12  6:15 ` Christoph Hellwig
  2004-05-12 13:39   ` Matt Porter
  2004-05-12  6:30 ` Christoph Hellwig
  7 siblings, 1 reply; 21+ messages in thread
From: Christoph Hellwig @ 2004-05-12  6:15 UTC (permalink / raw)
  To: Administrator; +Cc: akpm, benh, linux-kernel, linuxppc-dev


On Tue, May 11, 2004 at 05:01:50PM -0700, Matt Porter wrote:
> New OCP infrastructure ported from 2.4 along with several
> enhancements. Please apply.

The old-style PM callback (using struct pm_dev) is bogus, please kill
that part.


** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/



^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 1/2] PPC32: New OCP core support
  2004-05-12  0:01 [PATCH 1/2] PPC32: New OCP core support Matt Porter
                   ` (6 preceding siblings ...)
  2004-05-12  6:15 ` Christoph Hellwig
@ 2004-05-12  6:30 ` Christoph Hellwig
  7 siblings, 0 replies; 21+ messages in thread
From: Christoph Hellwig @ 2004-05-12  6:30 UTC (permalink / raw)
  To: Administrator; +Cc: akpm, benh, linux-kernel, linuxppc-dev



On Tue, May 11, 2004 at 05:01:50PM -0700, Matt Porter wrote:
> New OCP infrastructure ported from 2.4 along with several
> enhancements. Please apply.

The old-style PM callback (using struct pm_dev) is bogus, please kill
that part.


** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/



^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 1/2] PPC32: New OCP core support
  2004-05-12  3:00     ` Valdis.Kletnieks
@ 2004-05-12 13:32       ` Matt Porter
  0 siblings, 0 replies; 21+ messages in thread
From: Matt Porter @ 2004-05-12 13:32 UTC (permalink / raw)
  To: Valdis.Kletnieks; +Cc: akpm, benh, linux-kernel

On Wed, May 12, 2004 at 04:00:46AM +0100, Valdis.Kletnieks@vt.edu wrote:
> 
> On Tue, 11 May 2004 18:01:44 PDT, Matt Porter said:
> 
> > Actually, OCP stands for On-Chip Peripheral and is the basic system
> > we've used in ppc32 for some time now to abstract dumb peripherals
> > behind a standard API. BenH did yet another rewrite of OCP in 2.4
> > sometime ago and I picked up that work to port to 2.6 and the new
> > device model. It is a software abstraction, and easily allows us to
> > plug in SoC descriptors when new chips come out and use standard apis
> > to modify device entries on a per-board basis during "setup_arch()
> > time". It used to be PPC4xx-specific, but now is being used by
> > PPC85xx, MV64xxx, and MPC52xx based PPC systems. "Now", meaning that
> > the respective developers for those parts are using the OCP working
> > tree to base their 2.6 ports off of.
> 
> Wrap a /* */ around that paragraph and add it to the top of ppc/syslib/ocp.c :)

I incorporated a more polished version into the updated patch I just
sent.

Thanks.

-Matt

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 1/2] PPC32: New OCP core support
  2004-05-12  6:15 ` Christoph Hellwig
@ 2004-05-12 13:39   ` Matt Porter
  0 siblings, 0 replies; 21+ messages in thread
From: Matt Porter @ 2004-05-12 13:39 UTC (permalink / raw)
  To: Christoph Hellwig, akpm, benh, linux-kernel

On Wed, May 12, 2004 at 07:15:15AM +0100, Christoph Hellwig wrote:
> 
> On Tue, May 11, 2004 at 05:01:50PM -0700, Matt Porter wrote:
> > New OCP infrastructure ported from 2.4 along with several
> > enhancements. Please apply.
> 
> The old-style PM callback (using struct pm_dev) is bogus, please kill
> that part.

Thanks. I killed off the deprecated PM stuff in the updated patch
I just sent out.

-Matt

^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2004-05-12 13:41 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-05-12  0:01 [PATCH 1/2] PPC32: New OCP core support Matt Porter
2004-05-12  0:39 ` Valdis.Kletnieks
2004-05-12  1:01   ` Matt Porter
2004-05-12  1:10     ` Valdis.Kletnieks
2004-05-12  3:00     ` Valdis.Kletnieks
2004-05-12 13:32       ` Matt Porter
2004-05-12  3:15     ` Valdis.Kletnieks
2004-05-12  1:45   ` Matt Porter
2004-05-12  2:00   ` Matt Porter
2004-05-12  0:57 ` Andrew Morton
2004-05-12  1:06   ` Matt Porter
2004-05-12  1:45   ` Matt Porter
2004-05-12  2:38     ` Daniel Jacobowitz
2004-05-12  3:15     ` Daniel Jacobowitz
2004-05-12  1:30 ` Andrew Morton
2004-05-12  3:00 ` Valdis.Kletnieks
2004-05-12  3:15 ` Valdis.Kletnieks
2004-05-12  5:48 ` Christoph Hellwig
2004-05-12  6:15 ` Christoph Hellwig
2004-05-12 13:39   ` Matt Porter
2004-05-12  6:30 ` Christoph Hellwig

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox