diff options
Diffstat (limited to 'arch/powerpc/kernel/pci_32.c')
-rw-r--r-- | arch/powerpc/kernel/pci_32.c | 96 |
1 files changed, 28 insertions, 68 deletions
diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c index 0d9ff72e2852..2f54cd81dea5 100644 --- a/arch/powerpc/kernel/pci_32.c +++ b/arch/powerpc/kernel/pci_32.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/errno.h> | 12 | #include <linux/errno.h> |
13 | #include <linux/bootmem.h> | 13 | #include <linux/bootmem.h> |
14 | #include <linux/irq.h> | 14 | #include <linux/irq.h> |
15 | #include <linux/list.h> | ||
15 | 16 | ||
16 | #include <asm/processor.h> | 17 | #include <asm/processor.h> |
17 | #include <asm/io.h> | 18 | #include <asm/io.h> |
@@ -99,7 +100,7 @@ pcibios_fixup_resources(struct pci_dev *dev) | |||
99 | continue; | 100 | continue; |
100 | if (res->end == 0xffffffff) { | 101 | if (res->end == 0xffffffff) { |
101 | DBG("PCI:%s Resource %d [%016llx-%016llx] is unassigned\n", | 102 | DBG("PCI:%s Resource %d [%016llx-%016llx] is unassigned\n", |
102 | pci_name(dev), i, res->start, res->end); | 103 | pci_name(dev), i, (u64)res->start, (u64)res->end); |
103 | res->end -= res->start; | 104 | res->end -= res->start; |
104 | res->start = 0; | 105 | res->start = 0; |
105 | res->flags |= IORESOURCE_UNSET; | 106 | res->flags |= IORESOURCE_UNSET; |
@@ -115,11 +116,9 @@ pcibios_fixup_resources(struct pci_dev *dev) | |||
115 | if (offset != 0) { | 116 | if (offset != 0) { |
116 | res->start += offset; | 117 | res->start += offset; |
117 | res->end += offset; | 118 | res->end += offset; |
118 | #ifdef DEBUG | 119 | DBG("Fixup res %d (%lx) of dev %s: %llx -> %llx\n", |
119 | printk("Fixup res %d (%lx) of dev %s: %llx -> %llx\n", | 120 | i, res->flags, pci_name(dev), |
120 | i, res->flags, pci_name(dev), | 121 | (u64)res->start - offset, (u64)res->start); |
121 | res->start - offset, res->start); | ||
122 | #endif | ||
123 | } | 122 | } |
124 | } | 123 | } |
125 | 124 | ||
@@ -255,7 +254,7 @@ pcibios_allocate_bus_resources(struct list_head *bus_list) | |||
255 | } | 254 | } |
256 | 255 | ||
257 | DBG("PCI: bridge rsrc %llx..%llx (%lx), parent %p\n", | 256 | DBG("PCI: bridge rsrc %llx..%llx (%lx), parent %p\n", |
258 | res->start, res->end, res->flags, pr); | 257 | (u64)res->start, (u64)res->end, res->flags, pr); |
259 | if (pr) { | 258 | if (pr) { |
260 | if (request_resource(pr, res) == 0) | 259 | if (request_resource(pr, res) == 0) |
261 | continue; | 260 | continue; |
@@ -306,7 +305,7 @@ reparent_resources(struct resource *parent, struct resource *res) | |||
306 | for (p = res->child; p != NULL; p = p->sibling) { | 305 | for (p = res->child; p != NULL; p = p->sibling) { |
307 | p->parent = res; | 306 | p->parent = res; |
308 | DBG(KERN_INFO "PCI: reparented %s [%llx..%llx] under %s\n", | 307 | DBG(KERN_INFO "PCI: reparented %s [%llx..%llx] under %s\n", |
309 | p->name, p->start, p->end, res->name); | 308 | p->name, (u64)p->start, (u64)p->end, res->name); |
310 | } | 309 | } |
311 | return 0; | 310 | return 0; |
312 | } | 311 | } |
@@ -362,7 +361,7 @@ pci_relocate_bridge_resource(struct pci_bus *bus, int i) | |||
362 | } | 361 | } |
363 | if (request_resource(pr, res)) { | 362 | if (request_resource(pr, res)) { |
364 | DBG(KERN_ERR "PCI: huh? couldn't move to %llx..%llx\n", | 363 | DBG(KERN_ERR "PCI: huh? couldn't move to %llx..%llx\n", |
365 | res->start, res->end); | 364 | (u64)res->start, (u64)res->end); |
366 | return -1; /* "can't happen" */ | 365 | return -1; /* "can't happen" */ |
367 | } | 366 | } |
368 | update_bridge_base(bus, i); | 367 | update_bridge_base(bus, i); |
@@ -480,14 +479,14 @@ static inline void alloc_resource(struct pci_dev *dev, int idx) | |||
480 | struct resource *pr, *r = &dev->resource[idx]; | 479 | struct resource *pr, *r = &dev->resource[idx]; |
481 | 480 | ||
482 | DBG("PCI:%s: Resource %d: %016llx-%016llx (f=%lx)\n", | 481 | DBG("PCI:%s: Resource %d: %016llx-%016llx (f=%lx)\n", |
483 | pci_name(dev), idx, r->start, r->end, r->flags); | 482 | pci_name(dev), idx, (u64)r->start, (u64)r->end, r->flags); |
484 | pr = pci_find_parent_resource(dev, r); | 483 | pr = pci_find_parent_resource(dev, r); |
485 | if (!pr || request_resource(pr, r) < 0) { | 484 | if (!pr || request_resource(pr, r) < 0) { |
486 | printk(KERN_ERR "PCI: Cannot allocate resource region %d" | 485 | printk(KERN_ERR "PCI: Cannot allocate resource region %d" |
487 | " of device %s\n", idx, pci_name(dev)); | 486 | " of device %s\n", idx, pci_name(dev)); |
488 | if (pr) | 487 | if (pr) |
489 | DBG("PCI: parent is %p: %016llx-%016llx (f=%lx)\n", | 488 | DBG("PCI: parent is %p: %016llx-%016llx (f=%lx)\n", |
490 | pr, pr->start, pr->end, pr->flags); | 489 | pr, (u64)pr->start, (u64)pr->end, pr->flags); |
491 | /* We'll assign a new address later */ | 490 | /* We'll assign a new address later */ |
492 | r->flags |= IORESOURCE_UNSET; | 491 | r->flags |= IORESOURCE_UNSET; |
493 | r->end -= r->start; | 492 | r->end -= r->start; |
@@ -960,7 +959,7 @@ pci_process_bridge_OF_ranges(struct pci_controller *hose, | |||
960 | res->flags = IORESOURCE_IO; | 959 | res->flags = IORESOURCE_IO; |
961 | res->start = ranges[2]; | 960 | res->start = ranges[2]; |
962 | DBG("PCI: IO 0x%llx -> 0x%llx\n", | 961 | DBG("PCI: IO 0x%llx -> 0x%llx\n", |
963 | res->start, res->start + size - 1); | 962 | (u64)res->start, (u64)res->start + size - 1); |
964 | break; | 963 | break; |
965 | case 2: /* memory space */ | 964 | case 2: /* memory space */ |
966 | memno = 0; | 965 | memno = 0; |
@@ -982,7 +981,7 @@ pci_process_bridge_OF_ranges(struct pci_controller *hose, | |||
982 | res->flags |= IORESOURCE_PREFETCH; | 981 | res->flags |= IORESOURCE_PREFETCH; |
983 | res->start = ranges[na+2]; | 982 | res->start = ranges[na+2]; |
984 | DBG("PCI: MEM[%d] 0x%llx -> 0x%llx\n", memno, | 983 | DBG("PCI: MEM[%d] 0x%llx -> 0x%llx\n", memno, |
985 | res->start, res->start + size - 1); | 984 | (u64)res->start, (u64)res->start + size - 1); |
986 | } | 985 | } |
987 | break; | 986 | break; |
988 | } | 987 | } |
@@ -1268,7 +1267,10 @@ pcibios_init(void) | |||
1268 | if (pci_assign_all_buses) | 1267 | if (pci_assign_all_buses) |
1269 | hose->first_busno = next_busno; | 1268 | hose->first_busno = next_busno; |
1270 | hose->last_busno = 0xff; | 1269 | hose->last_busno = 0xff; |
1271 | bus = pci_scan_bus(hose->first_busno, hose->ops, hose); | 1270 | bus = pci_scan_bus_parented(hose->parent, hose->first_busno, |
1271 | hose->ops, hose); | ||
1272 | if (bus) | ||
1273 | pci_bus_add_devices(bus); | ||
1272 | hose->last_busno = bus->subordinate; | 1274 | hose->last_busno = bus->subordinate; |
1273 | if (pci_assign_all_buses || next_busno <= hose->last_busno) | 1275 | if (pci_assign_all_buses || next_busno <= hose->last_busno) |
1274 | next_busno = hose->last_busno + pcibios_assign_bus_offset; | 1276 | next_busno = hose->last_busno + pcibios_assign_bus_offset; |
@@ -1282,10 +1284,6 @@ pcibios_init(void) | |||
1282 | if (pci_assign_all_buses && have_of) | 1284 | if (pci_assign_all_buses && have_of) |
1283 | pcibios_make_OF_bus_map(); | 1285 | pcibios_make_OF_bus_map(); |
1284 | 1286 | ||
1285 | /* Do machine dependent PCI interrupt routing */ | ||
1286 | if (ppc_md.pci_swizzle && ppc_md.pci_map_irq) | ||
1287 | pci_fixup_irqs(ppc_md.pci_swizzle, ppc_md.pci_map_irq); | ||
1288 | |||
1289 | /* Call machine dependent fixup */ | 1287 | /* Call machine dependent fixup */ |
1290 | if (ppc_md.pcibios_fixup) | 1288 | if (ppc_md.pcibios_fixup) |
1291 | ppc_md.pcibios_fixup(); | 1289 | ppc_md.pcibios_fixup(); |
@@ -1308,25 +1306,6 @@ pcibios_init(void) | |||
1308 | 1306 | ||
1309 | subsys_initcall(pcibios_init); | 1307 | subsys_initcall(pcibios_init); |
1310 | 1308 | ||
1311 | unsigned char __init | ||
1312 | common_swizzle(struct pci_dev *dev, unsigned char *pinp) | ||
1313 | { | ||
1314 | struct pci_controller *hose = dev->sysdata; | ||
1315 | |||
1316 | if (dev->bus->number != hose->first_busno) { | ||
1317 | u8 pin = *pinp; | ||
1318 | do { | ||
1319 | pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn)); | ||
1320 | /* Move up the chain of bridges. */ | ||
1321 | dev = dev->bus->self; | ||
1322 | } while (dev->bus->self); | ||
1323 | *pinp = pin; | ||
1324 | |||
1325 | /* The slot is the idsel of the last bridge. */ | ||
1326 | } | ||
1327 | return PCI_SLOT(dev->devfn); | ||
1328 | } | ||
1329 | |||
1330 | unsigned long resource_fixup(struct pci_dev * dev, struct resource * res, | 1309 | unsigned long resource_fixup(struct pci_dev * dev, struct resource * res, |
1331 | unsigned long start, unsigned long size) | 1310 | unsigned long start, unsigned long size) |
1332 | { | 1311 | { |
@@ -1338,6 +1317,7 @@ void __init pcibios_fixup_bus(struct pci_bus *bus) | |||
1338 | struct pci_controller *hose = (struct pci_controller *) bus->sysdata; | 1317 | struct pci_controller *hose = (struct pci_controller *) bus->sysdata; |
1339 | unsigned long io_offset; | 1318 | unsigned long io_offset; |
1340 | struct resource *res; | 1319 | struct resource *res; |
1320 | struct pci_dev *dev; | ||
1341 | int i; | 1321 | int i; |
1342 | 1322 | ||
1343 | io_offset = (unsigned long)hose->io_base_virt - isa_io_base; | 1323 | io_offset = (unsigned long)hose->io_base_virt - isa_io_base; |
@@ -1390,8 +1370,16 @@ void __init pcibios_fixup_bus(struct pci_bus *bus) | |||
1390 | } | 1370 | } |
1391 | } | 1371 | } |
1392 | 1372 | ||
1373 | /* Platform specific bus fixups */ | ||
1393 | if (ppc_md.pcibios_fixup_bus) | 1374 | if (ppc_md.pcibios_fixup_bus) |
1394 | ppc_md.pcibios_fixup_bus(bus); | 1375 | ppc_md.pcibios_fixup_bus(bus); |
1376 | |||
1377 | /* Read default IRQs and fixup if necessary */ | ||
1378 | list_for_each_entry(dev, &bus->devices, bus_list) { | ||
1379 | pci_read_irq_line(dev); | ||
1380 | if (ppc_md.pci_irq_fixup) | ||
1381 | ppc_md.pci_irq_fixup(dev); | ||
1382 | } | ||
1395 | } | 1383 | } |
1396 | 1384 | ||
1397 | char __init *pcibios_setup(char *str) | 1385 | char __init *pcibios_setup(char *str) |
@@ -1571,7 +1559,7 @@ static struct resource *__pci_mmap_make_offset(struct pci_dev *dev, | |||
1571 | *offset += hose->pci_mem_offset; | 1559 | *offset += hose->pci_mem_offset; |
1572 | res_bit = IORESOURCE_MEM; | 1560 | res_bit = IORESOURCE_MEM; |
1573 | } else { | 1561 | } else { |
1574 | io_offset = hose->io_base_virt - ___IO_BASE; | 1562 | io_offset = hose->io_base_virt - (void __iomem *)_IO_BASE; |
1575 | *offset += io_offset; | 1563 | *offset += io_offset; |
1576 | res_bit = IORESOURCE_IO; | 1564 | res_bit = IORESOURCE_IO; |
1577 | } | 1565 | } |
@@ -1826,7 +1814,8 @@ void pci_resource_to_user(const struct pci_dev *dev, int bar, | |||
1826 | return; | 1814 | return; |
1827 | 1815 | ||
1828 | if (rsrc->flags & IORESOURCE_IO) | 1816 | if (rsrc->flags & IORESOURCE_IO) |
1829 | offset = ___IO_BASE - hose->io_base_virt + hose->io_base_phys; | 1817 | offset = (void __iomem *)_IO_BASE - hose->io_base_virt |
1818 | + hose->io_base_phys; | ||
1830 | 1819 | ||
1831 | *start = rsrc->start + offset; | 1820 | *start = rsrc->start + offset; |
1832 | *end = rsrc->end + offset; | 1821 | *end = rsrc->end + offset; |
@@ -1845,35 +1834,6 @@ pci_init_resource(struct resource *res, unsigned long start, unsigned long end, | |||
1845 | res->child = NULL; | 1834 | res->child = NULL; |
1846 | } | 1835 | } |
1847 | 1836 | ||
1848 | void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max) | ||
1849 | { | ||
1850 | unsigned long start = pci_resource_start(dev, bar); | ||
1851 | unsigned long len = pci_resource_len(dev, bar); | ||
1852 | unsigned long flags = pci_resource_flags(dev, bar); | ||
1853 | |||
1854 | if (!len) | ||
1855 | return NULL; | ||
1856 | if (max && len > max) | ||
1857 | len = max; | ||
1858 | if (flags & IORESOURCE_IO) | ||
1859 | return ioport_map(start, len); | ||
1860 | if (flags & IORESOURCE_MEM) | ||
1861 | /* Not checking IORESOURCE_CACHEABLE because PPC does | ||
1862 | * not currently distinguish between ioremap and | ||
1863 | * ioremap_nocache. | ||
1864 | */ | ||
1865 | return ioremap(start, len); | ||
1866 | /* What? */ | ||
1867 | return NULL; | ||
1868 | } | ||
1869 | |||
1870 | void pci_iounmap(struct pci_dev *dev, void __iomem *addr) | ||
1871 | { | ||
1872 | /* Nothing to do */ | ||
1873 | } | ||
1874 | EXPORT_SYMBOL(pci_iomap); | ||
1875 | EXPORT_SYMBOL(pci_iounmap); | ||
1876 | |||
1877 | unsigned long pci_address_to_pio(phys_addr_t address) | 1837 | unsigned long pci_address_to_pio(phys_addr_t address) |
1878 | { | 1838 | { |
1879 | struct pci_controller* hose = hose_head; | 1839 | struct pci_controller* hose = hose_head; |