S3C-fb: PM fix
[safe/jmp/linux-2.6] / drivers / parisc / lba_pci.c
index ad4a1a1..59fbbf1 100644 (file)
@@ -38,7 +38,6 @@
 #include <linux/pci.h>
 #include <linux/ioport.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 
 #include <asm/byteorder.h>
 #include <asm/pdc.h>
@@ -168,7 +167,8 @@ lba_dump_res(struct resource *r, int d)
 
        printk(KERN_DEBUG "(%p)", r->parent);
        for (i = d; i ; --i) printk(" ");
-       printk(KERN_DEBUG "%p [%lx,%lx]/%lx\n", r, r->start, r->end, r->flags);
+       printk(KERN_DEBUG "%p [%lx,%lx]/%lx\n", r,
+               (long)r->start, (long)r->end, r->flags);
        lba_dump_res(r->child, d+2);
        lba_dump_res(r->sibling, d);
 }
@@ -377,12 +377,12 @@ static int elroy_cfg_read(struct pci_bus *bus, unsigned int devfn, int pos, int
                /* original - Generate config cycle on broken elroy
                  with risk we will miss PCI bus errors. */
                *data = lba_rd_cfg(d, tok, pos, size);
-               DBG_CFG("%s(%x+%2x) -> 0x%x (a)\n", __FUNCTION__, tok, pos, *data);
+               DBG_CFG("%s(%x+%2x) -> 0x%x (a)\n", __func__, tok, pos, *data);
                return 0;
        }
 
        if (LBA_SKIP_PROBE(d) && !lba_device_present(bus->secondary, devfn, d)) {
-               DBG_CFG("%s(%x+%2x) -> -1 (b)\n", __FUNCTION__, tok, pos);
+               DBG_CFG("%s(%x+%2x) -> -1 (b)\n", __func__, tok, pos);
                /* either don't want to look or know device isn't present. */
                *data = ~0U;
                return(0);
@@ -398,7 +398,7 @@ static int elroy_cfg_read(struct pci_bus *bus, unsigned int devfn, int pos, int
        case 2: *data = READ_REG16(data_reg + (pos & 2)); break;
        case 4: *data = READ_REG32(data_reg); break;
        }
-       DBG_CFG("%s(%x+%2x) -> 0x%x (c)\n", __FUNCTION__, tok, pos, *data);
+       DBG_CFG("%s(%x+%2x) -> 0x%x (c)\n", __func__, tok, pos, *data);
        return 0;
 }
 
@@ -441,16 +441,16 @@ static int elroy_cfg_write(struct pci_bus *bus, unsigned int devfn, int pos, int
        if (!LBA_SKIP_PROBE(d)) {
                /* Original Workaround */
                lba_wr_cfg(d, tok, pos, (u32) data, size);
-               DBG_CFG("%s(%x+%2x) = 0x%x (a)\n", __FUNCTION__, tok, pos,data);
+               DBG_CFG("%s(%x+%2x) = 0x%x (a)\n", __func__, tok, pos,data);
                return 0;
        }
 
        if (LBA_SKIP_PROBE(d) && (!lba_device_present(bus->secondary, devfn, d))) {
-               DBG_CFG("%s(%x+%2x) = 0x%x (b)\n", __FUNCTION__, tok, pos,data);
+               DBG_CFG("%s(%x+%2x) = 0x%x (b)\n", __func__, tok, pos,data);
                return 1; /* New Workaround */
        }
 
-       DBG_CFG("%s(%x+%2x) = 0x%x (c)\n", __FUNCTION__, tok, pos, data);
+       DBG_CFG("%s(%x+%2x) = 0x%x (c)\n", __func__, tok, pos, data);
 
        /* Basic Algorithm */
        LBA_CFG_ADDR_SETUP(d, tok | pos);
@@ -521,7 +521,7 @@ static int mercury_cfg_write(struct pci_bus *bus, unsigned int devfn, int pos, i
        if ((pos > 255) || (devfn > 255))
                return -EINVAL;
 
-       DBG_CFG("%s(%x+%2x) <- 0x%x (c)\n", __FUNCTION__, tok, pos, data);
+       DBG_CFG("%s(%x+%2x) <- 0x%x (c)\n", __func__, tok, pos, data);
 
        LBA_CFG_TR4_ADDR_SETUP(d, tok | pos);
        switch(size) {
@@ -557,44 +557,6 @@ lba_bios_init(void)
 #ifdef CONFIG_64BIT
 
 /*
-** Determine if a device is already configured.
-** If so, reserve it resources.
-**
-** Read PCI cfg command register and see if I/O or MMIO is enabled.
-** PAT has to enable the devices it's using.
-**
-** Note: resources are fixed up before we try to claim them.
-*/
-static void
-lba_claim_dev_resources(struct pci_dev *dev)
-{
-       u16 cmd;
-       int i, srch_flags;
-
-       (void) pci_read_config_word(dev, PCI_COMMAND, &cmd);
-
-       srch_flags  = (cmd & PCI_COMMAND_IO) ? IORESOURCE_IO : 0;
-       if (cmd & PCI_COMMAND_MEMORY)
-               srch_flags |= IORESOURCE_MEM;
-
-       if (!srch_flags)
-               return;
-
-       for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
-               if (dev->resource[i].flags & srch_flags) {
-                       pci_claim_resource(dev, i);
-                       DBG("   claimed %s %d [%lx,%lx]/%lx\n",
-                               pci_name(dev), i,
-                               dev->resource[i].start,
-                               dev->resource[i].end,
-                               dev->resource[i].flags
-                               );
-               }
-       }
-}
-
-
-/*
  * truncate_pat_collision:  Deal with overlaps or outright collisions
  *                     between PAT PDC reported ranges.
  *
@@ -647,13 +609,12 @@ truncate_pat_collision(struct resource *root, struct resource *new)
        printk(KERN_WARNING "LBA: Truncating lmmio_space [%lx/%lx] "
                                        "to [%lx,%lx]\n",
                        start, end,
-                       new->start, new->end );
+                       (long)new->start, (long)new->end );
 
        return 0;       /* truncation successful */
 }
 
 #else
-#define lba_claim_dev_resources(dev) do { } while (0)
 #define truncate_pat_collision(r,n)  (0)
 #endif
 
@@ -683,9 +644,13 @@ lba_fixup_bus(struct pci_bus *bus)
        ** Properly Setup MMIO resources for this bus.
        ** pci_alloc_primary_bus() mangles this.
        */
-       if (bus->self) {
+       if (bus->parent) {
+               int i;
                /* PCI-PCI Bridge */
                pci_read_bridge_bases(bus);
+               for (i = PCI_BRIDGE_RESOURCES; i < PCI_NUM_RESOURCES; i++) {
+                       pci_claim_resource(bus->self, i);
+               }
        } else {
                /* Host-PCI Bridge */
                int err, i;
@@ -715,8 +680,8 @@ lba_fixup_bus(struct pci_bus *bus)
 
                                printk("FAILED: lba_fixup_bus() request for "
                                                "elmmio_space [%lx/%lx]\n",
-                                               ldev->hba.elmmio_space.start,
-                                               ldev->hba.elmmio_space.end);
+                                               (long)ldev->hba.elmmio_space.start,
+                                               (long)ldev->hba.elmmio_space.end);
 
                                /* lba_dump_res(&iomem_resource, 2); */
                                /* BUG(); */
@@ -738,15 +703,15 @@ lba_fixup_bus(struct pci_bus *bus)
                                        &(ldev->hba.lmmio_space))) {
 
                        printk(KERN_WARNING "LBA: lmmio_space [%lx/%lx] duplicate!\n",
-                                       ldev->hba.lmmio_space.start,
-                                       ldev->hba.lmmio_space.end);
+                                       (long)ldev->hba.lmmio_space.start,
+                                       (long)ldev->hba.lmmio_space.end);
                } else {
                        err = request_resource(&iomem_resource, &(ldev->hba.lmmio_space));
                        if (err < 0) {
                                printk(KERN_ERR "FAILED: lba_fixup_bus() request for "
                                        "lmmio_space [%lx/%lx]\n",
-                                       ldev->hba.lmmio_space.start,
-                                       ldev->hba.lmmio_space.end);
+                                       (long)ldev->hba.lmmio_space.start,
+                                       (long)ldev->hba.lmmio_space.end);
                        } else
                                bus->resource[i++] = &(ldev->hba.lmmio_space);
                }
@@ -758,8 +723,8 @@ lba_fixup_bus(struct pci_bus *bus)
                        if (err < 0) {
                                printk("FAILED: lba_fixup_bus() request for "
                                        "gmmio_space [%lx/%lx]\n",
-                                       ldev->hba.gmmio_space.start,
-                                       ldev->hba.gmmio_space.end);
+                                       (long)ldev->hba.gmmio_space.start,
+                                       (long)ldev->hba.gmmio_space.end);
                                lba_dump_res(&iomem_resource, 2);
                                BUG();
                        }
@@ -803,6 +768,13 @@ lba_fixup_bus(struct pci_bus *bus)
                                DBG("lba_fixup_bus() WTF? 0x%lx [%lx/%lx] XXX",
                                        res->flags, res->start, res->end);
                        }
+
+                       /*
+                       ** FIXME: this will result in whinging for devices
+                       ** that share expansion ROMs (think quad tulip), but
+                       ** isn't harmful.
+                       */
+                       pci_claim_resource(dev, i);
                }
 
 #ifdef FBB_SUPPORT
@@ -814,11 +786,6 @@ lba_fixup_bus(struct pci_bus *bus)
                bus->bridge_ctl &= ~(status & PCI_STATUS_FAST_BACK);
 #endif
 
-               if (is_pdc_pat()) {
-                       /* Claim resources for PDC's devices */
-                       lba_claim_dev_resources(dev);
-               }
-
                 /*
                ** P2PB's have no IRQs. ignore them.
                */
@@ -835,7 +802,7 @@ lba_fixup_bus(struct pci_bus *bus)
 ** Can't fixup here anyway....garr...
 */
        if (fbb_enable) {
-               if (bus->self) {
+               if (bus->parent) {
                        u8 control;
                        /* enable on PPB */
                        (void) pci_read_config_byte(bus->self, PCI_BRIDGE_CONTROL, &control);
@@ -857,7 +824,7 @@ lba_fixup_bus(struct pci_bus *bus)
 }
 
 
-struct pci_bios_ops lba_bios_ops = {
+static struct pci_bios_ops lba_bios_ops = {
        .init =         lba_bios_init,
        .fixup_bus =    lba_fixup_bus,
 };
@@ -923,7 +890,7 @@ LBA_PORT_IN(32, 0)
 #define LBA_PORT_OUT(size, mask) \
 static void lba_astro_out##size (struct pci_hba_data *d, u16 addr, u##size val) \
 { \
-       DBG_PORT("%s(0x%p, 0x%x, 0x%x)\n", __FUNCTION__, d, addr, val); \
+       DBG_PORT("%s(0x%p, 0x%x, 0x%x)\n", __func__, d, addr, val); \
        WRITE_REG##size(val, astro_iop_base + addr); \
        if (LBA_DEV(d)->hw_rev < 3) \
                lba_t32 = READ_U32(d->base_addr + LBA_FUNC_ID); \
@@ -965,7 +932,7 @@ static struct pci_port_ops lba_astro_port_ops = {
 static u##size lba_pat_in##size (struct pci_hba_data *l, u16 addr) \
 { \
        u##size t; \
-       DBG_PORT("%s(0x%p, 0x%x) ->", __FUNCTION__, l, addr); \
+       DBG_PORT("%s(0x%p, 0x%x) ->", __func__, l, addr); \
        t = READ_REG##size(PIOP_TO_GMMIO(LBA_DEV(l), addr)); \
        DBG_PORT(" 0x%x\n", t); \
        return (t); \
@@ -981,7 +948,7 @@ LBA_PORT_IN(32, 0)
 static void lba_pat_out##size (struct pci_hba_data *l, u16 addr, u##size val) \
 { \
        void __iomem *where = PIOP_TO_GMMIO(LBA_DEV(l), addr); \
-       DBG_PORT("%s(0x%p, 0x%x, 0x%x)\n", __FUNCTION__, l, addr, val); \
+       DBG_PORT("%s(0x%p, 0x%x, 0x%x)\n", __func__, l, addr, val); \
        WRITE_REG##size(val, where); \
        /* flush the I/O down to the elroy at least */ \
        lba_t32 = READ_U32(l->base_addr + LBA_FUNC_ID); \
@@ -1063,16 +1030,16 @@ lba_pat_resources(struct parisc_device *pa_dev, struct lba_device *lba_dev)
                        /* used to fix up pre-initialized MEM BARs */
                        if (!lba_dev->hba.lmmio_space.start) {
                                sprintf(lba_dev->hba.lmmio_name,
-                                               "PCI%02lx LMMIO",
-                                               lba_dev->hba.bus_num.start);
+                                               "PCI%02x LMMIO",
+                                               (int)lba_dev->hba.bus_num.start);
                                lba_dev->hba.lmmio_space_offset = p->start -
                                        io->start;
                                r = &lba_dev->hba.lmmio_space;
                                r->name = lba_dev->hba.lmmio_name;
                        } else if (!lba_dev->hba.elmmio_space.start) {
                                sprintf(lba_dev->hba.elmmio_name,
-                                               "PCI%02lx ELMMIO",
-                                               lba_dev->hba.bus_num.start);
+                                               "PCI%02x ELMMIO",
+                                               (int)lba_dev->hba.bus_num.start);
                                r = &lba_dev->hba.elmmio_space;
                                r->name = lba_dev->hba.elmmio_name;
                        } else {
@@ -1089,8 +1056,8 @@ lba_pat_resources(struct parisc_device *pa_dev, struct lba_device *lba_dev)
 
                case PAT_GMMIO:
                        /* MMIO space > 4GB phys addr; for 64-bit BAR */
-                       sprintf(lba_dev->hba.gmmio_name, "PCI%02lx GMMIO",
-                                       lba_dev->hba.bus_num.start);
+                       sprintf(lba_dev->hba.gmmio_name, "PCI%02x GMMIO",
+                                       (int)lba_dev->hba.bus_num.start);
                        r = &lba_dev->hba.gmmio_space;
                        r->name  = lba_dev->hba.gmmio_name;
                        r->start  = p->start;
@@ -1112,8 +1079,8 @@ lba_pat_resources(struct parisc_device *pa_dev, struct lba_device *lba_dev)
                        */
                        lba_dev->iop_base = ioremap_nocache(p->start, 64 * 1024 * 1024);
 
-                       sprintf(lba_dev->hba.io_name, "PCI%02lx Ports",
-                                       lba_dev->hba.bus_num.start);
+                       sprintf(lba_dev->hba.io_name, "PCI%02x Ports",
+                                       (int)lba_dev->hba.bus_num.start);
                        r = &lba_dev->hba.io_space;
                        r->name  = lba_dev->hba.io_name;
                        r->start  = HBA_PORT_BASE(lba_dev->hba.hba_num);
@@ -1166,8 +1133,8 @@ lba_legacy_resources(struct parisc_device *pa_dev, struct lba_device *lba_dev)
        ** Legacy boxes but it's nice to see in /proc/iomem.
        */
        r = &(lba_dev->hba.lmmio_space);
-       sprintf(lba_dev->hba.lmmio_name, "PCI%02lx LMMIO",
-                                       lba_dev->hba.bus_num.start);
+       sprintf(lba_dev->hba.lmmio_name, "PCI%02x LMMIO",
+                                       (int)lba_dev->hba.bus_num.start);
        r->name  = lba_dev->hba.lmmio_name;
 
 #if 1
@@ -1275,8 +1242,8 @@ lba_legacy_resources(struct parisc_device *pa_dev, struct lba_device *lba_dev)
        ** an existing (but unused portion of) distributed range.
        */
        r = &(lba_dev->hba.elmmio_space);
-       sprintf(lba_dev->hba.elmmio_name, "PCI%02lx ELMMIO",
-                                       lba_dev->hba.bus_num.start);
+       sprintf(lba_dev->hba.elmmio_name, "PCI%02x ELMMIO",
+                                       (int)lba_dev->hba.bus_num.start);
        r->name  = lba_dev->hba.elmmio_name;
 
 #if 1
@@ -1297,8 +1264,8 @@ lba_legacy_resources(struct parisc_device *pa_dev, struct lba_device *lba_dev)
 #endif
 
        r = &(lba_dev->hba.io_space);
-       sprintf(lba_dev->hba.io_name, "PCI%02lx Ports",
-                                       lba_dev->hba.bus_num.start);
+       sprintf(lba_dev->hba.io_name, "PCI%02x Ports",
+                                       (int)lba_dev->hba.bus_num.start);
        r->name  = lba_dev->hba.io_name;
        r->flags = IORESOURCE_IO;
        r->start = READ_REG32(lba_dev->hba.base_addr + LBA_IOS_BASE) & ~1L;
@@ -1406,13 +1373,20 @@ lba_hw_init(struct lba_device *d)
        return 0;
 }
 
-
+/*
+ * Unfortunately, when firmware numbers busses, it doesn't take into account
+ * Cardbus bridges.  So we have to renumber the busses to suit ourselves.
+ * Elroy/Mercury don't actually know what bus number they're attached to;
+ * we use bus 0 to indicate the directly attached bus and any other bus
+ * number will be taken care of by the PCI-PCI bridge.
+ */
+static unsigned int lba_next_bus = 0;
 
 /*
-** Determine if lba should claim this chip (return 0) or not (return 1).
-** If so, initialize the chip and tell other partners in crime they
-** have work to do.
-*/
+ * Determine if lba should claim this chip (return 0) or not (return 1).
+ * If so, initialize the chip and tell other partners in crime they
+ * have work to do.
+ */
 static int __init
 lba_driver_probe(struct parisc_device *dev)
 {
@@ -1440,7 +1414,7 @@ lba_driver_probe(struct parisc_device *dev)
                }
 
                printk(KERN_INFO "Elroy version %s (0x%x) found at 0x%lx\n",
-                      version, func_class & 0xf, dev->hpa.start);
+                      version, func_class & 0xf, (long)dev->hpa.start);
 
                if (func_class < 2) {
                        printk(KERN_WARNING "Can't support LBA older than "
@@ -1470,17 +1444,16 @@ lba_driver_probe(struct parisc_device *dev)
                  */ 
                printk(KERN_INFO "%s version TR%d.%d (0x%x) found at 0x%lx\n",
                       IS_MERCURY(dev) ? "Mercury" : "Quicksilver", major,
-                      minor, func_class, dev->hpa.start);
+                      minor, func_class, (long)dev->hpa.start);
 
                cfg_ops = &mercury_cfg_ops;
        } else {
-               printk(KERN_ERR "Unknown LBA found at 0x%lx\n", dev->hpa.start);
+               printk(KERN_ERR "Unknown LBA found at 0x%lx\n",
+                       (long)dev->hpa.start);
                return -ENODEV;
        }
 
-       /*
-       ** Tell I/O SAPIC driver we have a IRQ handler/region.
-       */
+       /* Tell I/O SAPIC driver we have a IRQ handler/region. */
        tmp_obj = iosapic_register(dev->hpa.start + LBA_IOSAPIC_BASE);
 
        /* NOTE: PCI devices (e.g. 103c:1005 graphics card) which don't
@@ -1529,16 +1502,17 @@ lba_driver_probe(struct parisc_device *dev)
                lba_legacy_resources(dev, lba_dev);
        }
 
-       /* 
-       ** Tell PCI support another PCI bus was found.
-       ** Walks PCI bus for us too.
-       */
+       if (lba_dev->hba.bus_num.start < lba_next_bus)
+               lba_dev->hba.bus_num.start = lba_next_bus;
+
        dev->dev.platform_data = lba_dev;
        lba_bus = lba_dev->hba.hba_bus =
                pci_scan_bus_parented(&dev->dev, lba_dev->hba.bus_num.start,
                                cfg_ops, NULL);
-       if (lba_bus)
+       if (lba_bus) {
+               lba_next_bus = lba_bus->subordinate + 1;
                pci_bus_add_devices(lba_bus);
+       }
 
        /* This is in lieu of calling pci_assign_unassigned_resources() */
        if (is_pdc_pat()) {
@@ -1610,7 +1584,7 @@ void lba_set_iregs(struct parisc_device *lba, u32 ibase, u32 imask)
        WARN_ON((ibase & 0x001fffff) != 0);
        WARN_ON((imask & 0x001fffff) != 0);
        
-       DBG("%s() ibase 0x%x imask 0x%x\n", __FUNCTION__, ibase, imask);
+       DBG("%s() ibase 0x%x imask 0x%x\n", __func__, ibase, imask);
        WRITE_REG32( imask, base_addr + LBA_IMASK);
        WRITE_REG32( ibase, base_addr + LBA_IBASE);
        iounmap(base_addr);