.flags  = IORESOURCE_MEM
 };
 
-static int mkaddr(int bus, int dev_fn, int where, int *flagsp)
+static int mkaddr(int bus, int dev_fn, int where,
+                 struct tx4938_pcic_reg *pcicptr)
 {
        if (bus > 0) {
                /* Type 1 configuration */
-               tx4938_pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) |
+               pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) |
                    ((dev_fn & 0xff) << 0x08) | (where & 0xfc) | 1;
        } else {
                if (dev_fn >= PCI_DEVFN(TX4938_PCIC_MAX_DEVNU, 0))
                        return -1;
 
                /* Type 0 configuration */
-               tx4938_pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) |
+               pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) |
                    ((dev_fn & 0xff) << 0x08) | (where & 0xfc);
        }
        /* clear M_ABORT and Disable M_ABORT Int. */
-       tx4938_pcicptr->pcistatus =
-           (tx4938_pcicptr->pcistatus & 0x0000ffff) |
+       pcicptr->pcistatus =
+           (pcicptr->pcistatus & 0x0000ffff) |
            (PCI_STATUS_REC_MASTER_ABORT << 16);
-       tx4938_pcicptr->pcimask &= ~PCI_STATUS_REC_MASTER_ABORT;
+       pcicptr->pcimask &= ~PCI_STATUS_REC_MASTER_ABORT;
 
        return 0;
 }
 
-static int check_abort(int flags)
+static int check_abort(struct tx4938_pcic_reg *pcicptr)
 {
        int code = PCIBIOS_SUCCESSFUL;
        /* wait write cycle completion before checking error status */
-       while (tx4938_pcicptr->pcicstatus & TX4938_PCIC_PCICSTATUS_IWB)
+       while (pcicptr->pcicstatus & TX4938_PCIC_PCICSTATUS_IWB)
                                ;
-       if (tx4938_pcicptr->pcistatus & (PCI_STATUS_REC_MASTER_ABORT << 16)) {
-               tx4938_pcicptr->pcistatus =
-                   (tx4938_pcicptr->
+       if (pcicptr->pcistatus & (PCI_STATUS_REC_MASTER_ABORT << 16)) {
+               pcicptr->pcistatus =
+                   (pcicptr->
                     pcistatus & 0x0000ffff) | (PCI_STATUS_REC_MASTER_ABORT
                                                << 16);
-               tx4938_pcicptr->pcimask |= PCI_STATUS_REC_MASTER_ABORT;
+               pcicptr->pcimask |= PCI_STATUS_REC_MASTER_ABORT;
                code = PCIBIOS_DEVICE_NOT_FOUND;
        }
        return code;
 }
 
+extern struct pci_controller tx4938_pci_controller[];
+extern struct tx4938_pcic_reg *get_tx4938_pcicptr(int ch);
+
+static struct tx4938_pcic_reg *pci_bus_to_pcicptr(struct pci_bus *bus)
+{
+       struct pci_controller *channel = bus->sysdata;
+       return get_tx4938_pcicptr(channel - &tx4938_pci_controller[0]);
+}
+
 static int tx4938_pcibios_read_config(struct pci_bus *bus, unsigned int devfn,
                                        int where, int size, u32 * val)
 {
-       int flags, retval, dev, busno, func;
+       int retval, dev, busno, func;
+       struct tx4938_pcic_reg *pcicptr = pci_bus_to_pcicptr(bus);
+       void __iomem *cfgdata =
+               (void __iomem *)(unsigned long)&pcicptr->g2pcfgdata;
 
        dev = PCI_SLOT(devfn);
        func = PCI_FUNC(devfn);
                busno = 0;
        }
 
-       if (mkaddr(busno, devfn, where, &flags))
+       if (mkaddr(busno, devfn, where, pcicptr))
                return -1;
 
        switch (size) {
        case 1:
-               *val = *(volatile u8 *) ((unsigned long) & tx4938_pcicptr->g2pcfgdata |
 #ifdef __BIG_ENDIAN
-                             ((where & 3) ^ 3));
+               cfgdata += (where & 3) ^ 3;
 #else
-                             (where & 3));
+               cfgdata += where & 3;
 #endif
+               *val = __raw_readb(cfgdata);
                break;
        case 2:
-               *val = *(volatile u16 *) ((unsigned long) & tx4938_pcicptr->g2pcfgdata |
 #ifdef __BIG_ENDIAN
-                               ((where & 3) ^ 2));
+               cfgdata += (where & 2) ^ 2;
 #else
-                               (where & 3));
+               cfgdata += where & 2;
 #endif
+               *val = __raw_readw(cfgdata);
                break;
        case 4:
-               *val = tx4938_pcicptr->g2pcfgdata;
+               *val = __raw_readl(cfgdata);
                break;
        }
 
-       retval = check_abort(flags);
+       retval = check_abort(pcicptr);
        if (retval == PCIBIOS_DEVICE_NOT_FOUND)
                *val = 0xffffffff;
 
 static int tx4938_pcibios_write_config(struct pci_bus *bus, unsigned int devfn, int where,
                                                int size, u32 val)
 {
-       int flags, dev, busno, func;
+       int dev, busno, func;
+       struct tx4938_pcic_reg *pcicptr = pci_bus_to_pcicptr(bus);
+       void __iomem *cfgdata =
+               (void __iomem *)(unsigned long)&pcicptr->g2pcfgdata;
 
        busno = bus->number;
        dev = PCI_SLOT(devfn);
                busno = 0;
        }
 
-       if (mkaddr(busno, devfn, where, &flags))
+       if (mkaddr(busno, devfn, where, pcicptr))
                return -1;
 
        switch (size) {
        case 1:
-               *(volatile u8 *) ((unsigned long) & tx4938_pcicptr->g2pcfgdata |
 #ifdef __BIG_ENDIAN
-                         ((where & 3) ^ 3)) = val;
+               cfgdata += (where & 3) ^ 3;
 #else
-                         (where & 3)) = val;
+               cfgdata += where & 3;
 #endif
+               __raw_writeb(val, cfgdata);
                break;
        case 2:
-               *(volatile u16 *) ((unsigned long) & tx4938_pcicptr->g2pcfgdata |
 #ifdef __BIG_ENDIAN
-                       ((where & 0x3) ^ 0x2)) = val;
+               cfgdata += (where & 2) ^ 2;
 #else
-                       (where & 3)) = val;
+               cfgdata += where & 2;
 #endif
+               __raw_writew(val, cfgdata);
                break;
        case 4:
-               tx4938_pcicptr->g2pcfgdata = val;
+               __raw_writel(val, cfgdata);
                break;
        }
 
-       return check_abort(flags);
+       return check_abort(pcicptr);
 }
 
 struct pci_ops tx4938_pci_ops = {
 
        static struct pci_dev dev;
        static struct pci_bus bus;
 
-       dev.sysdata = (void *)hose;
+       dev.sysdata = bus.sysdata = hose;
        dev.devfn = devfn;
        bus.number = busnr;
        bus.ops = hose->pci_ops;
        printk("PCI: Checking 66MHz capabilities...\n");
 
        for (pci_devfn=devfn_start; pci_devfn<devfn_stop; pci_devfn++) {
-               early_read_config_word(hose, top_bus, current_bus, pci_devfn,
-                                      PCI_VENDOR_ID, &vid);
+               if (early_read_config_word(hose, top_bus, current_bus,
+                                          pci_devfn, PCI_VENDOR_ID,
+                                          &vid) != PCIBIOS_SUCCESSFUL)
+                       continue;
 
                if (vid == 0xffff) continue;
 
        int extarb = !(tx4938_ccfgptr->ccfg & TX4938_CCFG_PCIXARB);
 
        PCIBIOS_MIN_IO = 0x00001000UL;
-       PCIBIOS_MIN_MEM = 0x01000000UL;
 
        mem_base[0] = txboard_request_phys_region_shrink(&mem_size[0]);
        io_base[0] = txboard_request_phys_region_shrink(&io_size[0]);
 #define        SRTC_CS 2       /* IOC */
 
 #ifdef CONFIG_PCI
-static unsigned char rbtx4938_ethaddr[17];
 static int __init rbtx4938_ethaddr_init(void)
 {
+       unsigned char dat[17];
        unsigned char sum;
        int i;
 
        /* 0-3: "MAC\0", 4-9:eth0, 10-15:eth1, 16:sum */
-       if (spi_eeprom_read(SEEPROM1_CS, 0,
-                           rbtx4938_ethaddr, sizeof(rbtx4938_ethaddr)))
+       if (spi_eeprom_read(SEEPROM1_CS, 0, dat, sizeof(dat))) {
                printk(KERN_ERR "seeprom: read error.\n");
-       else {
-               unsigned char *dat = rbtx4938_ethaddr;
+               return -ENODEV;
+       } else {
                if (strcmp(dat, "MAC") != 0)
                        printk(KERN_WARNING "seeprom: bad signature.\n");
                for (i = 0, sum = 0; i < sizeof(dat); i++)
                if (sum)
                        printk(KERN_WARNING "seeprom: bad checksum.\n");
        }
-       return 0;
-}
-device_initcall(rbtx4938_ethaddr_init);
-
-int rbtx4938_get_tx4938_ethaddr(struct pci_dev *dev, unsigned char *addr)
-{
-       struct pci_controller *channel = (struct pci_controller *)dev->bus->sysdata;
-       int ch = 0;
-
-       if (channel != &tx4938_pci_controller[1])
-               return -ENODEV;
-       /* TX4938 PCIC1 */
-       switch (PCI_SLOT(dev->devfn)) {
-       case TX4938_PCIC_IDSEL_AD_TO_SLOT(31):
-               ch = 0;
-               break;
-       case TX4938_PCIC_IDSEL_AD_TO_SLOT(30):
-               ch = 1;
-               break;
-       default:
-               return -ENODEV;
+       for (i = 0; i < 2; i++) {
+               unsigned int slot = TX4938_PCIC_IDSEL_AD_TO_SLOT(31 - i);
+               unsigned int id = (1 << 8) | PCI_DEVFN(slot, 0); /* bus 1 */
+               struct platform_device *pdev;
+               if (!(tx4938_ccfgptr->pcfg &
+                     (i ? TX4938_PCFG_ETH1_SEL : TX4938_PCFG_ETH0_SEL)))
+                       continue;
+               pdev = platform_device_alloc("tc35815-mac", id);
+               if (!pdev ||
+                   platform_device_add_data(pdev, &dat[4 + 6 * i], 6) ||
+                   platform_device_add(pdev))
+                       platform_device_put(pdev);
        }
-       memcpy(addr, &rbtx4938_ethaddr[4 + 6 * ch], 6);
        return 0;
 }
+device_initcall(rbtx4938_ethaddr_init);
 #endif /* CONFIG_PCI */
 
 static void __init rbtx4938_spi_setup(void)