All of lore.kernel.org
 help / color / mirror / Atom feed
* More OCP cleanups
@ 2002-06-07  8:31 David Gibson
  0 siblings, 0 replies; only message in thread
From: David Gibson @ 2002-06-07  8:31 UTC (permalink / raw)
  To: Armin Kuster; +Cc: linuxppc-embedded, Paul Mackerras


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
david@gibson.dropbear.id.au	| 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/

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2002-06-07  8:31 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-06-07  8:31 More OCP cleanups David Gibson

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.