]> git.hungrycats.org Git - linux/commitdiff
[ARM] Update PCI host bridge drivers for GregKH PCI cleanups.
authorRussell King <rmk@flint.arm.linux.org.uk>
Sun, 29 Sep 2002 21:06:15 +0000 (22:06 +0100)
committerRussell King <rmk@flint.arm.linux.org.uk>
Sun, 29 Sep 2002 21:06:15 +0000 (22:06 +0100)
arch/arm/kernel/plx90x0.c
arch/arm/kernel/via82c505.c
arch/arm/mach-footbridge/dc21285.c
arch/arm/mach-integrator/pci_v3.c
arch/arm/mach-iop310/iop310-pci.c

index bee4330b9c4e3f8dfbbdc7076324fd622b69d83e..f843e12267ed02f5238d5285281a82675836ee3f 100644 (file)
@@ -34,9 +34,9 @@
 #define PLX_SET_CONFIG                                                 \
        { unsigned long flags;                                          \
        local_irq_save(flags);                                          \
-       __raw_writel((1<<31 | (dev->bus->number << 16)                  \
-               | (dev->devfn << 8) | (where & ~3)                      \
-               | ((dev->bus->number == 0)?0:1)), PLX_BASE + 0xac);     \
+       __raw_writel((1<<31 | (bus->number << 16)                       \
+               | (devfn << 8) | (where & ~3)                           \
+               | ((bus->number == 0)?0:1)), PLX_BASE + 0xac);          \
 
 #define PLX_CONFIG_WRITE(size)                                         \
        PLX_SET_CONFIG                                                  \
 
 /* Configuration space access routines */
 
-static int
-plx90x0_read_config_byte (struct pci_dev *dev,
-                         int where, u8 *value)
-{
-       PLX_CONFIG_READ(b)
-}
-
-static int
-plx90x0_read_config_word (struct pci_dev *dev,
-                         int where, u16 *value)
-{
-       PLX_CONFIG_READ(w)
-}
-
 static int 
-plx90x0_read_config_dword (struct pci_dev *dev,
-                          int where, u32 *value)
+plx90x0_read_config (struct pci_bus *bus, unsigned int devfn, int where,
+                    int where, int size, u32 *value)
 {
-       PLX_CONFIG_READ(l)
-}
-
-static int 
-plx90x0_write_config_byte (struct pci_dev *dev,
-                          int where, u8 value)
-{
-       PLX_CONFIG_WRITE(b)
+       switch (size) {
+       case 1:
+               PLX_CONFIG_READ(b)
+               break;
+       case 2:
+               PLX_CONFIG_READ(w)
+               break;
+       case 4:
+               PLX_CONFIG_READ(l)
+               break;
+       }
+       return PCIBIOS_SUCCESSFUL;
 }
 
 static int 
-plx90x0_write_config_word (struct pci_dev *dev,
-                          int where, u16 value)
+plx90x0_write_config (struct pci_bus *bus, unsigned int devfn, int where,
+                     int where, int size, u32 value)
 {
-       PLX_CONFIG_WRITE(w)
+       switch (size) {
+       case 1:
+               PLX_CONFIG_WRITE(b)
+               break;
+       case 2:
+               PLX_CONFIG_WRITE(w)
+               break;
+       case 4:
+               PLX_CONFIG_WRITE(l)
+               break;
+       }
+       return PCIBIOS_SUCCESSFUL;
 }
 
-static int 
-plx90x0_write_config_dword (struct pci_dev *dev,
-                           int where, u32 value)
+static struct pci_ops plx90x0_ops = 
 {
-       PLX_CONFIG_WRITE(l)
-}
+       .read   = plx90x0_read_config,
+       .write  = plx90x0_write_config,
+};
 
 static void 
 plx_syserr_handler(int irq, void *handle, struct pt_regs *regs)
@@ -108,17 +108,6 @@ plx_syserr_handler(int irq, void *handle, struct pt_regs *regs)
        __raw_writew(0xf000, PLX_BASE + 6);
 }
 
-static struct pci_ops 
-plx90x0_ops = 
-{
-       plx90x0_read_config_byte,
-       plx90x0_read_config_word,
-       plx90x0_read_config_dword,
-       plx90x0_write_config_byte,
-       plx90x0_write_config_word,
-       plx90x0_write_config_dword,
-};
-
 /*
  * Initialise the PCI system.
  */
index 4ca621dbd825252b1b818ae2b9478f2202029172..345b9b6c73da16eae37abbdaab078bb2e039539a 100644 (file)
 
 #define MAX_SLOTS              7
 
-#define CONFIG_CMD(dev, where)   (0x80000000 | (dev->bus->number << 16) | (dev->devfn << 8) | (where & ~3))
+#define CONFIG_CMD(bus, devfn, where)   (0x80000000 | (bus->number << 16) | (devfn << 8) | (where & ~3))
 
 static int
-via82c505_read_config_byte(struct pci_dev *dev, int where, u8 *value)
+via82c505_read_config(struct pci_bus *bus, unsigned int devfn, int where,
+                     int size, u32 *value)
 {
        outl(CONFIG_CMD(dev,where),0xCF8);
-       *value=inb(0xCFC + (where&3));
-       return PCIBIOS_SUCCESSFUL;
-}
-
-static int
-via82c505_read_config_word(struct pci_dev *dev, int where, u16 *value)
-{
-       outl(CONFIG_CMD(dev,where),0xCF8);
-       *value=inw(0xCFC + (where&2));
-       return PCIBIOS_SUCCESSFUL;
-}
-
-static int
-via82c505_read_config_dword(struct pci_dev *dev, int where, u32 *value)
-{
-       outl(CONFIG_CMD(dev,where),0xCF8);
-       *value=inl(0xCFC);
-       return PCIBIOS_SUCCESSFUL;
-}
-
-static int
-via82c505_write_config_byte(struct pci_dev *dev, int where, u8 value)
-{
-       outl(CONFIG_CMD(dev,where),0xCF8);
-       outb(value, 0xCFC + (where&3));
-       return PCIBIOS_SUCCESSFUL;
-}
-
-static int
-via82c505_write_config_word(struct pci_dev *dev, int where, u16 value)
-{
-       outl(CONFIG_CMD(dev,where),0xCF8);
-       outw(value, 0xCFC + (where&2));
+       switch (size) {
+       case 1:
+               *value=inb(0xCFC + (where&3));
+               break;
+       case 2:
+               *value=inw(0xCFC + (where&2));
+               break;
+       case 4:
+               *value=inl(0xCFC);
+               break;
+       }
        return PCIBIOS_SUCCESSFUL;
 }
 
 static int
-via82c505_write_config_dword(struct pci_dev *dev, int where, u32 value)
+via82c505_write_config(struct pci_bus *bus, unsigned int devfn, int where
+                      int size, u32 value)
 {
-       outl(CONFIG_CMD(dev,where),0xCF8);
-       outl(value, 0xCFC);
+       outl(CONFIG_CMD(bus,devfn,where),0xCF8);
+       switch (size) {
+       case 1:
+               outb(value, 0xCFC + (where&3));
+               break;
+       case 2:
+               outw(value, 0xCFC + (where&2));
+               break;
+       case 4:
+               outl(value, 0xCFC);
+               break;
+       }
        return PCIBIOS_SUCCESSFUL;
 }
 
 static struct pci_ops via82c505_ops = {
-       via82c505_read_config_byte,
-       via82c505_read_config_word,
-       via82c505_read_config_dword,
-       via82c505_write_config_byte,
-       via82c505_write_config_word,
-       via82c505_write_config_dword,
+       .read   = via82c505_read_config,
+       .write  = via82c505_write_config,
 };
 
 void __init via82c505_preinit(void *sysdata)
index 8cfa3a437a4b1d16de8defae4b106ef2b9932bc0..cbe4ba754bdb806e95c3fea2c5d2f2e2cf82a273 100644 (file)
@@ -36,12 +36,11 @@ extern void pcibios_report_status(u_int status_mask, int warn);
 extern void register_isa_ports(unsigned int, unsigned int, unsigned int);
 
 static unsigned long
-dc21285_base_address(struct pci_dev *dev)
+dc21285_base_address(struct pci_bus *bus, unsigned int devfn)
 {
        unsigned long addr = 0;
-       unsigned int devfn = dev->devfn;
 
-       if (dev->bus->number == 0) {
+       if (bus->number == 0) {
                if (PCI_SLOT(devfn) == 0)
                        /*
                         * For devfn 0, point at the 21285
@@ -54,54 +53,33 @@ dc21285_base_address(struct pci_dev *dev)
                                addr = PCICFG0_BASE | 0xc00000 | (devfn << 8);
                }
        } else
-               addr = PCICFG1_BASE | (dev->bus->number << 16) | (devfn << 8);
+               addr = PCICFG1_BASE | (bus->number << 16) | (devfn << 8);
 
        return addr;
 }
 
 static int
-dc21285_read_config_byte(struct pci_dev *dev, int where, u8 *value)
+dc21285_read_config(struct pci_bus *bus, unsigned int devfn, int where,
+                   int size, u32 *value)
 {
-       unsigned long addr = dc21285_base_address(dev);
-       u8 v;
-
-       if (addr)
-               asm("ldr%?b     %0, [%1, %2]"
-                       : "=r" (v) : "r" (addr), "r" (where));
-       else
-               v = 0xff;
-
-       *value = v;
-
-       return PCIBIOS_SUCCESSFUL;
-}
-
-static int
-dc21285_read_config_word(struct pci_dev *dev, int where, u16 *value)
-{
-       unsigned long addr = dc21285_base_address(dev);
-       u16 v;
-
-       if (addr)
-               asm("ldr%?h     %0, [%1, %2]"
-                       : "=r" (v) : "r" (addr), "r" (where));
-       else
-               v = 0xffff;
-
-       *value = v;
-
-       return PCIBIOS_SUCCESSFUL;
-}
-
-static int
-dc21285_read_config_dword(struct pci_dev *dev, int where, u32 *value)
-{
-       unsigned long addr = dc21285_base_address(dev);
+       unsigned long addr = dc21285_base_address(bus, devfn);
        u32 v;
 
        if (addr)
-               asm("ldr%?      %0, [%1, %2]"
-                       : "=r" (v) : "r" (addr), "r" (where));
+               switch (size) {
+               case 1:
+                       asm("ldr%?b     %0, [%1, %2]"
+                               : "=r" (v) : "r" (addr), "r" (where));
+                       break;
+               case 2:
+                       asm("ldr%?h     %0, [%1, %2]"
+                               : "=r" (v) : "r" (addr), "r" (where));
+                       break;
+               case 4:
+                       asm("ldr%?      %0, [%1, %2]"
+                               : "=r" (v) : "r" (addr), "r" (where));
+                       break;
+               }
        else
                v = 0xffffffff;
 
@@ -111,48 +89,33 @@ dc21285_read_config_dword(struct pci_dev *dev, int where, u32 *value)
 }
 
 static int
-dc21285_write_config_byte(struct pci_dev *dev, int where, u8 value)
-{
-       unsigned long addr = dc21285_base_address(dev);
-
-       if (addr)
-               asm("str%?b     %0, [%1, %2]"
-                       : : "r" (value), "r" (addr), "r" (where));
-
-       return PCIBIOS_SUCCESSFUL;
-}
-
-static int
-dc21285_write_config_word(struct pci_dev *dev, int where, u16 value)
-{
-       unsigned long addr = dc21285_base_address(dev);
-
-       if (addr)
-               asm("str%?h     %0, [%1, %2]"
-                       : : "r" (value), "r" (addr), "r" (where));
-
-       return PCIBIOS_SUCCESSFUL;
-}
-
-static int
-dc21285_write_config_dword(struct pci_dev *dev, int where, u32 value)
+dc21285_write_config(struct pci_bus *bus, unsigned int devfn, int where,
+                    int size, u32 value)
 {
-       unsigned long addr = dc21285_base_address(dev);
+       unsigned long addr = dc21285_base_address(bus, devfn);
 
        if (addr)
-               asm("str%?      %0, [%1, %2]"
-                       : : "r" (value), "r" (addr), "r" (where));
+               switch (size) {
+               case 1:
+                       asm("str%?b     %0, [%1, %2]"
+                               : : "r" (value), "r" (addr), "r" (where));
+                       break;
+               case 2:
+                       asm("str%?h     %0, [%1, %2]"
+                               : : "r" (value), "r" (addr), "r" (where));
+                       break;
+               case 4:
+                       asm("str%?      %0, [%1, %2]"
+                               : : "r" (value), "r" (addr), "r" (where));
+                       break;
+               }
 
        return PCIBIOS_SUCCESSFUL;
 }
 
 static struct pci_ops dc21285_ops = {
-       dc21285_read_config_byte,
-       dc21285_read_config_word,
-       dc21285_read_config_dword,
-       dc21285_write_config_byte,
-       dc21285_write_config_word,
-       dc21285_write_config_dword,
+       .read   = dc21285_read_config,
+       .write  = dc21285_write_config,
 };
 
 static struct timer_list serr_timer;
index 772e3f64f5d296bd767bc71bdf093f6d94b6157b..7c87676a73d888994191cb2162d8d1707e953146 100644 (file)
@@ -181,11 +181,12 @@ static spinlock_t v3_lock = SPIN_LOCK_UNLOCKED;
 #undef V3_LB_BASE_PREFETCH
 #define V3_LB_BASE_PREFETCH 0
 
-static unsigned long v3_open_config_window(struct pci_dev *dev, int offset)
+static unsigned long v3_open_config_window(struct pci_bus *bus,
+                                          unsigned int devfn, int offset)
 {
        unsigned int address, mapaddress, busnr;
 
-       busnr = dev->bus->number;
+       busnr = bus->number;
 
        /*
         * Trap out illegal values
@@ -194,11 +195,11 @@ static unsigned long v3_open_config_window(struct pci_dev *dev, int offset)
                BUG();
        if (busnr > 255)
                BUG();
-       if (dev->devfn > 255)
+       if (devfn > 255)
                BUG();
 
        if (busnr == 0) {
-               int slot = PCI_SLOT(dev->devfn);
+               int slot = PCI_SLOT(devfn);
 
                /*
                 * local bus segment so need a type 0 config cycle
@@ -210,7 +211,7 @@ static unsigned long v3_open_config_window(struct pci_dev *dev, int offset)
                 *  3:1 = config cycle (101)
                 *  0   = PCI A1 & A0 are 0 (0)
                 */
-               address = PCI_FUNC(dev->devfn) << 8;
+               address = PCI_FUNC(devfn) << 8;
                mapaddress = V3_LB_MAP_TYPE_CONFIG;
 
                if (slot > 12)
@@ -237,7 +238,7 @@ static unsigned long v3_open_config_window(struct pci_dev *dev, int offset)
                 *  0   = PCI A1 & A0 from host bus (1)
                 */
                mapaddress = V3_LB_MAP_TYPE_CONFIG | V3_LB_MAP_AD_LOW_EN;
-               address = (busnr << 16) | (dev->devfn << 8);
+               address = (busnr << 16) | (devfn << 8);
        }
 
        /*
@@ -276,104 +277,62 @@ static void v3_close_config_window(void)
                        V3_LB_BASE_ADR_SIZE_256MB | V3_LB_BASE_ENABLE);
 }
 
-static int v3_read_config_byte(struct pci_dev *dev, int where, u8 *val)
-{
-       unsigned long addr;
-       unsigned long flags;
-       u8 v;
-
-       spin_lock_irqsave(&v3_lock, flags);
-       addr = v3_open_config_window(dev, where);
-
-       v = __raw_readb(addr);
-
-       v3_close_config_window();
-       spin_unlock_irqrestore(&v3_lock, flags);
-
-       *val = v;
-       return PCIBIOS_SUCCESSFUL;
-}
-
-static int v3_read_config_word(struct pci_dev *dev, int where, u16 *val)
-{
-       unsigned long addr;
-       unsigned long flags;
-       u16 v;
-
-       spin_lock_irqsave(&v3_lock, flags);
-       addr = v3_open_config_window(dev, where);
-
-       v = __raw_readw(addr);
-
-       v3_close_config_window();
-       spin_unlock_irqrestore(&v3_lock, flags);
-
-       *val = v;
-       return PCIBIOS_SUCCESSFUL;
-}
-
-static int v3_read_config_dword(struct pci_dev *dev, int where, u32 *val)
+static int v3_read_config(struct pci_bus *bus, unsigned int devfn, int where,
+                         int size, u32 *val)
 {
        unsigned long addr;
        unsigned long flags;
        u32 v;
 
        spin_lock_irqsave(&v3_lock, flags);
-       addr = v3_open_config_window(dev, where);
+       addr = v3_open_config_window(bus, devfn, where);
 
-       v = __raw_readl(addr);
+       switch (size) {
+       case 1:
+               v = __raw_readb(addr);
+               break;
 
-       v3_close_config_window();
-       spin_unlock_irqrestore(&v3_lock, flags);
-
-       *val = v;
-       return PCIBIOS_SUCCESSFUL;
-}
-
-static int v3_write_config_byte(struct pci_dev *dev, int where, u8 val)
-{
-       unsigned long addr;
-       unsigned long flags;
-
-       spin_lock_irqsave(&v3_lock, flags);
-       addr = v3_open_config_window(dev, where);
-
-       __raw_writeb(val, addr);
-       __raw_readb(addr);
-       
-       v3_close_config_window();
-       spin_unlock_irqrestore(&v3_lock, flags);
-
-       return PCIBIOS_SUCCESSFUL;
-}
-
-static int v3_write_config_word(struct pci_dev *dev, int where, u16 val)
-{
-       unsigned long addr;
-       unsigned long flags;
-
-       spin_lock_irqsave(&v3_lock, flags);
-       addr = v3_open_config_window(dev, where);
+       case 2:
+               v = __raw_readw(addr);
+               break;
 
-       __raw_writew(val, addr);
-       __raw_readw(addr);
+       case 4:
+               v = __raw_readl(addr);
+               break;
+       }
 
        v3_close_config_window();
        spin_unlock_irqrestore(&v3_lock, flags);
 
+       *val = v;
        return PCIBIOS_SUCCESSFUL;
 }
 
-static int v3_write_config_dword(struct pci_dev *dev, int where, u32 val)
+static int v3_write_config(struct pci_bus *bus, unsigned int devfn, int where,
+                          int size, u32 val)
 {
        unsigned long addr;
        unsigned long flags;
 
        spin_lock_irqsave(&v3_lock, flags);
-       addr = v3_open_config_window(dev, where);
-
-       __raw_writel(val, addr);
-       __raw_readl(addr);
+       addr = v3_open_config_window(bus, devfn, where);
+
+       switch (size) {
+       case 1:
+               __raw_writeb((u8)val, addr);
+               __raw_readb(addr);
+               break;
+
+       case 2:
+               __raw_writew((u16)val, addr);
+               __raw_readw(addr);
+               break;
+
+       case 4:
+               __raw_writel(val, addr);
+               __raw_readl(addr);
+               break;
+       }
 
        v3_close_config_window();
        spin_unlock_irqrestore(&v3_lock, flags);
@@ -382,12 +341,8 @@ static int v3_write_config_dword(struct pci_dev *dev, int where, u32 val)
 }
 
 static struct pci_ops pci_v3_ops = {
-       .read_byte      = v3_read_config_byte,
-       .read_word      = v3_read_config_word,
-       .read_dword     = v3_read_config_dword,
-       .write_byte     = v3_write_config_byte,
-       .write_word     = v3_write_config_word,
-       .write_dword    = v3_write_config_dword,
+       .read   = v3_read_config,
+       .write  = v3_write_config,
 };
 
 static struct resource non_mem = {
index a92ff17fe8345e73db95e45b3c57b1407a753748..c7fddcdf9107e7278a3bf901cff795fee99f0cf1 100644 (file)
 #define  DBG(x...) do { } while (0)
 #endif
 
-extern int (*external_fault)(unsigned long, struct pt_regs *);
-
-static u32 iop310_cfg_address(struct pci_dev *dev, int where)
+/*
+ * Calculate the address, etc from the bus, devfn and register
+ * offset.  Note that we have two root buses, so we need some
+ * method to determine whether we need config type 0 or 1 cycles.
+ * We use a root bus number in our bus->sysdata structure for this.
+ */
+static u32 iop310_cfg_address(struct pci_bus *bus, int devfn, int where)
 {
-       struct pci_sys_data *sys = dev->sysdata;
+       struct pci_sys_data *sys = bus->sysdata;
        u32 addr;
 
-       where &= ~3;
-
-       if (sys->busnr == dev->bus->number)
-               addr = 1 << (PCI_SLOT(dev->devfn) + 16);
+       if (sys->busnr == bus->number)
+               addr = 1 << (PCI_SLOT(devfn) + 16);
        else
-               addr = dev->bus->number << 16 |
-                      PCI_SLOT(dev->devfn) << 11 | 1;
+               addr = bus->number << 16 | PCI_SLOT(devfn) << 11 | 1;
 
-       addr |= PCI_FUNC(dev->devfn) << 8 | where;
+       addr |= PCI_FUNC(devfn) << 8 | (where & ~3);
 
        return addr;
 }
@@ -106,9 +107,13 @@ static int iop310_pri_pci_status(void)
        return ret;
 }
 
-static inline u32 iop310_pri_read(struct pci_dev *dev, int where)
+/*
+ * Simply write the address register and read the configuration
+ * data.  Note that the 4 nop's ensure that we are able to handle
+ * a delayed abort (in theory.)
+ */
+static inline u32 iop310_pri_read(unsigned long addr)
 {
-       unsigned long addr = iop310_cfg_address(dev, where);
        u32 val;
 
        __asm__ __volatile__(
@@ -125,111 +130,59 @@ static inline u32 iop310_pri_read(struct pci_dev *dev, int where)
 }
 
 static int
-iop310_pri_rd_cfg_byte(struct pci_dev *dev, int where, u8 *p)
-{
-       u8 val;
-
-       val = iop310_pri_read(dev, where) >> ((where & 3) * 8);
-
-       if (iop310_pri_pci_status())
-               val = 0xff;
-
-       *p = val;
-
-       return PCIBIOS_SUCCESSFUL;
-}
-
-static int
-iop310_pri_rd_cfg_word(struct pci_dev *dev, int where, u16 *p)
-{
-       u16 val;
-
-       val = iop310_pri_read(dev, where) >> ((where & 3) * 8);
-
-       if (iop310_pri_pci_status())
-               val = 0xffff;
-
-       *p = val;
-
-       return PCIBIOS_SUCCESSFUL;
-}
-
-static int
-iop310_pri_rd_cfg_dword(struct pci_dev *dev, int where, u32 *p)
+iop310_pri_read_config(struct pci_bus *bus, unsigned int devfn, int where,
+                      int size, u32 *value)
 {
-       u32 val;
-
-       val = iop310_pri_read(dev, where);
+       unsigned long addr = iop310_cfg_address(bus, devfn, where);
+       u32 val = iop310_pri_read(addr) >> ((where & 3) * 8);
 
        if (iop310_pri_pci_status())
                val = 0xffffffff;
 
-       *p = val;
+       *value = val;
 
        return PCIBIOS_SUCCESSFUL;
 }
 
 static int
-iop310_pri_wr_cfg_byte(struct pci_dev *dev, int where, u8 v)
+iop310_pri_write_config(struct pci_bus *bus, unsigned int devfn, int where
+                       int size, u32 value)
 {
+       unsigned long addr = iop310_cfg_address(bus, devfn, where);
        u32 val;
 
-       val = iop310_pri_read(dev, where);
+       if (size != 4) {
+               val = iop310_pri_read(addr);
+               if (!iop310_pri_pci_status() == 0)
+                       return PCIBIOS_SUCCESSFUL;
 
-       if (iop310_pri_pci_status() == 0) {
                where = (where & 3) * 8;
-               val &= ~(0xff << where);
-               val |= v << where;
-               *IOP310_POCCDR = val;
-       }
-
-       return PCIBIOS_SUCCESSFUL;
-}
 
-static int
-iop310_pri_wr_cfg_word(struct pci_dev *dev, int where, u16 v)
-{
-       u32 val;
-
-       val = iop310_pri_read(dev, where);
-
-       if (iop310_pri_pci_status() == 0) {
-               where = (where & 2) * 8;
-               val &= ~(0xffff << where);
-               val |= v << where;
-               *IOP310_POCCDR = val;
+               if (size == 1)
+                       val &= ~(0xff << where);
+               else
+                       val &= ~(0xffff << where);
+
+               *IOP310_POCCDR = val | v << where;
+       } else {
+               asm volatile(
+                       "str    %1, [%2]\n\t"
+                       "str    %0, [%3]\n\t"
+                       "nop\n\t"
+                       "nop\n\t"
+                       "nop\n\t"
+                       "nop\n\t"
+                       :
+                       : "r" (val), "r" (addr),
+                         "r" (IOP310_POCCAR), "r" (IOP310_POCCDR));
        }
 
        return PCIBIOS_SUCCESSFUL;
 }
 
-static int
-iop310_pri_wr_cfg_dword(struct pci_dev *dev, int where, u32 val)
-{
-       unsigned long addr;
-
-       addr = iop310_cfg_address(dev, where);
-
-       __asm__ __volatile__(
-               "str    %1, [%2]\n\t"
-               "str    %0, [%3]\n\t"
-               "nop\n\t"
-               "nop\n\t"
-               "nop\n\t"
-               "nop\n\t"
-               :
-               : "r" (val), "r" (addr), "r" (IOP310_POCCAR), "r" (IOP310_POCCDR));
-
-       return PCIBIOS_SUCCESSFUL;
-}
-
 static struct pci_ops iop310_primary_ops = {
-       iop310_pri_rd_cfg_byte,
-       iop310_pri_rd_cfg_word,
-       iop310_pri_rd_cfg_dword,
-       iop310_pri_wr_cfg_byte,
-       iop310_pri_wr_cfg_word,
-       iop310_pri_wr_cfg_dword,
+       .read   = iop310_pri_read_config,
+       .write  = iop310_pri_write_config,
 };
 
 /*
@@ -255,9 +208,13 @@ static int iop310_sec_pci_status(void)
        return ret;
 }
 
-static inline u32 iop310_sec_read(struct pci_dev *dev, int where)
+/*
+ * Simply write the address register and read the configuration
+ * data.  Note that the 4 nop's ensure that we are able to handle
+ * a delayed abort (in theory.)
+ */
+static inline u32 iop310_sec_read(unsigned long addr)
 {
-       unsigned long addr = iop310_cfg_address(dev, where);
        u32 val;
 
        __asm__ __volatile__(
@@ -274,111 +231,60 @@ static inline u32 iop310_sec_read(struct pci_dev *dev, int where)
 }
 
 static int
-iop310_sec_rd_cfg_byte(struct pci_dev *dev, int where, u8 *p)
-{
-       u8 val;
-
-       val = iop310_sec_read(dev, where) >> ((where & 3) * 8);
-
-       if (iop310_sec_pci_status())
-               val = 0xff;
-
-       *p = val;
-
-       return PCIBIOS_SUCCESSFUL;
-}
-
-static int
-iop310_sec_rd_cfg_word(struct pci_dev *dev, int where, u16 *p)
+iop310_sec_read_config(struct pci_bus *bus, unsigned int devfn, int where,
+                      int size, u32 *value)
 {
-       u16 val;
-
-       val = iop310_sec_read(dev, where) >> ((where & 3) * 8);
-
-       if (iop310_sec_pci_status())
-               val = 0xffff;
-
-       *p = val;
-
-       return PCIBIOS_SUCCESSFUL;
-}
-
-static int
-iop310_sec_rd_cfg_dword(struct pci_dev *dev, int where, u32 *p)
-{
-       u32 val;
-
-       val = iop310_sec_read(dev, where);
+       unsigned long addr = iop310_cfg_address(bus, devfn, where);
+       u32 val = iop310_sec_read(addr) >> ((where & 3) * 8);
 
        if (iop310_sec_pci_status())
                val = 0xffffffff;
 
-       *p = val;
+       *value = val;
 
        return PCIBIOS_SUCCESSFUL;
 }
 
 static int
-iop310_sec_wr_cfg_byte(struct pci_dev *dev, int where, u8 v)
+iop310_sec_write_config(struct pci_bus *bus, unsigned int devfn, int where
+                       int size, u32 value)
 {
+       unsigned long addr = iop310_cfg_address(bus, devfn, where);
        u32 val;
 
-       val = iop310_sec_read(dev, where);
+       if (size != 4) {
+               val = iop310_sec_read(addr);
 
-       if (iop310_sec_pci_status() == 0) {
-               where = (where & 3) * 8;
-               val &= ~(0xff << where);
-               val |= v << where;
-               *IOP310_SOCCDR = val;
-       }
-
-       return PCIBIOS_SUCCESSFUL;
-}
-
-static int
-iop310_sec_wr_cfg_word(struct pci_dev *dev, int where, u16 v)
-{
-       u32 val;
+               if (!iop310_sec_pci_status() == 0)
+                       return PCIBIOS_SUCCESSFUL;
 
-       val = iop310_sec_read(dev, where);
+               where = (where & 3) * 8;
 
-       if (iop310_sec_pci_status() == 0) {
-               where = (where & 2) * 8;
-               val &= ~(0xffff << where);
-               val |= v << where;
-               *IOP310_SOCCDR = val;
+               if (size == 1)
+                       val &= ~(0xff << where);
+               else
+                       val &= ~(0xffff << where);
+
+               *IOP310_SOCCDR = val | v << where;
+       } else {
+               asm volatile(
+                       "str    %1, [%2]\n\t"
+                       "str    %0, [%3]\n\t"
+                       "nop\n\t"
+                       "nop\n\t"
+                       "nop\n\t"
+                       "nop\n\t"
+                       :
+                       : "r" (val), "r" (addr),
+                         "r" (IOP310_SOCCAR), "r" (IOP310_SOCCDR));
        }
 
        return PCIBIOS_SUCCESSFUL;
 }
 
-static int
-iop310_sec_wr_cfg_dword(struct pci_dev *dev, int where, u32 val)
-{
-       unsigned long addr;
-
-       addr = iop310_cfg_address(dev, where);
-
-       __asm__ __volatile__(
-               "str    %1, [%2]\n\t"
-               "str    %0, [%3]\n\t"
-               "nop\n\t"
-               "nop\n\t"
-               "nop\n\t"
-               "nop\n\t"
-               :
-               : "r" (val), "r" (addr), "r" (IOP310_SOCCAR), "r" (IOP310_SOCCDR));
-
-       return PCIBIOS_SUCCESSFUL;
-}
-
 static struct pci_ops iop310_secondary_ops = {
-       iop310_sec_rd_cfg_byte,
-       iop310_sec_rd_cfg_word,
-       iop310_sec_rd_cfg_dword,
-       iop310_sec_wr_cfg_byte,
-       iop310_sec_wr_cfg_word,
-       iop310_sec_wr_cfg_dword,
+       .read   = iop310_sec_read_config,
+       .write  = iop310_sec_write_config,
 };
 
 /*
@@ -524,5 +430,5 @@ void iop310_init(void)
         */
        *IOP310_PCR &= 0xfff8;
 
-       hook_fault_code(6, iop310_pci_abort, SIGBUS, "imprecise external abort");
+       hook_fault_code(16+6, iop310_pci_abort, SIGBUS, "imprecise external abort");
 }