Subject: More OCP cleanups

From: David Gibson <[email-masked]>
Date: Fri, 7 Jun 2002 18:31:46 +1000

Ok, never mind that last OCP change I sent you, this patch obsoletes
it.  This cleans up a bunch of functions in ocp.c and removes some
unused cruft from ocp.h.

More importantly though, it replaces the irq_resources field of struct
ocp_dev with a simple integer irq field.  The only thing that ever
used the irq_resources field to store more than a single irq was the
EMAC, and it required special cases all over the place anyway.

The next step is to get rid of irq_resources entirely, since its use
for the EMAC is a horrible abstraction violation.

diff -urN /home/dgibson/kernel/linuxppc_2_4_devel/arch/ppc/kernel/ocp.c linux-grinch/arch/ppc/kernel/ocp.c
--- /home/dgibson/kernel/linuxppc_2_4_devel/arch/ppc/kernel/ocp.c	Wed May 29 10:05:14 2002
+++ linux-grinch/arch/ppc/kernel/ocp.c	Fri Jun  7 18:20:02 2002
@@ -126,19 +126,14 @@

 	for (i = 0; core_ocp[i].type != OCP_NULL_TYPE; i++) {
 		if (type == core_ocp[i].type) {
-			if (dev_num > a) {
-				a++;
-			} else {
-				break;
-			}
+			if (a == dev_num)
+				return core_ocp[i].irq;
+
+			a++;
 		}
 	}

-	if (a > (ocp_get_max(type) - 1)) {
-		return(OCP_IRQ_NA);
-	} else {
-		return(core_ocp[i].irq);
-	}
+	return OCP_IRQ_NA;
 }

 /**
@@ -157,19 +152,14 @@

 	for (i = 0; core_ocp[i].type != OCP_NULL_TYPE; i++) {
 		if (type == core_ocp[i].type) {
-			if (dev_num > a) {
-				a++;
-			} else {
-				break;
-			}
+			if (a == dev_num)
+				return core_ocp[i].paddr;
+
+			a++;
 		}
 	}

-	if (a > (ocp_get_max(type) - 1)) {
-		return 0x0;
-	} else {
-		return ((unsigned long) core_ocp[i].paddr);
-	}
+	return 0;
 }

@@ -180,57 +170,47 @@
 	int a, i;
 	a = 0;

+	strcpy(ocp->name,ocp_type_info[ocp->type].name);
+
 	for (i = 0; core_ocp[i].type != OCP_NULL_TYPE; i++) {
 		if (ocp->type == core_ocp[i].type) {
-			if (ocp->num > a) {
-				a++;
-			} else {
-				break;
+			if (a == ocp->num) {
+				ocp->paddr = core_ocp[i].paddr;
+				ocp->irq = core_ocp[i].irq;
+				return 1;
 			}
+
+			a++;
 		}
 	}

-	strcpy(ocp->name,ocp_type_info[ocp->type].name);
-
-	if (a > (ocp_get_max(ocp->type) - 1)) {
-		ocp->paddr = 0x0;
-		ocp->irq_resource[0][0].irq = OCP_IRQ_NA;
-		return 0;
-	} else {
-		ocp->paddr = core_ocp[i].paddr;
-		ocp->irq_resource[0][0].irq = core_ocp[i].irq;
-	}
-	return 1;
+	ocp->paddr = 0;
+	ocp->irq = OCP_IRQ_NA;
+	return 0;
 }

 /**
- * ocp_get_numtypes - This determines how many "ocp type's" are
+ * ocp_get_numtypes - This determines how many OCP devices of a given
+ * type are registered.
  * registered
  * @type: OCP type such as PCI, GPT, UART, OPB, IIC, GPIO, EMAC, ZMII,
  *
- * The routine returns number of types are registered or -ENXIO when
- * no type is registered
+ * The routine returns number of devices registered of the given type.
  */
-int
+static int
 ocp_get_numtypes(int type)
 {
-	int count, max;
+	int count = 0;
 	struct ocp_dev *ocp;
 	struct list_head *ocp_l;

-	count = 0;
-	max = ocp_get_max(type);
-
-	for (ocp_l = ocp_list.next; ocp_l != &ocp_list; ocp_l = ocp_l->next) {
+	list_for_each(ocp_l, &ocp_list) {
 		ocp = list_entry(ocp_l, struct ocp_dev, ocp_list);
 		if (type == ocp->type)
 			count++;
-		if (count > max)
-			return -ENXIO;
 	}

-	return (count);
-
+	return count;
 }

 /**
@@ -297,17 +277,18 @@
 int
 ocp_register(struct ocp_dev *drv)
 {
-	int index;
-	int count = 0;
+	int max;
+
+	max = ocp_get_max(drv->type);

 	list_add(&drv->ocp_list, &ocp_list);

-	if ((count = ocp_get_numtypes(drv->type)) < 0) {
+	drv->num = ocp_get_numtypes(drv->type) - 1;
+	if (drv->num >= max) {
 		list_del(&drv->ocp_list);
 		return -ENXIO;
 	}

-	drv->num = count - 1;
 	if (!ocp_set_dev(drv)) {
 		list_del(&drv->ocp_list);
 		return -ENXIO;
@@ -318,7 +299,7 @@
 #endif
 #ifdef OCP_DEBUG
 	printk("Dev: %s Num:%d @ paddr:0x%x irq:%d\n", drv->name, drv->num,
-	       drv->paddr, drv->irq_resource[0][0].irq);
+	       drv->paddr, drv->irq);
 #endif
 	return (drv->num);
 }
@@ -356,26 +337,22 @@
 {
 	struct ocp_dev *ocp;
 	struct list_head *ocp_l;
-	int max;
 	int count = 0;
-	if ((max = ocp_get_numtypes(type)) > 0)
-		for (ocp_l = ocp_list.next;
-		     (count < max) && (ocp_l != &ocp_list);
-		     ocp_l = ocp_l->next) {
-			ocp = list_entry(ocp_l, struct ocp_dev, ocp_list);
-			if (type == ocp->type) {
-				if (dev_num == count)
-					return ocp;
-				count++;
-			}
+
+	list_for_each(ocp_l, &ocp_list) {
+		ocp = list_entry(ocp_l, struct ocp_dev, ocp_list);
+		if (type == ocp->type) {
+			if (dev_num == count)
+				return ocp;
+			count++;
 		}
+	}
 	return NULL;
 }

 EXPORT_SYMBOL(ocp_get_irq);
 EXPORT_SYMBOL(ocp_get_paddr);
 EXPORT_SYMBOL(ocp_get_max);
-EXPORT_SYMBOL(ocp_get_numtypes);
 EXPORT_SYMBOL(ocp_get_dev);
 EXPORT_SYMBOL(ocp_alloc_dev);
 EXPORT_SYMBOL(ocp_free_dev);
diff -urN /home/dgibson/kernel/linuxppc_2_4_devel/arch/ppc/kernel/ocp_proc.c linux-grinch/arch/ppc/kernel/ocp_proc.c
--- /home/dgibson/kernel/linuxppc_2_4_devel/arch/ppc/kernel/ocp_proc.c	Fri May 31 09:49:15 2002
+++ linux-grinch/arch/ppc/kernel/ocp_proc.c	Fri Jun  7 17:53:52 2002
@@ -50,6 +50,7 @@
 #include <asm/byteorder.h>
 #include <asm/ocp.h>
 extern struct type_info ocp_type_info[];
+extern struct irq_resources irq_resource[][OCP_MAX_IRQS];

 /* iterator */
 static void *
@@ -91,33 +92,21 @@

 	drv = ocp_dev_g(p);
 	seq_printf(m, "%s\t %02d", drv->name, drv->num);
-	switch (drv->type) {
-	case UART:
-	case IDE:
-	case USB:
-	case IIC:
-		seq_printf(m, " %02d", drv->irq_resource[0][0].irq);
-		break;
-	case GPIO:
-	case ZMII:
-		/* no IRQ */
-		seq_printf(m, " N/A");
-		break;
-	case EMAC:
-
+	if (drv->type == EMAC) {
 		for (i = 0; i < OCP_MAX_IRQS; i++) {
 			seq_printf(m, " %02d",
-				   drv->irq_resource[drv->num][i].irq);
+				   irq_resource[drv->num][i].irq);
 		}
-
-		break;
-	default:
-		seq_printf(m, " %02d", drv->irq_resource[0][0].irq);
+	} else if (drv->irq != OCP_IRQ_NA) {
+		seq_printf(m, " %02d", drv->irq);
+	} else {
+		/* no IRQ */
+		seq_printf(m, " N/A");
 	}

 	seq_printf(m, " %8.8lx", drv->paddr);
 	if (drv->vaddr)
-		seq_printf(m, " %8.8lx", drv->vaddr);
+		seq_printf(m, " %p", drv->vaddr);
 	else
 		seq_printf(m, " N/A");
 	seq_putc(m, '\n');
@@ -147,33 +136,22 @@
 	drv = ocp_dev_g(p);
 	seq_printf(m, "  Device: %s%02d\n", drv->name, drv->num);
 	seq_printf(m, "  description: %s\n",ocp_type_info[drv->type].desc);
-	switch (drv->type) {
-	case UART:
-	case IDE:
-	case USB:
-	case IIC:
-		seq_printf(m, "   Irq: %02d\n", drv->irq_resource[0][0].irq);
-		break;
-	case GPIO:
-	case ZMII:
-		/* no IRQ */
-		seq_printf(m, "    Irq: N/A\n");
-		break;
-	case EMAC:
+	if (drv->type == EMAC) { /* Blech, special case */
 		for (i = 0; i < OCP_MAX_IRQS; i++) {
 			seq_printf(m, "    Irq: %02d   Name: %s\n",
-				   drv->irq_resource[drv->num][i].irq,
-				   drv->irq_resource[drv->num][i].irq_name);
+				   irq_resource[drv->num][i].irq,
+				   irq_resource[drv->num][i].irq_name);
 		}
-
-		break;
-	default:
-		seq_printf(m, "   Irq: %02d\n", drv->irq_resource[0][0].irq);
+	} else if (drv->irq != OCP_IRQ_NA) {
+		seq_printf(m, "   Irq: %02d\n", drv->irq);
+	} else {
+		/* no IRQ */
+		seq_printf(m, "    Irq: N/A\n");
 	}

 	seq_printf(m, "   Physical Address start 0x%lx\n", drv->paddr);
 	if (drv->vaddr)
-		seq_printf(m, "   Virtual  Address start 0x%lx\n\n", drv->vaddr);
+		seq_printf(m, "   Virtual  Address start %p\n\n", drv->vaddr);
 	else
 		seq_printf(m, "   Virtual  Address start N/A\n\n");
 	return 0;
@@ -209,7 +187,7 @@
 int
 ocp_proc_attach_device(struct ocp_dev *dev)
 {
-	struct proc_dir_entry *de, *e;
+	struct proc_dir_entry *e;
 	char name[16];

 	sprintf(name, "%s%d", dev->name, dev->num);
diff -urN /home/dgibson/kernel/linuxppc_2_4_devel/arch/ppc/kernel/ocp_uart.c linux-grinch/arch/ppc/kernel/ocp_uart.c
--- /home/dgibson/kernel/linuxppc_2_4_devel/arch/ppc/kernel/ocp_uart.c	Wed May 29 10:05:14 2002
+++ linux-grinch/arch/ppc/kernel/ocp_uart.c	Fri Jun  7 17:53:00 2002
@@ -102,7 +102,7 @@
 		uart_drv->type = UART;
 		/* this returns the next uart number */
 		if ((curr_uart = ocp_register(uart_drv)) != -ENXIO) {
-			uart_drv->irq_resource[0][0].irq =
+			uart_drv->irq =
 			    uart_table[curr_uart].irq;

 		} else {
diff -urN /home/dgibson/kernel/linuxppc_2_4_devel/drivers/i2c/i2c-adap-ibm_ocp.c linux-grinch/drivers/i2c/i2c-adap-ibm_ocp.c
--- /home/dgibson/kernel/linuxppc_2_4_devel/drivers/i2c/i2c-adap-ibm_ocp.c	Wed May 29 10:05:14 2002
+++ linux-grinch/drivers/i2c/i2c-adap-ibm_ocp.c	Fri Jun  7 17:48:17 2002
@@ -122,7 +122,7 @@
 	 * sleep.  This process will be awakened by two events -- either the
 	 * the IIC peripheral interrupts or the timeout expires.
 	 */
-	if (iic_dev->irq_resource[0][0].irq > 0) {
+	if (iic_dev->irq > 0) {
 		cli();
 		if (iic_pending == 0) {
 			interruptible_sleep_on_timeout(&
@@ -180,9 +180,9 @@

 	for (i = 0; i < ocp_get_max(IIC); i++) {
 		iic_drv = ocp_get_dev(IIC, i);
-		if (iic_drv->irq_resource[0][0].irq > 0) {
-			disable_irq(iic_drv->irq_resource[0][0].irq);
-			free_irq(iic_drv->irq_resource[0][0].irq, 0);
+		if (iic_drv->irq > 0) {
+			disable_irq(iic_drv->irq);
+			free_irq(iic_drv->irq, 0);
 		}
 	}

@@ -253,11 +253,11 @@
 			    ("iic_hw_resrc_init: Physical Base address: 0x%lx\n",
 			     iic_drv->paddr));
 			DEB(printk
-			    ("iic_hw_resrc_init: ioremapped base address: 0x%lx\n",
+			    ("iic_hw_resrc_init: ioremapped base address: %p\n",
 			     iic_drv->vaddr));
 			DEB(printk
 			    ("Adapter irq %x\n",
-			     iic_drv->irq_resource[0][0].irq));
+			     iic_drv->irq));

 			strcpy(adap->name, "IBM OCP IIC adapter");
 			adap->data = (void *) iic_drv;
@@ -270,15 +270,14 @@

 			init_waitqueue_head(&(iic_wait[curr_iic]));

-			if (iic_drv->irq_resource[0][0].irq > 0) {
+			if (iic_drv->irq > 0) {
 				if (request_irq
-				    (iic_drv->irq_resource[0][0].irq,
+				    (iic_drv->irq,
 				     iic_ibmocp_handler, 0, "IBM OCP IIC",
 				     iic_drv)) {
 					printk(KERN_ERR "iic_hw_resrc_init: Request irq%d
-				failed\n", iic_drv->irq_resource[0][0].
-					       irq);
-					iic_drv->irq_resource[0][0].irq = 0;
+				failed\n", iic_drv->irq);
+					iic_drv->irq = 0;
 				} else {
 					DEB3(printk
 					     ("iic_hw_resrc_init: Enabled interrupt\n"));
@@ -290,7 +289,7 @@

 			DEB(printk
 			    (KERN_INFO
-			     "iic_ibmocp_init: found device at %#lx.\n\n",
+			     "iic_ibmocp_init: found device at %p.\n\n",
 			     iic_drv->vaddr));
 		} else {
 			ocp_free_dev(iic_drv);
diff -urN /home/dgibson/kernel/linuxppc_2_4_devel/drivers/ide/ibm_ocp_ide.c linux-grinch/drivers/ide/ibm_ocp_ide.c
--- /home/dgibson/kernel/linuxppc_2_4_devel/drivers/ide/ibm_ocp_ide.c	Wed May 29 10:05:14 2002
+++ linux-grinch/drivers/ide/ibm_ocp_ide.c	Fri Jun  7 18:16:21 2002
@@ -656,7 +656,7 @@
 		hw->io_ports[IDE_CONTROL_OFFSET] = (int) (&(idp->si_c0adc));

 		if (irq)
-			*irq = ide_dev->irq_resource[0][0].irq;
+			*irq = ide_dev->irq;

 		pio_mode[0] = pio_mode[1] = -1;

@@ -693,6 +693,6 @@

 		memcpy(ide_hwifs[data_port].io_ports, hw->io_ports,
 		       sizeof (hw->io_ports));
-		ide_hwifs[data_port].irq = ide_dev->irq_resource[0][0].irq;
+		ide_hwifs[data_port].irq = ide_dev->irq;
 	}
 }
diff -urN /home/dgibson/kernel/linuxppc_2_4_devel/include/asm-ppc/ocp.h linux-grinch/include/asm-ppc/ocp.h
--- /home/dgibson/kernel/linuxppc_2_4_devel/include/asm-ppc/ocp.h	Thu May 30 11:16:20 2002
+++ linux-grinch/include/asm-ppc/ocp.h	Fri Jun  7 17:46:50 2002
@@ -51,19 +51,11 @@

 #include <linux/list.h>
 #include <linux/config.h>
-#include <linux/devfs_fs_kernel.h>

 #include <asm/mmu.h>		/* For phys_addr_t */

-#if defined(CONFIG_IBM_OCP)
-#include <platforms/ibm_ocp.h>
-#endif
-
 #define OCP_MAX_IRQS	7
 #define MAX_EMACS	4
-#define MAX_OCP_DEVS	20
-#define OCP_ACTIVE	1
-#define OCP_INACTIVE	2
 #define OCP_IRQ_NA	-1	/* used when ocp device does not have an irq */
 #define OCP_IRQ_MUL	-2	/* used for ocp devices with multiply irqs */
 #define OCP_NULL_TYPE	-1	/* used to mark end of list */
@@ -120,14 +112,8 @@
 	phys_addr_t paddr;
 	void *vaddr;
 	u32 flags;
-	struct irq_resources irq_resource[MAX_EMACS][OCP_MAX_IRQS];
+	int irq;
 	void *ocpdev;		/* ocp device struct  pointer */
-	u64		dma_mask;	/* Mask of the bits of bus address this
-					   device implements.  Normally this is
-					   0xffffffff.  You only need to change
-					   this if your device has broken DMA
-					   or supports 64-bit transfers.  */
-
 #if defined(CONFIG_PM)
 	u32 current_state;	/* Current operating state. In ACPI-speak,
 				   this is D0-D3, D0 being fully functional,
@@ -139,14 +125,10 @@
 	int (*enable_wake) (u32 state, int enable);	/* Enable wake event */
 #endif
 #if defined(CONFIG_OCP_PROC)
-	struct proc_dir_entry *procdir;	/* dir entry in /proc/bus */
 	struct proc_dir_entry *procent;	/* device entry in /proc/bus/ocp */
 #endif
 };
 #define ocp_dev_g(n) list_entry(n, struct ocp_dev, ocp_list)
-#define ocp_for_each_dev(dev) \
-	for(dev = ocp_dev_g(ocp_devs.next); dev != ocp_dev_g(&ocp_devs); dev = ocp_dev_g(dev->ocp_list.next))
-

 extern int ocp_register(struct ocp_dev *drv);
 extern void ocp_unregister(struct ocp_dev *drv);
@@ -156,7 +138,6 @@
 extern int ocp_proc_attach_device(struct ocp_dev *dev);
 extern int ocp_proc_detach_device(struct ocp_dev *dev);
 extern unsigned long ocp_get_paddr(int type, int dev_num);
-extern int ocp_get_numtypes(int type);
 extern int ocp_get_max(int type);
 extern int ocp_get_irq(int type, int dev_num);

--
David Gibson			| For every complex problem there is a
[email-masked]	| solution which is simple, neat and
				| wrong.  -- H.L. Mencken
http://www.ozlabs.org/people/dgibson

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