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 at 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/



Reply via email to