diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-23 14:02:12 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-23 14:02:12 -0700 |
commit | 475c77edf826333aa61625f49d6a2bec26ecb5a6 (patch) | |
tree | 8e1c6c319e347cd3c649fdb0b3ab45971c6b19e7 /arch | |
parent | 934e18b5cb4531cc6e81865bf54115cfd21d1ac6 (diff) | |
parent | 1488d5158dcd612fcdaf6b642451b026ee8bbcbb (diff) |
Merge branch 'linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci
Pull PCI changes (including maintainer change) from Jesse Barnes:
"This pull has some good cleanups from Bjorn and Yinghai, as well as
some more code from Yinghai to better handle resource re-allocation
when enabled.
There's also a new initcall_debug feature from Arjan which will print
out quirk timing information to help identify slow quirks for fixing
or refinement (Yinghai sent in a few patches to do just that once the
new debug code landed).
Beyond that, I'm handing off PCI maintainership to Bjorn Helgaas.
He's been a core PCI and Linux contributor for some time now, and has
kindly volunteered to take over. I just don't feel I have the time
for PCI review and work that it deserves lately (I've taken on some
other projects), and haven't been as responsive lately as I'd like, so
I approached Bjorn asking if he'd like to manage things. He's going
to give it a try, and I'm confident he'll do at least as well as I
have in keeping the tree managed, patches flowing, and keeping things
stable."
Fix up some fairly trivial conflicts due to other cleanups (mips device
resource fixup cleanups clashing with list handling cleanup, ppc iseries
removal clashing with pci_probe_only cleanup etc)
* 'linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci: (112 commits)
PCI: Bjorn gets PCI hotplug too
PCI: hand PCI maintenance over to Bjorn Helgaas
unicore32/PCI: move <asm-generic/pci-bridge.h> include to asm/pci.h
sparc/PCI: convert devtree and arch-probed bus addresses to resource
powerpc/PCI: allow reallocation on PA Semi
powerpc/PCI: convert devtree bus addresses to resource
powerpc/PCI: compute I/O space bus-to-resource offset consistently
arm/PCI: don't export pci_flags
PCI: fix bridge I/O window bus-to-resource conversion
x86/PCI: add spinlock held check to 'pcibios_fwaddrmap_lookup()'
PCI / PCIe: Introduce command line option to disable ARI
PCI: make acpihp use __pci_remove_bus_device instead
PCI: export __pci_remove_bus_device
PCI: Rename pci_remove_behind_bridge to pci_stop_and_remove_behind_bridge
PCI: Rename pci_remove_bus_device to pci_stop_and_remove_bus_device
PCI: print out PCI device info along with duration
PCI: Move "pci reassigndev resource alignment" out of quirks.c
PCI: Use class for quirk for usb host controller fixup
PCI: Use class for quirk for ti816x class fixup
PCI: Use class for quirk for intel e100 interrupt fixup
...
Diffstat (limited to 'arch')
75 files changed, 355 insertions, 1058 deletions
diff --git a/arch/alpha/include/asm/pci.h b/arch/alpha/include/asm/pci.h index 28d0497fd3c7..d01afb78919c 100644 --- a/arch/alpha/include/asm/pci.h +++ b/arch/alpha/include/asm/pci.h @@ -7,6 +7,7 @@ #include <linux/dma-mapping.h> #include <asm/scatterlist.h> #include <asm/machvec.h> +#include <asm-generic/pci-bridge.h> /* * The following structure is used to manage multiple PCI busses. @@ -99,12 +100,6 @@ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel) return channel ? 15 : 14; } -extern void pcibios_resource_to_bus(struct pci_dev *, struct pci_bus_region *, - struct resource *); - -extern void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, - struct pci_bus_region *region); - #define pci_domain_nr(bus) ((struct pci_controller *)(bus)->sysdata)->index static inline int pci_proc_domain(struct pci_bus *bus) diff --git a/arch/alpha/kernel/pci.c b/arch/alpha/kernel/pci.c index 8c723c1b086a..1a629636cc16 100644 --- a/arch/alpha/kernel/pci.c +++ b/arch/alpha/kernel/pci.c @@ -43,12 +43,10 @@ const char *const pci_mem_names[] = { const char pci_hae0_name[] = "HAE0"; -/* Indicate whether we respect the PCI setup left by console. */ /* - * Make this long-lived so that we know when shutting down - * whether we probed only or not. + * If PCI_PROBE_ONLY in pci_flags is set, we don't change any PCI resource + * assignments. */ -int pci_probe_only; /* * The PCI controller list. @@ -215,7 +213,7 @@ pdev_save_srm_config(struct pci_dev *dev) struct pdev_srm_saved_conf *tmp; static int printed = 0; - if (!alpha_using_srm || pci_probe_only) + if (!alpha_using_srm || pci_has_flag(PCI_PROBE_ONLY)) return; if (!printed) { @@ -242,7 +240,7 @@ pci_restore_srm_config(void) struct pdev_srm_saved_conf *tmp; /* No need to restore if probed only. */ - if (pci_probe_only) + if (pci_has_flag(PCI_PROBE_ONLY)) return; /* Restore SRM config. */ @@ -253,46 +251,17 @@ pci_restore_srm_config(void) #endif void __devinit -pcibios_fixup_resource(struct resource *res, struct resource *root) -{ - res->start += root->start; - res->end += root->start; -} - -void __devinit -pcibios_fixup_device_resources(struct pci_dev *dev, struct pci_bus *bus) -{ - /* Update device resources. */ - struct pci_controller *hose = (struct pci_controller *)bus->sysdata; - int i; - - for (i = 0; i < PCI_NUM_RESOURCES; i++) { - if (!dev->resource[i].start) - continue; - if (dev->resource[i].flags & IORESOURCE_IO) - pcibios_fixup_resource(&dev->resource[i], - hose->io_space); - else if (dev->resource[i].flags & IORESOURCE_MEM) - pcibios_fixup_resource(&dev->resource[i], - hose->mem_space); - } -} - -void __devinit pcibios_fixup_bus(struct pci_bus *bus) { struct pci_dev *dev = bus->self; - if (pci_probe_only && dev && + if (pci_has_flag(PCI_PROBE_ONLY) && dev && (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) { pci_read_bridge_bases(bus); - pcibios_fixup_device_resources(dev, bus); } list_for_each_entry(dev, &bus->devices, bus_list) { pdev_save_srm_config(dev); - if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI) - pcibios_fixup_device_resources(dev, bus); } } @@ -302,42 +271,6 @@ pcibios_update_irq(struct pci_dev *dev, int irq) pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); } -void -pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, - struct resource *res) -{ - struct pci_controller *hose = (struct pci_controller *)dev->sysdata; - unsigned long offset = 0; - - if (res->flags & IORESOURCE_IO) - offset = hose->io_space->start; - else if (res->flags & IORESOURCE_MEM) - offset = hose->mem_space->start; - - region->start = res->start - offset; - region->end = res->end - offset; -} - -void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, - struct pci_bus_region *region) -{ - struct pci_controller *hose = (struct pci_controller *)dev->sysdata; - unsigned long offset = 0; - - if (res->flags & IORESOURCE_IO) - offset = hose->io_space->start; - else if (res->flags & IORESOURCE_MEM) - offset = hose->mem_space->start; - - res->start = region->start + offset; - res->end = region->end + offset; -} - -#ifdef CONFIG_HOTPLUG -EXPORT_SYMBOL(pcibios_resource_to_bus); -EXPORT_SYMBOL(pcibios_bus_to_resource); -#endif - int pcibios_enable_device(struct pci_dev *dev, int mask) { @@ -374,7 +307,8 @@ pcibios_claim_one_bus(struct pci_bus *b) if (r->parent || !r->start || !r->flags) continue; - if (pci_probe_only || (r->flags & IORESOURCE_PCI_FIXED)) + if (pci_has_flag(PCI_PROBE_ONLY) || + (r->flags & IORESOURCE_PCI_FIXED)) pci_claim_resource(dev, i); } } @@ -416,8 +350,10 @@ common_init_pci(void) hose->mem_space->end = end; INIT_LIST_HEAD(&resources); - pci_add_resource(&resources, hose->io_space); - pci_add_resource(&resources, hose->mem_space); + pci_add_resource_offset(&resources, hose->io_space, + hose->io_space->start); + pci_add_resource_offset(&resources, hose->mem_space, + hose->mem_space->start); bus = pci_scan_root_bus(NULL, next_busno, alpha_mv.pci_ops, hose, &resources); diff --git a/arch/alpha/kernel/pci_impl.h b/arch/alpha/kernel/pci_impl.h index 85457b2d4516..2b0ac429f5eb 100644 --- a/arch/alpha/kernel/pci_impl.h +++ b/arch/alpha/kernel/pci_impl.h @@ -173,9 +173,6 @@ extern void pci_restore_srm_config(void); extern struct pci_controller *hose_head, **hose_tail; extern struct pci_controller *pci_isa_hose; -/* Indicate that we trust the console to configure things properly. */ -extern int pci_probe_only; - extern unsigned long alpha_agpgart_size; extern void common_init_pci(void); diff --git a/arch/alpha/kernel/sys_marvel.c b/arch/alpha/kernel/sys_marvel.c index 95cfc83ece8f..fc8b12508611 100644 --- a/arch/alpha/kernel/sys_marvel.c +++ b/arch/alpha/kernel/sys_marvel.c @@ -384,7 +384,8 @@ marvel_init_pci(void) marvel_register_error_handlers(); - pci_probe_only = 1; + /* Indicate that we trust the console to configure things properly */ + pci_set_flags(PCI_PROBE_ONLY); common_init_pci(); locate_and_init_vga(NULL); diff --git a/arch/alpha/kernel/sys_titan.c b/arch/alpha/kernel/sys_titan.c index f47b30a2a117..b8eafa053539 100644 --- a/arch/alpha/kernel/sys_titan.c +++ b/arch/alpha/kernel/sys_titan.c @@ -331,7 +331,8 @@ titan_init_pci(void) */ titan_late_init(); - pci_probe_only = 1; + /* Indicate that we trust the console to configure things properly */ + pci_set_flags(PCI_PROBE_ONLY); common_init_pci(); SMC669_Init(0); locate_and_init_vga(NULL); diff --git a/arch/arm/common/it8152.c b/arch/arm/common/it8152.c index fb1f1cfce60c..dcb13494ca0d 100644 --- a/arch/arm/common/it8152.c +++ b/arch/arm/common/it8152.c @@ -299,8 +299,8 @@ int __init it8152_pci_setup(int nr, struct pci_sys_data *sys) goto err1; } - pci_add_resource(&sys->resources, &it8152_io); - pci_add_resource(&sys->resources, &it8152_mem); + pci_add_resource_offset(&sys->resources, &it8152_io, sys->io_offset); + pci_add_resource_offset(&sys->resources, &it8152_mem, sys->mem_offset); if (platform_notify || platform_notify_remove) { printk(KERN_ERR "PCI: Can't use platform_notify\n"); diff --git a/arch/arm/include/asm/pci.h b/arch/arm/include/asm/pci.h index da337ba57ffd..a98a2e112fae 100644 --- a/arch/arm/include/asm/pci.h +++ b/arch/arm/include/asm/pci.h @@ -57,14 +57,6 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev, extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, enum pci_mmap_state mmap_state, int write_combine); -extern void -pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, - struct resource *res); - -extern void -pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, - struct pci_bus_region *region); - /* * Dummy implementation; always return 0. */ diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c index f58ba3589908..632df9a66f8c 100644 --- a/arch/arm/kernel/bios32.c +++ b/arch/arm/kernel/bios32.c @@ -16,7 +16,6 @@ #include <asm/mach/pci.h> static int debug_pci; -static int use_firmware; /* * We can't use pci_find_device() here since we are @@ -295,28 +294,6 @@ static inline int pdev_bad_for_parity(struct pci_dev *dev) } /* - * Adjust the device resources from bus-centric to Linux-centric. - */ -static void __devinit -pdev_fixup_device_resources(struct pci_sys_data *root, struct pci_dev *dev) -{ - resource_size_t offset; - int i; - - for (i = 0; i < PCI_NUM_RESOURCES; i++) { - if (dev->resource[i].start == 0) - continue; - if (dev->resource[i].flags & IORESOURCE_MEM) - offset = root->mem_offset; - else - offset = root->io_offset; - - dev->resource[i].start += offset; - dev->resource[i].end += offset; - } -} - -/* * pcibios_fixup_bus - Called after each bus is probed, * but before its children are examined. */ @@ -333,8 +310,6 @@ void pcibios_fixup_bus(struct pci_bus *bus) list_for_each_entry(dev, &bus->devices, bus_list) { u16 status; - pdev_fixup_device_resources(root, dev); - pci_read_config_word(dev, PCI_STATUS, &status); /* @@ -400,43 +375,6 @@ EXPORT_SYMBOL(pcibios_fixup_bus); #endif /* - * Convert from Linux-centric to bus-centric addresses for bridge devices. - */ -void -pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, - struct resource *res) -{ - struct pci_sys_data *root = dev->sysdata; - unsigned long offset = 0; - - if (res->flags & IORESOURCE_IO) - offset = root->io_offset; - if (res->flags & IORESOURCE_MEM) - offset = root->mem_offset; - - region->start = res->start - offset; - region->end = res->end - offset; -} -EXPORT_SYMBOL(pcibios_resource_to_bus); - -void __devinit -pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, - struct pci_bus_region *region) -{ - struct pci_sys_data *root = dev->sysdata; - unsigned long offset = 0; - - if (res->flags & IORESOURCE_IO) - offset = root->io_offset; - if (res->flags & IORESOURCE_MEM) - offset = root->mem_offset; - - res->start = region->start + offset; - res->end = region->end + offset; -} -EXPORT_SYMBOL(pcibios_bus_to_resource); - -/* * Swizzle the device pin each time we cross a bridge. * This might update pin and returns the slot number. */ @@ -497,10 +435,10 @@ static void __init pcibios_init_hw(struct hw_pci *hw) if (ret > 0) { if (list_empty(&sys->resources)) { - pci_add_resource(&sys->resources, - &ioport_resource); - pci_add_resource(&sys->resources, - &iomem_resource); + pci_add_resource_offset(&sys->resources, + &ioport_resource, sys->io_offset); + pci_add_resource_offset(&sys->resources, + &iomem_resource, sys->mem_offset); } sys->bus = hw->scan(nr, sys); @@ -525,6 +463,7 @@ void __init pci_common_init(struct hw_pci *hw) INIT_LIST_HEAD(&hw->buses); + pci_add_flags(PCI_REASSIGN_ALL_RSRC); if (hw->preinit) hw->preinit(); pcibios_init_hw(hw); @@ -536,7 +475,7 @@ void __init pci_common_init(struct hw_pci *hw) list_for_each_entry(sys, &hw->buses, node) { struct pci_bus *bus = sys->bus; - if (!use_firmware) { + if (!pci_has_flag(PCI_PROBE_ONLY)) { /* * Size the bridge windows. */ @@ -573,7 +512,7 @@ char * __init pcibios_setup(char *str) debug_pci = 1; return NULL; } else if (!strcmp(str, "firmware")) { - use_firmware = 1; + pci_add_flags(PCI_PROBE_ONLY); return NULL; } return str; diff --git a/arch/arm/mach-cns3xxx/pcie.c b/arch/arm/mach-cns3xxx/pcie.c index e159d69967c9..79d001f831e0 100644 --- a/arch/arm/mach-cns3xxx/pcie.c +++ b/arch/arm/mach-cns3xxx/pcie.c @@ -155,8 +155,8 @@ static int cns3xxx_pci_setup(int nr, struct pci_sys_data *sys) BUG_ON(request_resource(&iomem_resource, res_io) || request_resource(&iomem_resource, res_mem)); - pci_add_resource(&sys->resources, res_io); - pci_add_resource(&sys->resources, res_mem); + pci_add_resource_offset(&sys->resources, res_io, sys->io_offset); + pci_add_resource_offset(&sys->resources, res_mem, sys->mem_offset); return 1; } diff --git a/arch/arm/mach-dove/pcie.c b/arch/arm/mach-dove/pcie.c index 52e96d397ba8..48a032005ea3 100644 --- a/arch/arm/mach-dove/pcie.c +++ b/arch/arm/mach-dove/pcie.c @@ -69,7 +69,7 @@ static int __init dove_pcie_setup(int nr, struct pci_sys_data *sys) pp->res[0].flags = IORESOURCE_IO; if (request_resource(&ioport_resource, &pp->res[0])) panic("Request PCIe IO resource failed\n"); - pci_add_resource(&sys->resources, &pp->res[0]); + pci_add_resource_offset(&sys->resources, &pp->res[0], sys->io_offset); /* * IORESOURCE_MEM @@ -88,7 +88,7 @@ static int __init dove_pcie_setup(int nr, struct pci_sys_data *sys) pp->res[1].flags = IORESOURCE_MEM; if (request_resource(&iomem_resource, &pp->res[1])) panic("Request PCIe Memory resource failed\n"); - pci_add_resource(&sys->resources, &pp->res[1]); + pci_add_resource_offset(&sys->resources, &pp->res[1], sys->mem_offset); return 1; } diff --git a/arch/arm/mach-footbridge/dc21285.c b/arch/arm/mach-footbridge/dc21285.c index f685650c25d7..3194d3f73503 100644 --- a/arch/arm/mach-footbridge/dc21285.c +++ b/arch/arm/mach-footbridge/dc21285.c @@ -275,11 +275,13 @@ int __init dc21285_setup(int nr, struct pci_sys_data *sys) allocate_resource(&iomem_resource, &res[0], 0x40000000, 0x80000000, 0xffffffff, 0x40000000, NULL, NULL); - pci_add_resource(&sys->resources, &ioport_resource); - pci_add_resource(&sys->resources, &res[0]); - pci_add_resource(&sys->resources, &res[1]); sys->mem_offset = DC21285_PCI_MEM; + pci_add_resource_offset(&sys->resources, + &ioport_resource, sys->io_offset); + pci_add_resource_offset(&sys->resources, &res[0], sys->mem_offset); + pci_add_resource_offset(&sys->resources, &res[1], sys->mem_offset); + return 1; } diff --git a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c index 3c82566acece..015be770c1d8 100644 --- a/arch/arm/mach-integrator/pci_v3.c +++ b/arch/arm/mach-integrator/pci_v3.c @@ -378,9 +378,10 @@ static int __init pci_v3_setup_resources(struct pci_sys_data *sys) * the mem resource for this bus * the prefetch mem resource for this bus */ - pci_add_resource(&sys->resources, &ioport_resource); - pci_add_resource(&sys->resources, &non_mem); - pci_add_resource(&sys->resources, &pre_mem); + pci_add_resource_offset(&sys->resources, + &ioport_resource, sys->io_offset); + pci_add_resource_offset(&sys->resources, &non_mem, sys->mem_offset); + pci_add_resource_offset(&sys->resources, &pre_mem, sys->mem_offset); return 1; } diff --git a/arch/arm/mach-iop13xx/pci.c b/arch/arm/mach-iop13xx/pci.c index b8f5a8736511..861cb12ef436 100644 --- a/arch/arm/mach-iop13xx/pci.c +++ b/arch/arm/mach-iop13xx/pci.c @@ -1084,8 +1084,8 @@ int iop13xx_pci_setup(int nr, struct pci_sys_data *sys) request_resource(&ioport_resource, &res[0]); request_resource(&iomem_resource, &res[1]); - pci_add_resource(&sys->resources, &res[0]); - pci_add_resource(&sys->resources, &res[1]); + pci_add_resource_offset(&sys->resources, &res[0], sys->io_offset); + pci_add_resource_offset(&sys->resources, &res[1], sys->mem_offset); return 1; } diff --git a/arch/arm/mach-ixp2000/ixdp2400.c b/arch/arm/mach-ixp2000/ixdp2400.c index f53e911ec94a..d519944653ad 100644 --- a/arch/arm/mach-ixp2000/ixdp2400.c +++ b/arch/arm/mach-ixp2000/ixdp2400.c @@ -134,11 +134,11 @@ static void ixdp2400_pci_postinit(void) if (ixdp2x00_master_npu()) { dev = pci_get_bus_and_slot(1, IXDP2400_SLAVE_ENET_DEVFN); - pci_remove_bus_device(dev); + pci_stop_and_remove_bus_device(dev); pci_dev_put(dev); } else { dev = pci_get_bus_and_slot(1, IXDP2400_MASTER_ENET_DEVFN); - pci_remove_bus_device(dev); + pci_stop_and_remove_bus_device(dev); pci_dev_put(dev); ixdp2x00_slave_pci_postinit(); diff --git a/arch/arm/mach-ixp2000/ixdp2800.c b/arch/arm/mach-ixp2000/ixdp2800.c index a2e7c393e74f..b415febd2025 100644 --- a/arch/arm/mach-ixp2000/ixdp2800.c +++ b/arch/arm/mach-ixp2000/ixdp2800.c @@ -262,14 +262,14 @@ int __init ixdp2800_pci_init(void) pci_common_init(&ixdp2800_pci); if (ixdp2x00_master_npu()) { dev = pci_get_bus_and_slot(1, IXDP2800_SLAVE_ENET_DEVFN); - pci_remove_bus_device(dev); + pci_stop_and_remove_bus_device(dev); pci_dev_put(dev); ixdp2800_master_enable_slave(); ixdp2800_master_wait_for_slave_bus_scan(); } else { dev = pci_get_bus_and_slot(1, IXDP2800_MASTER_ENET_DEVFN); - pci_remove_bus_device(dev); + pci_stop_and_remove_bus_device(dev); pci_dev_put(dev); } } diff --git a/arch/arm/mach-ixp2000/ixdp2x00.c b/arch/arm/mach-ixp2000/ixdp2x00.c index 634b6c852f68..dd9838299068 100644 --- a/arch/arm/mach-ixp2000/ixdp2x00.c +++ b/arch/arm/mach-ixp2000/ixdp2x00.c @@ -239,12 +239,12 @@ void ixdp2x00_slave_pci_postinit(void) * Remove PMC device is there is one */ if((dev = pci_get_bus_and_slot(1, IXDP2X00_PMC_DEVFN))) { - pci_remove_bus_device(dev); + pci_stop_and_remove_bus_device(dev); pci_dev_put(dev); } dev = pci_get_bus_and_slot(0, IXDP2X00_21555_DEVFN); - pci_remove_bus_device(dev); + pci_stop_and_remove_bus_device(dev); pci_dev_put(dev); } diff --git a/arch/arm/mach-ixp2000/pci.c b/arch/arm/mach-ixp2000/pci.c index 626fda435aa9..49c36f3cd602 100644 --- a/arch/arm/mach-ixp2000/pci.c +++ b/arch/arm/mach-ixp2000/pci.c @@ -243,8 +243,10 @@ int ixp2000_pci_setup(int nr, struct pci_sys_data *sys) if (nr >= 1) return 0; - pci_add_resource(&sys->resources, &ixp2000_pci_io_space); - pci_add_resource(&sys->resources, &ixp2000_pci_mem_space); + pci_add_resource_offset(&sys->resources, + &ixp2000_pci_io_space, sys->io_offset); + pci_add_resource_offset(&sys->resources, + &ixp2000_pci_mem_space, sys->mem_offset); return 1; } diff --git a/arch/arm/mach-ixp23xx/pci.c b/arch/arm/mach-ixp23xx/pci.c index 25b5c462cea2..3cbbd3208fa8 100644 --- a/arch/arm/mach-ixp23xx/pci.c +++ b/arch/arm/mach-ixp23xx/pci.c @@ -281,8 +281,10 @@ int ixp23xx_pci_setup(int nr, struct pci_sys_data *sys) if (nr >= 1) return 0; - pci_add_resource(&sys->resources, &ixp23xx_pci_io_space); - pci_add_resource(&sys->resources, &ixp23xx_pci_mem_space); + pci_add_resource_offset(&sys->resources, + &ixp23xx_pci_io_space, sys->io_offset); + pci_add_resource_offset(&sys->resources, + &ixp23xx_pci_mem_space, sys->mem_offset); return 1; } diff --git a/arch/arm/mach-ixp4xx/common-pci.c b/arch/arm/mach-ixp4xx/common-pci.c index 5eff15f24bc2..8508882b13f0 100644 --- a/arch/arm/mach-ixp4xx/common-pci.c +++ b/arch/arm/mach-ixp4xx/common-pci.c @@ -472,8 +472,8 @@ int ixp4xx_setup(int nr, struct pci_sys_data *sys) request_resource(&ioport_resource, &res[0]); request_resource(&iomem_resource, &res[1]); - pci_add_resource(&sys->resources, &res[0]); - pci_add_resource(&sys->resources, &res[1]); + pci_add_resource_offset(&sys->resources, &res[0], sys->io_offset); + pci_add_resource_offset(&sys->resources, &res[1], sys->mem_offset); platform_notify = ixp4xx_pci_platform_notify; platform_notify_remove = ixp4xx_pci_platform_notify_remove; diff --git a/arch/arm/mach-kirkwood/pcie.c b/arch/arm/mach-kirkwood/pcie.c index a066a6d8d9d2..f56a0118c1bb 100644 --- a/arch/arm/mach-kirkwood/pcie.c +++ b/arch/arm/mach-kirkwood/pcie.c @@ -198,9 +198,9 @@ static int __init kirkwood_pcie_setup(int nr, struct pci_sys_data *sys) if (request_resource(&iomem_resource, &pp->res[1])) panic("Request PCIe%d Memory resource failed\n", index); - pci_add_resource(&sys->resources, &pp->res[0]); - pci_add_resource(&sys->resources, &pp->res[1]); sys->io_offset = 0; + pci_add_resource_offset(&sys->resources, &pp->res[0], sys->io_offset); + pci_add_resource_offset(&sys->resources, &pp->res[1], sys->mem_offset); /* * Generic PCIe unit setup. diff --git a/arch/arm/mach-ks8695/pci.c b/arch/arm/mach-ks8695/pci.c index b26f992071df..acc701435817 100644 --- a/arch/arm/mach-ks8695/pci.c +++ b/arch/arm/mach-ks8695/pci.c @@ -169,8 +169,8 @@ static int __init ks8695_pci_setup(int nr, struct pci_sys_data *sys) request_resource(&iomem_resource, &pci_mem); request_resource(&ioport_resource, &pci_io); - pci_add_resource(&sys->resources, &pci_io); - pci_add_resource(&sys->resources, &pci_mem); + pci_add_resource_offset(&sys->resources, &pci_io, sys->io_offset); + pci_add_resource_offset(&sys->resources, &pci_mem, sys->mem_offset); /* Assign and enable processor bridge */ ks8695_local_writeconfig(PCI_BASE_ADDRESS_0, KS8695_PCIMEM_PA); diff --git a/arch/arm/mach-mv78xx0/pcie.c b/arch/arm/mach-mv78xx0/pcie.c index 8459f6d7d8ca..df3e38055a24 100644 --- a/arch/arm/mach-mv78xx0/pcie.c +++ b/arch/arm/mach-mv78xx0/pcie.c @@ -155,8 +155,8 @@ static int __init mv78xx0_pcie_setup(int nr, struct pci_sys_data *sys) orion_pcie_set_local_bus_nr(pp->base, sys->busnr); orion_pcie_setup(pp->base); - pci_add_resource(&sys->resources, &pp->res[0]); - pci_add_resource(&sys->resources, &pp->res[1]); + pci_add_resource_offset(&sys->resources, &pp->res[0], sys->io_offset); + pci_add_resource_offset(&sys->resources, &pp->res[1], sys->mem_offset); return 1; } diff --git a/arch/arm/mach-orion5x/pci.c b/arch/arm/mach-orion5x/pci.c index 09a045f0c406..d6a91948e4dc 100644 --- a/arch/arm/mach-orion5x/pci.c +++ b/arch/arm/mach-orion5x/pci.c @@ -171,13 +171,14 @@ static int __init pcie_setup(struct pci_sys_data *sys) /* * IORESOURCE_IO */ + sys->io_offset = 0; res[0].name = "PCIe I/O Space"; res[0].flags = IORESOURCE_IO; res[0].start = ORION5X_PCIE_IO_BUS_BASE; res[0].end = res[0].start + ORION5X_PCIE_IO_SIZE - 1; if (request_resource(&ioport_resource, &res[0])) panic("Request PCIe IO resource failed\n"); - pci_add_resource(&sys->resources, &res[0]); + pci_add_resource_offset(&sys->resources, &res[0], sys->io_offset); /* * IORESOURCE_MEM @@ -188,9 +189,7 @@ static int __init pcie_setup(struct pci_sys_data *sys) res[1].end = res[1].start + ORION5X_PCIE_MEM_SIZE - 1; if (request_resource(&iomem_resource, &res[1])) panic("Request PCIe Memory resource failed\n"); - pci_add_resource(&sys->resources, &res[1]); - - sys->io_offset = 0; + pci_add_resource_offset(&sys->resources, &res[1], sys->mem_offset); return 1; } @@ -499,13 +498,14 @@ static int __init pci_setup(struct pci_sys_data *sys) /* * IORESOURCE_IO */ + sys->io_offset = 0; res[0].name = "PCI I/O Space"; res[0].flags = IORESOURCE_IO; res[0].start = ORION5X_PCI_IO_BUS_BASE; res[0].end = res[0].start + ORION5X_PCI_IO_SIZE - 1; if (request_resource(&ioport_resource, &res[0])) panic("Request PCI IO resource failed\n"); - pci_add_resource(&sys->resources, &res[0]); + pci_add_resource_offset(&sys->resources, &res[0], sys->io_offset); /* * IORESOURCE_MEM @@ -516,9 +516,7 @@ static int __init pci_setup(struct pci_sys_data *sys) res[1].end = res[1].start + ORION5X_PCI_MEM_SIZE - 1; if (request_resource(&iomem_resource, &res[1])) panic("Request PCI Memory resource failed\n"); - pci_add_resource(&sys->resources, &res[1]); - - sys->io_offset = 0; + pci_add_resource_offset(&sys->resources, &res[1], sys->mem_offset); return 1; } diff --git a/arch/arm/mach-sa1100/pci-nanoengine.c b/arch/arm/mach-sa1100/pci-nanoengine.c index 0d01ca788922..b466bca9c651 100644 --- a/arch/arm/mach-sa1100/pci-nanoengine.c +++ b/arch/arm/mach-sa1100/pci-nanoengine.c @@ -244,9 +244,11 @@ static int __init pci_nanoengine_setup_resources(struct pci_sys_data *sys) printk(KERN_ERR "PCI: unable to allocate prefetchable\n"); return -EBUSY; } - pci_add_resource(&sys->resources, &pci_io_ports); - pci_add_resource(&sys->resources, &pci_non_prefetchable_memory); - pci_add_resource(&sys->resources, &pci_prefetchable_memory); + pci_add_resource_offset(&sys->resources, &pci_io_ports, sys->io_offset); + pci_add_resource_offset(&sys->resources, + &pci_non_prefetchable_memory, sys->mem_offset); + pci_add_resource_offset(&sys->resources, + &pci_prefetchable_memory, sys->mem_offset); return 1; } diff --git a/arch/arm/mach-tegra/pcie.c b/arch/arm/mach-tegra/pcie.c index af8b63435727..14b29ab5d8f0 100644 --- a/arch/arm/mach-tegra/pcie.c +++ b/arch/arm/mach-tegra/pcie.c @@ -408,7 +408,7 @@ static int tegra_pcie_setup(int nr, struct pci_sys_data *sys) pp->res[0].flags = IORESOURCE_IO; if (request_resource(&ioport_resource, &pp->res[0])) panic("Request PCIe IO resource failed\n"); - pci_add_resource(&sys->resources, &pp->res[0]); + pci_add_resource_offset(&sys->resources, &pp->res[0], sys->io_offset); /* * IORESOURCE_MEM @@ -427,7 +427,7 @@ static int tegra_pcie_setup(int nr, struct pci_sys_data *sys) pp->res[1].flags = IORESOURCE_MEM; if (request_resource(&iomem_resource, &pp->res[1])) panic("Request PCIe Memory resource failed\n"); - pci_add_resource(&sys->resources, &pp->res[1]); + pci_add_resource_offset(&sys->resources, &pp->res[1], sys->mem_offset); /* * IORESOURCE_MEM | IORESOURCE_PREFETCH @@ -446,7 +446,7 @@ static int tegra_pcie_setup(int nr, struct pci_sys_data *sys) pp->res[2].flags = IORESOURCE_MEM | IORESOURCE_PREFETCH; if (request_resource(&iomem_resource, &pp->res[2])) panic("Request PCIe Prefetch Memory resource failed\n"); - pci_add_resource(&sys->resources, &pp->res[2]); + pci_add_resource_offset(&sys->resources, &pp->res[2], sys->mem_offset); return 1; } diff --git a/arch/arm/mach-versatile/pci.c b/arch/arm/mach-versatile/pci.c index 90069bce23bc..51733b022d04 100644 --- a/arch/arm/mach-versatile/pci.c +++ b/arch/arm/mach-versatile/pci.c @@ -219,9 +219,9 @@ static int __init pci_versatile_setup_resources(struct list_head *resources) * the mem resource for this bus * the prefetch mem resource for this bus */ - pci_add_resource(resources, &io_mem); - pci_add_resource(resources, &non_mem); - pci_add_resource(resources, &pre_mem); + pci_add_resource_offset(resources, &io_mem, sys->io_offset); + pci_add_resource_offset(resources, &non_mem, sys->mem_offset); + pci_add_resource_offset(resources, &pre_mem, sys->mem_offset); goto out; diff --git a/arch/arm/mm/iomap.c b/arch/arm/mm/iomap.c index e62956e12030..4614208369f1 100644 --- a/arch/arm/mm/iomap.c +++ b/arch/arm/mm/iomap.c @@ -32,9 +32,6 @@ EXPORT_SYMBOL(pcibios_min_io); unsigned long pcibios_min_mem = 0x01000000; EXPORT_SYMBOL(pcibios_min_mem); -unsigned int pci_flags = PCI_REASSIGN_ALL_RSRC; -EXPORT_SYMBOL(pci_flags); - void pci_iounmap(struct pci_dev *dev, void __iomem *addr) { if ((unsigned long)addr >= VMALLOC_START && diff --git a/arch/arm/plat-iop/pci.c b/arch/arm/plat-iop/pci.c index f4d40a27111e..72768356447a 100644 --- a/arch/arm/plat-iop/pci.c +++ b/arch/arm/plat-iop/pci.c @@ -215,8 +215,8 @@ int iop3xx_pci_setup(int nr, struct pci_sys_data *sys) sys->mem_offset = IOP3XX_PCI_LOWER_MEM_PA - *IOP3XX_OMWTVR0; sys->io_offset = IOP3XX_PCI_LOWER_IO_PA - *IOP3XX_OIOWTVR; - pci_add_resource(&sys->resources, &res[0]); - pci_add_resource(&sys->resources, &res[1]); + pci_add_resource_offset(&sys->resources, &res[0], sys->io_offset); + pci_add_resource_offset(&sys->resources, &res[1], sys->mem_offset); return 1; } diff --git a/arch/ia64/include/asm/pci.h b/arch/ia64/include/asm/pci.h index 279b38ae74aa..b22e5f5fa593 100644 --- a/arch/ia64/include/asm/pci.h +++ b/arch/ia64/include/asm/pci.h @@ -108,12 +108,6 @@ static inline int pci_proc_domain(struct pci_bus *bus) return (pci_domain_nr(bus) != 0); } -extern void pcibios_resource_to_bus(struct pci_dev *dev, - struct pci_bus_region *region, struct resource *res); - -extern void pcibios_bus_to_resource(struct pci_dev *dev, - struct resource *res, struct pci_bus_region *region); - static inline struct resource * pcibios_select_root(struct pci_dev *pdev, struct resource *res) { diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index f82f5d4b65fd..d1ce3200147c 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c @@ -320,7 +320,8 @@ static __devinit acpi_status add_window(struct acpi_resource *res, void *data) * Ignore these tiny memory ranges */ if (!((window->resource.flags & IORESOURCE_MEM) && (window->resource.end - window->resource.start < 16))) - pci_add_resource(&info->resources, &window->resource); + pci_add_resource_offset(&info->resources, &window->resource, + window->offset); return AE_OK; } @@ -395,54 +396,6 @@ out1: return NULL; } -void pcibios_resource_to_bus(struct pci_dev *dev, - struct pci_bus_region *region, struct resource *res) -{ - struct pci_controller *controller = PCI_CONTROLLER(dev); - unsigned long offset = 0; - int i; - - for (i = 0; i < controller->windows; i++) { - struct pci_window *window = &controller->window[i]; - if (!(window->resource.flags & res->flags)) - continue; - if (window->resource.start > res->start) - continue; - if (window->resource.end < res->end) - continue; - offset = window->offset; - break; - } - - region->start = res->start - offset; - region->end = res->end - offset; -} -EXPORT_SYMBOL(pcibios_resource_to_bus); - -void pcibios_bus_to_resource(struct pci_dev *dev, - struct resource *res, struct pci_bus_region *region) -{ - struct pci_controller *controller = PCI_CONTROLLER(dev); - unsigned long offset = 0; - int i; - - for (i = 0; i < controller->windows; i++) { - struct pci_window *window = &controller->window[i]; - if (!(window->resource.flags & res->flags)) - continue; - if (window->resource.start - window->offset > region->start) - continue; - if (window->resource.end - window->offset < region->end) - continue; - offset = window->offset; - break; - } - - res->start = region->start + offset; - res->end = region->end + offset; -} -EXPORT_SYMBOL(pcibios_bus_to_resource); - static int __devinit is_valid_resource(struct pci_dev *dev, int idx) { unsigned int i, type_mask = IORESOURCE_IO | IORESOURCE_MEM; @@ -464,15 +417,11 @@ static int __devinit is_valid_resource(struct pci_dev *dev, int idx) static void __devinit pcibios_fixup_resources(struct pci_dev *dev, int start, int limit) { - struct pci_bus_region region; int i; for (i = start; i < limit; i++) { if (!dev->resource[i].flags) continue; - region.start = dev->resource[i].start; - region.end = dev->resource[i].end; - pcibios_bus_to_resource(dev, &dev->resource[i], ®ion); if ((is_valid_resource(dev, i))) pci_claim_resource(dev, i); } diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c index 0a36f082eaf1..238e2c511d94 100644 --- a/arch/ia64/sn/kernel/io_init.c +++ b/arch/ia64/sn/kernel/io_init.c @@ -297,7 +297,8 @@ sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus) s64 status = 0; struct pci_controller *controller; struct pcibus_bussoft *prom_bussoft_ptr; - + LIST_HEAD(resources); + int i; status = sal_get_pcibus_info((u64) segment, (u64) busnum, (u64) ia64_tpa(&prom_bussoft_ptr)); @@ -315,7 +316,15 @@ sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus) */ controller->platform_data = prom_bussoft_ptr; - bus = pci_scan_bus(busnum, &pci_root_ops, controller); + sn_legacy_pci_window_fixup(controller, + prom_bussoft_ptr->bs_legacy_io, + prom_bussoft_ptr->bs_legacy_mem); + for (i = 0; i < controller->windows; i++) + pci_add_resource_offset(&resources, + &controller->window[i].resource, + controller->window[i].offset); + bus = pci_scan_root_bus(NULL, busnum, &pci_root_ops, controller, + &resources); if (bus == NULL) goto error_return; /* error, or bus already scanned */ @@ -348,9 +357,6 @@ sn_bus_fixup(struct pci_bus *bus) return; } sn_common_bus_fixup(bus, prom_bussoft_ptr); - sn_legacy_pci_window_fixup(PCI_CONTROLLER(bus), - prom_bussoft_ptr->bs_legacy_io, - prom_bussoft_ptr->bs_legacy_mem); } list_for_each_entry(pci_dev, &bus->devices, bus_list) { sn_io_slot_fixup(pci_dev); diff --git a/arch/microblaze/include/asm/pci-bridge.h b/arch/microblaze/include/asm/pci-bridge.h index e9834b2991d0..cb5d39794800 100644 --- a/arch/microblaze/include/asm/pci-bridge.h +++ b/arch/microblaze/include/asm/pci-bridge.h @@ -10,7 +10,6 @@ #include <linux/pci.h> #include <linux/list.h> #include <linux/ioport.h> -#include <asm-generic/pci-bridge.h> struct device_node; diff --git a/arch/microblaze/include/asm/pci.h b/arch/microblaze/include/asm/pci.h index 033137628e8a..a0da88bf70c5 100644 --- a/arch/microblaze/include/asm/pci.h +++ b/arch/microblaze/include/asm/pci.h @@ -94,14 +94,6 @@ extern int pci_mmap_legacy_page_range(struct pci_bus *bus, */ #define PCI_DMA_BUS_IS_PHYS (1) -extern void pcibios_resource_to_bus(struct pci_dev *dev, - struct pci_bus_region *region, - struct resource *res); - -extern void pcibios_bus_to_resource(struct pci_dev *dev, - struct resource *res, - struct pci_bus_region *region); - static inline struct resource *pcibios_select_root(struct pci_dev *pdev, struct resource *res) { diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c index 85f2ac1230a8..d10403dadd2b 100644 --- a/arch/microblaze/pci/pci-common.c +++ b/arch/microblaze/pci/pci-common.c @@ -46,9 +46,6 @@ static int global_phb_number; /* Global phb counter */ /* ISA Memory physical address */ resource_size_t isa_mem_base; -/* Default PCI flags is 0 on ppc32, modified at boot on ppc64 */ -unsigned int pci_flags; - static struct dma_map_ops *pci_dma_ops = &dma_direct_ops; unsigned long isa_io_base; @@ -833,64 +830,7 @@ int pci_proc_domain(struct pci_bus *bus) { struct pci_controller *hose = pci_bus_to_host(bus); - if (!(pci_flags & PCI_ENABLE_PROC_DOMAINS)) - return 0; - if (pci_flags & PCI_COMPAT_DOMAIN_0) - return hose->global_number != 0; - return 1; -} - -void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, - struct resource *res) -{ - resource_size_t offset = 0, mask = (resource_size_t)-1; - struct pci_controller *hose = pci_bus_to_host(dev->bus); - - if (!hose) - return; - if (res->flags & IORESOURCE_IO) { - offset = (unsigned long)hose->io_base_virt - _IO_BASE; - mask = 0xffffffffu; - } else if (res->flags & IORESOURCE_MEM) - offset = hose->pci_mem_offset; - - region->start = (res->start - offset) & mask; - region->end = (res->end - offset) & mask; -} -EXPORT_SYMBOL(pcibios_resource_to_bus); - -void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, - struct pci_bus_region *region) -{ - resource_size_t offset = 0, mask = (resource_size_t)-1; - struct pci_controller *hose = pci_bus_to_host(dev->bus); - - if (!hose) - return; - if (res->flags & IORESOURCE_IO) { - offset = (unsigned long)hose->io_base_virt - _IO_BASE; - mask = 0xffffffffu; - } else if (res->flags & IORESOURCE_MEM) - offset = hose->pci_mem_offset; - res->start = (region->start + offset) & mask; - res->end = (region->end + offset) & mask; -} -EXPORT_SYMBOL(pcibios_bus_to_resource); - -/* Fixup a bus resource into a linux resource */ -static void __devinit fixup_resource(struct resource *res, struct pci_dev *dev) -{ - struct pci_controller *hose = pci_bus_to_host(dev->bus); - resource_size_t offset = 0, mask = (resource_size_t)-1; - - if (res->flags & IORESOURCE_IO) { - offset = (unsigned long)hose->io_base_virt - _IO_BASE; - mask = 0xffffffffu; - } else if (res->flags & IORESOURCE_MEM) - offset = hose->pci_mem_offset; - - res->start = (res->start + offset) & mask; - res->end = (res->end + offset) & mask; + return 0; } /* This header fixup will do the resource fixup for all devices as they are @@ -910,13 +850,7 @@ static void __devinit pcibios_fixup_resources(struct pci_dev *dev) struct resource *res = dev->resource + i; if (!res->flags) continue; - /* On platforms that have PCI_PROBE_ONLY set, we don't - * consider 0 as an unassigned BAR value. It's technically - * a valid value, but linux doesn't like it... so when we can - * re-assign things, we do so, but if we can't, we keep it - * around and hope for the best... - */ - if (res->start == 0 && !(pci_flags & PCI_PROBE_ONLY)) { + if (res->start == 0) { pr_debug("PCI:%s Resource %d %016llx-%016llx [%x]" \ "is unassigned\n", pci_name(dev), i, @@ -929,18 +863,11 @@ static void __devinit pcibios_fixup_resources(struct pci_dev *dev) continue; } - pr_debug("PCI:%s Resource %d %016llx-%016llx [%x] fixup...\n", + pr_debug("PCI:%s Resource %d %016llx-%016llx [%x]\n", pci_name(dev), i, (unsigned long long)res->start,\ (unsigned long long)res->end, (unsigned int)res->flags); - - fixup_resource(res, dev); - - pr_debug("PCI:%s %016llx-%016llx\n", - pci_name(dev), - (unsigned long long)res->start, - (unsigned long long)res->end); } } DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pcibios_fixup_resources); @@ -959,10 +886,6 @@ static int __devinit pcibios_uninitialized_bridge_resource(struct pci_bus *bus, u16 command; int i; - /* We don't do anything if PCI_PROBE_ONLY is set */ - if (pci_flags & PCI_PROBE_ONLY) - return 0; - /* Job is a bit different between memory and IO */ if (res->flags & IORESOURCE_MEM) { /* If the BAR is non-0 (res != pci_mem_offset) then it's @@ -1037,9 +960,6 @@ static void __devinit pcibios_fixup_bridge(struct pci_bus *bus) (unsigned long long)res->end, (unsigned int)res->flags); - /* Perform fixup */ - fixup_resource(res, dev); - /* Try to detect uninitialized P2P bridge resources, * and clear them out so they get re-assigned later */ @@ -1107,9 +1027,6 @@ EXPORT_SYMBOL(pcibios_fixup_bus); static int skip_isa_ioresource_align(struct pci_dev *dev) { - if ((pci_flags & PCI_CAN_SKIP_ISA_ALIGN) && - !(dev->bus->bridge_ctl & PCI_BRIDGE_CTL_ISA)) - return 1; return 0; } @@ -1236,8 +1153,6 @@ void pcibios_allocate_bus_resources(struct pci_bus *bus) * and as such ensure proper re-allocation * later. */ - if (pci_flags & PCI_REASSIGN_ALL_RSRC) - goto clear_resource; pr = pci_find_parent_resource(bus->self, res); if (pr == res) { /* this happens when the generic PCI @@ -1422,27 +1337,19 @@ void __init pcibios_resource_survey(void) list_for_each_entry(b, &pci_root_buses, node) pcibios_allocate_bus_resources(b); - if (!(pci_flags & PCI_REASSIGN_ALL_RSRC)) { - pcibios_allocate_resources(0); - pcibios_allocate_resources(1); - } + pcibios_allocate_resources(0); + pcibios_allocate_resources(1); /* Before we start assigning unassigned resource, we try to reserve * the low IO area and the VGA memory area if they intersect the * bus available resources to avoid allocating things on top of them */ - if (!(pci_flags & PCI_PROBE_ONLY)) { - list_for_each_entry(b, &pci_root_buses, node) - pcibios_reserve_legacy_regions(b); - } + list_for_each_entry(b, &pci_root_buses, node) + pcibios_reserve_legacy_regions(b); - /* Now, if the platform didn't decide to blindly trust the firmware, - * we proceed to assigning things that were left unassigned - */ - if (!(pci_flags & PCI_PROBE_ONLY)) { - pr_debug("PCI: Assigning unassigned resources...\n"); - pci_assign_unassigned_resources(); - } + /* Now proceed to assigning things that were left unassigned */ + pr_debug("PCI: Assigning unassigned resources...\n"); + pci_assign_unassigned_resources(); } #ifdef CONFIG_HOTPLUG @@ -1535,7 +1442,7 @@ static void __devinit pcibios_setup_phb_resources(struct pci_controller *hose, s res->end = res->start + IO_SPACE_LIMIT; res->flags = IORESOURCE_IO; } - pci_add_resource(resources, res); + pci_add_resource_offset(resources, res, hose->io_base_virt - _IO_BASE); pr_debug("PCI: PHB IO resource = %016llx-%016llx [%lx]\n", (unsigned long long)res->start, @@ -1558,7 +1465,7 @@ static void __devinit pcibios_setup_phb_resources(struct pci_controller *hose, s res->flags = IORESOURCE_MEM; } - pci_add_resource(resources, res); + pci_add_resource_offset(resources, res, hose->pci_mem_offset); pr_debug("PCI: PHB MEM resource %d = %016llx-%016llx [%lx]\n", i, (unsigned long long)res->start, diff --git a/arch/mips/include/asm/pci.h b/arch/mips/include/asm/pci.h index 576397c69920..fcd4060f6421 100644 --- a/arch/mips/include/asm/pci.h +++ b/arch/mips/include/asm/pci.h @@ -92,6 +92,7 @@ extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, #include <asm/scatterlist.h> #include <linux/string.h> #include <asm/io.h> +#include <asm-generic/pci-bridge.h> struct pci_dev; @@ -112,12 +113,6 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev, } #endif -extern void pcibios_resource_to_bus(struct pci_dev *dev, - struct pci_bus_region *region, struct resource *res); - -extern void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, - struct pci_bus_region *region); - #define pci_domain_nr(bus) ((struct pci_controller *)(bus)->sysdata)->index static inline int pci_proc_domain(struct pci_bus *bus) @@ -145,8 +140,6 @@ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel) #define arch_setup_msi_irqs arch_setup_msi_irqs #endif -extern int pci_probe_only; - extern char * (*pcibios_plat_setup)(char *str); #endif /* _ASM_PCI_H */ diff --git a/arch/mips/pci/fixup-cobalt.c b/arch/mips/pci/fixup-cobalt.c index acacd1407c63..9553b14002dd 100644 --- a/arch/mips/pci/fixup-cobalt.c +++ b/arch/mips/pci/fixup-cobalt.c @@ -51,67 +51,6 @@ static void qube_raq_galileo_early_fixup(struct pci_dev *dev) DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_MARVELL, PCI_DEVICE_ID_MARVELL_GT64111, qube_raq_galileo_early_fixup); -static void __devinit cobalt_legacy_ide_resource_fixup(struct pci_dev *dev, - struct resource *res) -{ - struct pci_controller *hose = (struct pci_controller *)dev->sysdata; - unsigned long offset = hose->io_offset; - struct resource orig = *res; - - if (!(res->flags & IORESOURCE_IO) || - !(res->flags & IORESOURCE_PCI_FIXED)) - return; - - res->start -= offset; - res->end -= offset; - dev_printk(KERN_DEBUG, &dev->dev, "converted legacy %pR to bus %pR\n", - &orig, res); -} - -static void __devinit cobalt_legacy_ide_fixup(struct pci_dev *dev) -{ - u32 class; - u8 progif; - - /* - * If the IDE controller is in legacy mode, pci_setup_device() fills in - * the resources with the legacy addresses that normally appear on the - * PCI bus, just as if we had read them from a BAR. - * - * However, with the GT-64111, those legacy addresses, e.g., 0x1f0, - * will never appear on the PCI bus because it converts memory accesses - * in the PCI I/O region (which is never at address zero) into I/O port - * accesses with no address translation. - * - * For example, if GT_DEF_PCI0_IO_BASE is 0x10000000, a load or store - * to physical address 0x100001f0 will become a PCI access to I/O port - * 0x100001f0. There's no way to generate an access to I/O port 0x1f0, - * but the VT82C586 IDE controller does respond at 0x100001f0 because - * it only decodes the low 24 bits of the address. - * - * When this quirk runs, the pci_dev resources should contain bus - * addresses, not Linux I/O port numbers, so convert legacy addresses - * like 0x1f0 to bus addresses like 0x100001f0. Later, we'll convert - * them back with pcibios_fixup_bus() or pcibios_bus_to_resource(). - */ - class = dev->class >> 8; - if (class != PCI_CLASS_STORAGE_IDE) - return; - - pci_read_config_byte(dev, PCI_CLASS_PROG, &progif); - if ((progif & 1) == 0) { - cobalt_legacy_ide_resource_fixup(dev, &dev->resource[0]); - cobalt_legacy_ide_resource_fixup(dev, &dev->resource[1]); - } - if ((progif & 4) == 0) { - cobalt_legacy_ide_resource_fixup(dev, &dev->resource[2]); - cobalt_legacy_ide_resource_fixup(dev, &dev->resource[3]); - } -} - -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, - cobalt_legacy_ide_fixup); - static void qube_raq_via_bmIDE_fixup(struct pci_dev *dev) { unsigned short cfgword; diff --git a/arch/mips/pci/pci-bcm1480.c b/arch/mips/pci/pci-bcm1480.c index af8c31996965..37b52dc3d27e 100644 --- a/arch/mips/pci/pci-bcm1480.c +++ b/arch/mips/pci/pci-bcm1480.c @@ -204,7 +204,7 @@ static int __init bcm1480_pcibios_init(void) uint64_t reg; /* CFE will assign PCI resources */ - pci_probe_only = 1; + pci_set_flags(PCI_PROBE_ONLY); /* Avoid ISA compat ranges. */ PCIBIOS_MIN_IO = 0x00008000UL; diff --git a/arch/mips/pci/pci-ip27.c b/arch/mips/pci/pci-ip27.c index 193e9494f98e..0fbe4c0c170a 100644 --- a/arch/mips/pci/pci-ip27.c +++ b/arch/mips/pci/pci-ip27.c @@ -50,7 +50,7 @@ int __cpuinit bridge_probe(nasid_t nasid, int widget_id, int masterwid) bridge_t *bridge; int slot; - pci_probe_only = 1; + pci_set_flags(PCI_PROBE_ONLY); printk("a bridge\n"); diff --git a/arch/mips/pci/pci-lantiq.c b/arch/mips/pci/pci-lantiq.c index be1e1afe12c3..030c77e7926e 100644 --- a/arch/mips/pci/pci-lantiq.c +++ b/arch/mips/pci/pci-lantiq.c @@ -270,7 +270,8 @@ static int __devinit ltq_pci_probe(struct platform_device *pdev) { struct ltq_pci_data *ltq_pci_data = (struct ltq_pci_data *) pdev->dev.platform_data; - pci_probe_only = 0; + + pci_clear_flags(PCI_PROBE_ONLY); ltq_pci_irq_map = ltq_pci_data->irq; ltq_pci_membase = ioremap_nocache(PCI_CR_BASE_ADDR, PCI_CR_SIZE); ltq_pci_mapped_cfg = diff --git a/arch/mips/pci/pci-sb1250.c b/arch/mips/pci/pci-sb1250.c index 1711e8e101bc..dd97f3a83baa 100644 --- a/arch/mips/pci/pci-sb1250.c +++ b/arch/mips/pci/pci-sb1250.c @@ -213,7 +213,7 @@ static int __init sb1250_pcibios_init(void) uint64_t reg; /* CFE will assign PCI resources */ - pci_probe_only = 1; + pci_set_flags(PCI_PROBE_ONLY); /* Avoid ISA compat ranges. */ PCIBIOS_MIN_IO = 0x00008000UL; diff --git a/arch/mips/pci/pci-xlr.c b/arch/mips/pci/pci-xlr.c index 3d701a962ef4..1644805a6730 100644 --- a/arch/mips/pci/pci-xlr.c +++ b/arch/mips/pci/pci-xlr.c @@ -292,7 +292,7 @@ int pcibios_plat_dev_init(struct pci_dev *dev) static int __init pcibios_init(void) { /* PSB assigns PCI resources */ - pci_probe_only = 1; + pci_set_flags(PCI_PROBE_ONLY); pci_config_base = ioremap(DEFAULT_PCI_CONFIG_BASE, 16 << 20); /* Extend IO port for memory mapped io */ diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c index 15521505ebe8..0514866fa925 100644 --- a/arch/mips/pci/pci.c +++ b/arch/mips/pci/pci.c @@ -20,16 +20,9 @@ #include <asm/cpu-info.h> /* - * Indicate whether we respect the PCI setup left by the firmware. - * - * Make this long-lived so that we know when shutting down - * whether we probed only or not. + * If PCI_PROBE_ONLY in pci_flags is set, we don't change any PCI resource + * assignments. */ -int pci_probe_only; - -#define PCI_ASSIGN_ALL_BUSSES 1 - -unsigned int pci_probe = PCI_ASSIGN_ALL_BUSSES; /* * The PCI controller list. @@ -92,11 +85,12 @@ static void __devinit pcibios_scanbus(struct pci_controller *hose) if (!hose->iommu) PCI_DMA_BUS_IS_PHYS = 1; - if (hose->get_busno && pci_probe_only) + if (hose->get_busno && pci_has_flag(PCI_PROBE_ONLY)) next_busno = (*hose->get_busno)(); - pci_add_resource(&resources, hose->mem_resource); - pci_add_resource(&resources, hose->io_resource); + pci_add_resource_offset(&resources, + hose->mem_resource, hose->mem_offset); + pci_add_resource_offset(&resources, hose->io_resource, hose->io_offset); bus = pci_scan_root_bus(NULL, next_busno, hose->pci_ops, hose, &resources); if (!bus) @@ -115,7 +109,7 @@ static void __devinit pcibios_scanbus(struct pci_controller *hose) need_domain_info = 1; } - if (!pci_probe_only) { + if (!pci_has_flag(PCI_PROBE_ONLY)) { pci_bus_size_bridges(bus); pci_bus_assign_resources(bus); pci_enable_bridges(bus); @@ -241,7 +235,7 @@ static int pcibios_enable_resources(struct pci_dev *dev, int mask) unsigned int pcibios_assign_all_busses(void) { - return (pci_probe & PCI_ASSIGN_ALL_BUSSES) ? 1 : 0; + return 1; } int pcibios_enable_device(struct pci_dev *dev, int mask) @@ -254,42 +248,13 @@ int pcibios_enable_device(struct pci_dev *dev, int mask) return pcibios_plat_dev_init(dev); } -static void pcibios_fixup_device_resources(struct pci_dev *dev, - struct pci_bus *bus) -{ - /* Update device resources. */ - struct pci_controller *hose = (struct pci_controller *)bus->sysdata; - unsigned long offset = 0; - int i; - - for (i = 0; i < PCI_NUM_RESOURCES; i++) { - if (!dev->resource[i].start) - continue; - if (dev->resource[i].flags & IORESOURCE_IO) - offset = hose->io_offset; - else if (dev->resource[i].flags & IORESOURCE_MEM) - offset = hose->mem_offset; - - dev->resource[i].start += offset; - dev->resource[i].end += offset; - } -} - void __devinit pcibios_fixup_bus(struct pci_bus *bus) { - /* Propagate hose info into the subordinate devices. */ - struct pci_dev *dev = bus->self; - if (pci_probe_only && dev && + if (pci_has_flag(PCI_PROBE_ONLY) && dev && (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) { pci_read_bridge_bases(bus); - pcibios_fixup_device_resources(dev, bus); - } - - list_for_each_entry(dev, &bus->devices, bus_list) { - if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI) - pcibios_fixup_device_resources(dev, bus); } } @@ -299,40 +264,7 @@ pcibios_update_irq(struct pci_dev *dev, int irq) pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); } -void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, - struct resource *res) -{ - struct pci_controller *hose = (struct pci_controller *)dev->sysdata; - unsigned long offset = 0; - - if (res->flags & IORESOURCE_IO) - offset = hose->io_offset; - else if (res->flags & IORESOURCE_MEM) - offset = hose->mem_offset; - - region->start = res->start - offset; - region->end = res->end - offset; -} - -void __devinit -pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, - struct pci_bus_region *region) -{ - struct pci_controller *hose = (struct pci_controller *)dev->sysdata; - unsigned long offset = 0; - - if (res->flags & IORESOURCE_IO) - offset = hose->io_offset; - else if (res->flags & IORESOURCE_MEM) - offset = hose->mem_offset; - - res->start = region->start + offset; - res->end = region->end + offset; -} - #ifdef CONFIG_HOTPLUG -EXPORT_SYMBOL(pcibios_resource_to_bus); -EXPORT_SYMBOL(pcibios_bus_to_resource); EXPORT_SYMBOL(PCIBIOS_MIN_IO); EXPORT_SYMBOL(PCIBIOS_MIN_MEM); #endif diff --git a/arch/mn10300/include/asm/pci.h b/arch/mn10300/include/asm/pci.h index 6095a28561dd..8137c25c4e15 100644 --- a/arch/mn10300/include/asm/pci.h +++ b/arch/mn10300/include/asm/pci.h @@ -85,22 +85,6 @@ extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, /* implement the pci_ DMA API in terms of the generic device dma_ one */ #include <asm-generic/pci-dma-compat.h> -/** - * pcibios_resource_to_bus - convert resource to PCI bus address - * @dev: device which owns this resource - * @region: converted bus-centric region (start,end) - * @res: resource to convert - * - * Convert a resource to a PCI device bus address or bus window. - */ -extern void pcibios_resource_to_bus(struct pci_dev *dev, - struct pci_bus_region *region, - struct resource *res); - -extern void pcibios_bus_to_resource(struct pci_dev *dev, - struct resource *res, - struct pci_bus_region *region); - static inline struct resource * pcibios_select_root(struct pci_dev *pdev, struct resource *res) { diff --git a/arch/mn10300/unit-asb2305/pci.c b/arch/mn10300/unit-asb2305/pci.c index a7c5f08ca9f5..6dce9fc2cf3c 100644 --- a/arch/mn10300/unit-asb2305/pci.c +++ b/arch/mn10300/unit-asb2305/pci.c @@ -32,8 +32,7 @@ struct pci_ops *pci_root_ops; * insert specific PCI bus resources instead of using the platform-level bus * resources directly for the PCI root bus. * - * These are configured and inserted by pcibios_init() and are attached to the - * root bus by pcibios_fixup_bus(). + * These are configured and inserted by pcibios_init(). */ static struct resource pci_ioport_resource = { .name = "PCI IO", @@ -78,52 +77,6 @@ static inline int __query(const struct pci_bus *bus, unsigned int devfn) } /* - * translate Linuxcentric addresses to PCI bus addresses - */ -void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, - struct resource *res) -{ - if (res->flags & IORESOURCE_IO) { - region->start = (res->start & 0x00ffffff); - region->end = (res->end & 0x00ffffff); - } - - if (res->flags & IORESOURCE_MEM) { - region->start = (res->start & 0x03ffffff) | MEM_PAGING_REG; - region->end = (res->end & 0x03ffffff) | MEM_PAGING_REG; - } - -#if 0 - printk(KERN_DEBUG "RES->BUS: %lx-%lx => %lx-%lx\n", - res->start, res->end, region->start, region->end); -#endif -} -EXPORT_SYMBOL(pcibios_resource_to_bus); - -/* - * translate PCI bus addresses to Linuxcentric addresses - */ -void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, - struct pci_bus_region *region) -{ - if (res->flags & IORESOURCE_IO) { - res->start = (region->start & 0x00ffffff) | 0xbe000000; - res->end = (region->end & 0x00ffffff) | 0xbe000000; - } - - if (res->flags & IORESOURCE_MEM) { - res->start = (region->start & 0x03ffffff) | 0xb8000000; - res->end = (region->end & 0x03ffffff) | 0xb8000000; - } - -#if 0 - printk(KERN_INFO "BUS->RES: %lx-%lx => %lx-%lx\n", - region->start, region->end, res->start, res->end); -#endif -} -EXPORT_SYMBOL(pcibios_bus_to_resource); - -/* * */ static int pci_ampci_read_config_byte(struct pci_bus *bus, unsigned int devfn, @@ -364,9 +317,6 @@ static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev) if (!dev->resource[i].flags) continue; - region.start = dev->resource[i].start; - region.end = dev->resource[i].end; - pcibios_bus_to_resource(dev, &dev->resource[i], ®ion); if (is_valid_resource(dev, i)) pci_claim_resource(dev, i); } @@ -397,6 +347,7 @@ void __devinit pcibios_fixup_bus(struct pci_bus *bus) */ static int __init pcibios_init(void) { + resource_size_t io_offset, mem_offset; LIST_HEAD(resources); ioport_resource.start = 0xA0000000; @@ -420,8 +371,13 @@ static int __init pcibios_init(void) printk(KERN_INFO "PCI: Probing PCI hardware [mempage %08x]\n", MEM_PAGING_REG); - pci_add_resource(&resources, &pci_ioport_resource); - pci_add_resource(&resources, &pci_iomem_resource); + io_offset = pci_ioport_resource.start - + (pci_ioport_resource.start & 0x00ffffff); + mem_offset = pci_iomem_resource.start - + ((pci_iomem_resource.start & 0x03ffffff) | MEM_PAGING_REG); + + pci_add_resource_offset(&resources, &pci_ioport_resource, io_offset); + pci_add_resource_offset(&resources, &pci_iomem_resource, mem_offset); pci_root_bus = pci_scan_root_bus(NULL, 0, &pci_direct_ampci, NULL, &resources); diff --git a/arch/parisc/include/asm/pci.h b/arch/parisc/include/asm/pci.h index 2242a5c636c2..3234f492d575 100644 --- a/arch/parisc/include/asm/pci.h +++ b/arch/parisc/include/asm/pci.h @@ -82,38 +82,8 @@ struct pci_hba_data { #ifdef CONFIG_64BIT #define PCI_F_EXTEND 0xffffffff00000000UL -#define PCI_IS_LMMIO(hba,a) pci_is_lmmio(hba,a) - -/* We need to know if an address is LMMMIO or GMMIO. - * LMMIO requires mangling and GMMIO we must use as-is. - */ -static __inline__ int pci_is_lmmio(struct pci_hba_data *hba, unsigned long a) -{ - return(((a) & PCI_F_EXTEND) == PCI_F_EXTEND); -} - -/* -** Convert between PCI (IO_VIEW) addresses and processor (PA_VIEW) addresses. -** See pci.c for more conversions used by Generic PCI code. -** -** Platform characteristics/firmware guarantee that -** (1) PA_VIEW - IO_VIEW = lmmio_offset for both LMMIO and ELMMIO -** (2) PA_VIEW == IO_VIEW for GMMIO -*/ -#define PCI_BUS_ADDR(hba,a) (PCI_IS_LMMIO(hba,a) \ - ? ((a) - hba->lmmio_space_offset) /* mangle LMMIO */ \ - : (a)) /* GMMIO */ -#define PCI_HOST_ADDR(hba,a) (((a) & PCI_F_EXTEND) == 0 \ - ? (a) + hba->lmmio_space_offset \ - : (a)) - #else /* !CONFIG_64BIT */ - -#define PCI_BUS_ADDR(hba,a) (a) -#define PCI_HOST_ADDR(hba,a) (a) #define PCI_F_EXTEND 0UL -#define PCI_IS_LMMIO(hba,a) (1) /* 32-bit doesn't support GMMIO */ - #endif /* !CONFIG_64BIT */ /* @@ -245,14 +215,6 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev, } #endif -extern void -pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, - struct resource *res); - -extern void -pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, - struct pci_bus_region *region); - static inline void pcibios_penalize_isa_irq(int irq, int active) { /* We don't need to penalize isa irq's */ diff --git a/arch/parisc/kernel/pci.c b/arch/parisc/kernel/pci.c index 9efd97405317..74d544b1cd22 100644 --- a/arch/parisc/kernel/pci.c +++ b/arch/parisc/kernel/pci.c @@ -195,58 +195,6 @@ void __init pcibios_init_bus(struct pci_bus *bus) pci_write_config_word(dev, PCI_BRIDGE_CONTROL, bridge_ctl); } -/* called by drivers/pci/setup-bus.c:pci_setup_bridge(). */ -void __devinit pcibios_resource_to_bus(struct pci_dev *dev, - struct pci_bus_region *region, struct resource *res) -{ -#ifdef CONFIG_64BIT - struct pci_hba_data *hba = HBA_DATA(dev->bus->bridge->platform_data); -#endif - - if (res->flags & IORESOURCE_IO) { - /* - ** I/O space may see busnumbers here. Something - ** in the form of 0xbbxxxx where bb is the bus num - ** and xxxx is the I/O port space address. - ** Remaining address translation are done in the - ** PCI Host adapter specific code - ie dino_out8. - */ - region->start = PCI_PORT_ADDR(res->start); - region->end = PCI_PORT_ADDR(res->end); - } else if (res->flags & IORESOURCE_MEM) { - /* Convert MMIO addr to PCI addr (undo global virtualization) */ - region->start = PCI_BUS_ADDR(hba, res->start); - region->end = PCI_BUS_ADDR(hba, res->end); - } - - DBG_RES("pcibios_resource_to_bus(%02x %s [%lx,%lx])\n", - dev->bus->number, res->flags & IORESOURCE_IO ? "IO" : "MEM", - region->start, region->end); -} - -void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, - struct pci_bus_region *region) -{ -#ifdef CONFIG_64BIT - struct pci_hba_data *hba = HBA_DATA(dev->bus->bridge->platform_data); -#endif - - if (res->flags & IORESOURCE_MEM) { - res->start = PCI_HOST_ADDR(hba, region->start); - res->end = PCI_HOST_ADDR(hba, region->end); - } - - if (res->flags & IORESOURCE_IO) { - res->start = region->start; - res->end = region->end; - } -} - -#ifdef CONFIG_HOTPLUG -EXPORT_SYMBOL(pcibios_resource_to_bus); -EXPORT_SYMBOL(pcibios_bus_to_resource); -#endif - /* * pcibios align resources() is called every time generic PCI code * wants to generate a new address. The process of looking for diff --git a/arch/powerpc/include/asm/pci.h b/arch/powerpc/include/asm/pci.h index f54b3d26ce9d..6653f2743c4e 100644 --- a/arch/powerpc/include/asm/pci.h +++ b/arch/powerpc/include/asm/pci.h @@ -154,14 +154,6 @@ extern int pci_mmap_legacy_page_range(struct pci_bus *bus, #endif /* CONFIG_PPC64 */ -extern void pcibios_resource_to_bus(struct pci_dev *dev, - struct pci_bus_region *region, - struct resource *res); - -extern void pcibios_bus_to_resource(struct pci_dev *dev, - struct resource *res, - struct pci_bus_region *region); - extern void pcibios_claim_one_bus(struct pci_bus *b); extern void pcibios_finish_adding_to_bus(struct pci_bus *bus); @@ -190,6 +182,7 @@ extern void pci_resource_to_user(const struct pci_dev *dev, int bar, const struct resource *rsrc, resource_size_t *start, resource_size_t *end); +extern resource_size_t pcibios_io_space_offset(struct pci_controller *hose); extern void pcibios_setup_bus_devices(struct pci_bus *bus); extern void pcibios_setup_bus_self(struct pci_bus *bus); extern void pcibios_setup_phb_io_space(struct pci_controller *hose); diff --git a/arch/powerpc/include/asm/ppc-pci.h b/arch/powerpc/include/asm/ppc-pci.h index e660b37aa7d0..80fa704d410f 100644 --- a/arch/powerpc/include/asm/ppc-pci.h +++ b/arch/powerpc/include/asm/ppc-pci.h @@ -45,8 +45,6 @@ extern void init_pci_config_tokens (void); extern unsigned long get_phb_buid (struct device_node *); extern int rtas_setup_phb(struct pci_controller *phb); -extern unsigned long pci_probe_only; - #ifdef CONFIG_EEH void pci_addr_cache_build(void); diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index d0373bcb7c9d..8e78e93c8185 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c @@ -49,9 +49,6 @@ static int global_phb_number; /* Global phb counter */ /* ISA Memory physical address */ resource_size_t isa_mem_base; -/* Default PCI flags is 0 on ppc32, modified at boot on ppc64 */ -unsigned int pci_flags = 0; - static struct dma_map_ops *pci_dma_ops = &dma_direct_ops; @@ -834,60 +831,6 @@ int pci_proc_domain(struct pci_bus *bus) return 1; } -void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, - struct resource *res) -{ - resource_size_t offset = 0, mask = (resource_size_t)-1; - struct pci_controller *hose = pci_bus_to_host(dev->bus); - - if (!hose) - return; - if (res->flags & IORESOURCE_IO) { - offset = (unsigned long)hose->io_base_virt - _IO_BASE; - mask = 0xffffffffu; - } else if (res->flags & IORESOURCE_MEM) - offset = hose->pci_mem_offset; - - region->start = (res->start - offset) & mask; - region->end = (res->end - offset) & mask; -} -EXPORT_SYMBOL(pcibios_resource_to_bus); - -void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, - struct pci_bus_region *region) -{ - resource_size_t offset = 0, mask = (resource_size_t)-1; - struct pci_controller *hose = pci_bus_to_host(dev->bus); - - if (!hose) - return; - if (res->flags & IORESOURCE_IO) { - offset = (unsigned long)hose->io_base_virt - _IO_BASE; - mask = 0xffffffffu; - } else if (res->flags & IORESOURCE_MEM) - offset = hose->pci_mem_offset; - res->start = (region->start + offset) & mask; - res->end = (region->end + offset) & mask; -} -EXPORT_SYMBOL(pcibios_bus_to_resource); - -/* Fixup a bus resource into a linux resource */ -static void __devinit fixup_resource(struct resource *res, struct pci_dev *dev) -{ - struct pci_controller *hose = pci_bus_to_host(dev->bus); - resource_size_t offset = 0, mask = (resource_size_t)-1; - - if (res->flags & IORESOURCE_IO) { - offset = (unsigned long)hose->io_base_virt - _IO_BASE; - mask = 0xffffffffu; - } else if (res->flags & IORESOURCE_MEM) - offset = hose->pci_mem_offset; - - res->start = (res->start + offset) & mask; - res->end = (res->end + offset) & mask; -} - - /* This header fixup will do the resource fixup for all devices as they are * probed, but not for bridge ranges */ @@ -927,18 +870,11 @@ static void __devinit pcibios_fixup_resources(struct pci_dev *dev) continue; } - pr_debug("PCI:%s Resource %d %016llx-%016llx [%x] fixup...\n", + pr_debug("PCI:%s Resource %d %016llx-%016llx [%x]\n", pci_name(dev), i, (unsigned long long)res->start,\ (unsigned long long)res->end, (unsigned int)res->flags); - - fixup_resource(res, dev); - - pr_debug("PCI:%s %016llx-%016llx\n", - pci_name(dev), - (unsigned long long)res->start, - (unsigned long long)res->end); } /* Call machine specific resource fixup */ @@ -1040,27 +976,18 @@ static void __devinit pcibios_fixup_bridge(struct pci_bus *bus) continue; } - pr_debug("PCI:%s Bus rsrc %d %016llx-%016llx [%x] fixup...\n", + pr_debug("PCI:%s Bus rsrc %d %016llx-%016llx [%x]\n", pci_name(dev), i, (unsigned long long)res->start,\ (unsigned long long)res->end, (unsigned int)res->flags); - /* Perform fixup */ - fixup_resource(res, dev); - /* Try to detect uninitialized P2P bridge resources, * and clear them out so they get re-assigned later */ if (pcibios_uninitialized_bridge_resource(bus, res)) { res->flags = 0; pr_debug("PCI:%s (unassigned)\n", pci_name(dev)); - } else { - - pr_debug("PCI:%s %016llx-%016llx\n", - pci_name(dev), - (unsigned long long)res->start, - (unsigned long long)res->end); } } } @@ -1550,6 +1477,11 @@ int pcibios_enable_device(struct pci_dev *dev, int mask) return pci_enable_resources(dev, mask); } +resource_size_t pcibios_io_space_offset(struct pci_controller *hose) +{ + return (unsigned long) hose->io_base_virt - _IO_BASE; +} + static void __devinit pcibios_setup_phb_resources(struct pci_controller *hose, struct list_head *resources) { struct resource *res; @@ -1574,7 +1506,7 @@ static void __devinit pcibios_setup_phb_resources(struct pci_controller *hose, s (unsigned long long)res->start, (unsigned long long)res->end, (unsigned long)res->flags); - pci_add_resource(resources, res); + pci_add_resource_offset(resources, res, pcibios_io_space_offset(hose)); /* Hookup PHB Memory resources */ for (i = 0; i < 3; ++i) { @@ -1597,7 +1529,7 @@ static void __devinit pcibios_setup_phb_resources(struct pci_controller *hose, s (unsigned long long)res->start, (unsigned long long)res->end, (unsigned long)res->flags); - pci_add_resource(resources, res); + pci_add_resource_offset(resources, res, hose->pci_mem_offset); } pr_debug("PCI: PHB MEM offset = %016llx\n", diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c index fdd1a3d951dc..4b06ec5a502e 100644 --- a/arch/powerpc/kernel/pci_32.c +++ b/arch/powerpc/kernel/pci_32.c @@ -219,9 +219,9 @@ void __devinit pcibios_setup_phb_io_space(struct pci_controller *hose) struct resource *res = &hose->io_resource; /* Fixup IO space offset */ - io_offset = (unsigned long)hose->io_base_virt - isa_io_base; - res->start = (res->start + io_offset) & 0xffffffffu; - res->end = (res->end + io_offset) & 0xffffffffu; + io_offset = pcibios_io_space_offset(hose); + res->start += io_offset; + res->end += io_offset; } static int __init pcibios_init(void) diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c index 3318d39b7d4c..94a54f61d341 100644 --- a/arch/powerpc/kernel/pci_64.c +++ b/arch/powerpc/kernel/pci_64.c @@ -33,8 +33,6 @@ #include <asm/machdep.h> #include <asm/ppc-pci.h> -unsigned long pci_probe_only = 1; - /* pci_io_base -- the base address from which io bars are offsets. * This is the lowest I/O base address (so bar values are always positive), * and it *must* be the start of ISA space if an ISA bus exists because @@ -55,9 +53,6 @@ static int __init pcibios_init(void) */ ppc_md.phys_mem_access_prot = pci_phys_mem_access_prot; - if (pci_probe_only) - pci_add_flags(PCI_PROBE_ONLY); - /* On ppc64, we always enable PCI domains and we keep domain 0 * backward compatible in /proc for video cards */ @@ -173,7 +168,7 @@ static int __devinit pcibios_map_phb_io_space(struct pci_controller *hose) return -ENOMEM; /* Fixup hose IO resource */ - io_virt_offset = (unsigned long)hose->io_base_virt - _IO_BASE; + io_virt_offset = pcibios_io_space_offset(hose); hose->io_resource.start += io_virt_offset; hose->io_resource.end += io_virt_offset; diff --git a/arch/powerpc/kernel/pci_of_scan.c b/arch/powerpc/kernel/pci_of_scan.c index b37d0b5a796e..89dde171a6fa 100644 --- a/arch/powerpc/kernel/pci_of_scan.c +++ b/arch/powerpc/kernel/pci_of_scan.c @@ -75,6 +75,7 @@ static void of_pci_parse_addrs(struct device_node *node, struct pci_dev *dev) { u64 base, size; unsigned int flags; + struct pci_bus_region region; struct resource *res; const u32 *addrs; u32 i; @@ -106,10 +107,11 @@ static void of_pci_parse_addrs(struct device_node *node, struct pci_dev *dev) printk(KERN_ERR "PCI: bad cfg reg num 0x%x\n", i); continue; } - res->start = base; - res->end = base + size - 1; res->flags = flags; res->name = pci_name(dev); + region.start = base; + region.end = base + size - 1; + pcibios_bus_to_resource(dev, res, ®ion); } } @@ -209,6 +211,7 @@ void __devinit of_scan_pci_bridge(struct pci_dev *dev) struct pci_bus *bus; const u32 *busrange, *ranges; int len, i, mode; + struct pci_bus_region region; struct resource *res; unsigned int flags; u64 size; @@ -270,9 +273,10 @@ void __devinit of_scan_pci_bridge(struct pci_dev *dev) res = bus->resource[i]; ++i; } - res->start = of_read_number(&ranges[1], 2); - res->end = res->start + size - 1; res->flags = flags; + region.start = of_read_number(&ranges[1], 2); + region.end = region.start + size - 1; + pcibios_bus_to_resource(dev, res, ®ion); } sprintf(bus->name, "PCI Bus %04x:%02x", pci_domain_nr(bus), bus->number); diff --git a/arch/powerpc/kernel/rtas_pci.c b/arch/powerpc/kernel/rtas_pci.c index 517bd86bc3f0..179af906dcda 100644 --- a/arch/powerpc/kernel/rtas_pci.c +++ b/arch/powerpc/kernel/rtas_pci.c @@ -279,7 +279,7 @@ void __init find_and_init_phbs(void) eeh_dev_phb_init(); /* - * pci_probe_only and pci_assign_all_buses can be set via properties + * PCI_PROBE_ONLY and PCI_REASSIGN_ALL_BUS can be set via properties * in chosen. */ if (of_chosen) { @@ -287,8 +287,12 @@ void __init find_and_init_phbs(void) prop = of_get_property(of_chosen, "linux,pci-probe-only", NULL); - if (prop) - pci_probe_only = *prop; + if (prop) { + if (*prop) + pci_add_flags(PCI_PROBE_ONLY); + else + pci_clear_flags(PCI_PROBE_ONLY); + } #ifdef CONFIG_PPC32 /* Will be made generic soon */ prop = of_get_property(of_chosen, diff --git a/arch/powerpc/platforms/maple/pci.c b/arch/powerpc/platforms/maple/pci.c index 401e3f3f74c8..465ee8f5c086 100644 --- a/arch/powerpc/platforms/maple/pci.c +++ b/arch/powerpc/platforms/maple/pci.c @@ -620,7 +620,7 @@ void __init maple_pci_init(void) } /* Tell pci.c to not change any resource allocations. */ - pci_probe_only = 1; + pci_add_flags(PCI_PROBE_ONLY); } int maple_pci_get_legacy_ide_irq(struct pci_dev *pdev, int channel) diff --git a/arch/powerpc/platforms/pasemi/pci.c b/arch/powerpc/platforms/pasemi/pci.c index b6a0ec45c695..aa862713258c 100644 --- a/arch/powerpc/platforms/pasemi/pci.c +++ b/arch/powerpc/platforms/pasemi/pci.c @@ -229,9 +229,6 @@ void __init pas_pci_init(void) /* Setup the linkage between OF nodes and PHBs */ pci_devs_phb_init(); - - /* Use the common resource allocation mechanism */ - pci_probe_only = 1; } void __iomem *pasemi_pci_getcfgaddr(struct pci_dev *dev, int offset) diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c index 31a7d3a7ce25..43bbe1bda939 100644 --- a/arch/powerpc/platforms/powermac/pci.c +++ b/arch/powerpc/platforms/powermac/pci.c @@ -1059,9 +1059,6 @@ void __init pmac_pci_init(void) } /* pmac_check_ht_link(); */ - /* We can allocate missing resources if any */ - pci_probe_only = 0; - #else /* CONFIG_PPC64 */ init_p2pbridge(); init_second_ohare(); diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index 5e155dfc4320..fbdd74dac3ac 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -1299,15 +1299,14 @@ void __init pnv_pci_init_ioda1_phb(struct device_node *np) /* Setup MSI support */ pnv_pci_init_ioda_msis(phb); - /* We set both probe_only and PCI_REASSIGN_ALL_RSRC. This is an + /* We set both PCI_PROBE_ONLY and PCI_REASSIGN_ALL_RSRC. This is an * odd combination which essentially means that we skip all resource * fixups and assignments in the generic code, and do it all * ourselves here */ - pci_probe_only = 1; ppc_md.pcibios_fixup_phb = pnv_pci_ioda_fixup_phb; ppc_md.pcibios_enable_device_hook = pnv_pci_enable_device_hook; - pci_add_flags(PCI_REASSIGN_ALL_RSRC); + pci_add_flags(PCI_PROBE_ONLY | PCI_REASSIGN_ALL_RSRC); /* Reset IODA tables to a clean state */ rc = opal_pci_reset(phb_id, OPAL_PCI_IODA_TABLE_RESET, OPAL_ASSERT_RESET); diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c index 214478d781ae..be3cfc5ceabb 100644 --- a/arch/powerpc/platforms/powernv/pci.c +++ b/arch/powerpc/platforms/powernv/pci.c @@ -562,10 +562,7 @@ void __init pnv_pci_init(void) { struct device_node *np; - pci_set_flags(PCI_CAN_SKIP_ISA_ALIGN); - - /* We do not want to just probe */ - pci_probe_only = 0; + pci_add_flags(PCI_CAN_SKIP_ISA_ALIGN); /* OPAL absent, try POPAL first then RTAS detection of PHBs */ if (!firmware_has_feature(FW_FEATURE_OPAL)) { diff --git a/arch/powerpc/platforms/pseries/pci_dlpar.c b/arch/powerpc/platforms/pseries/pci_dlpar.c index fbb21fc3080b..8b7bafa489c2 100644 --- a/arch/powerpc/platforms/pseries/pci_dlpar.c +++ b/arch/powerpc/platforms/pseries/pci_dlpar.c @@ -84,7 +84,7 @@ void pcibios_remove_pci_devices(struct pci_bus *bus) list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) { pr_debug(" * Removing %s...\n", pci_name(dev)); eeh_remove_bus_device(dev); - pci_remove_bus_device(dev); + pci_stop_and_remove_bus_device(dev); } } EXPORT_SYMBOL_GPL(pcibios_remove_pci_devices); diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index 8f137af616af..51ecac920dd8 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c @@ -383,6 +383,9 @@ static void __init pSeries_setup_arch(void) fwnmi_init(); + /* By default, only probe PCI (can be overriden by rtas_pci) */ + pci_add_flags(PCI_PROBE_ONLY); + /* Find and initialize PCI host bridges */ init_pci_config_tokens(); eeh_pseries_init(); diff --git a/arch/powerpc/platforms/wsp/wsp_pci.c b/arch/powerpc/platforms/wsp/wsp_pci.c index d24b3acf858e..763014cd1e62 100644 --- a/arch/powerpc/platforms/wsp/wsp_pci.c +++ b/arch/powerpc/platforms/wsp/wsp_pci.c @@ -682,7 +682,6 @@ static int __init wsp_setup_one_phb(struct device_node *np) /* XXX Force re-assigning of everything for now */ pci_add_flags(PCI_REASSIGN_ALL_BUS | PCI_REASSIGN_ALL_RSRC | PCI_ENABLE_PROC_DOMAINS); - pci_probe_only = 0; /* Calculate how the TCE space is divided */ phb->dma32_base = 0; diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c index 1e7b0e2e764d..9d10a3cb8797 100644 --- a/arch/sh/drivers/pci/pci.c +++ b/arch/sh/drivers/pci/pci.c @@ -37,11 +37,20 @@ static void __devinit pcibios_scanbus(struct pci_channel *hose) static int next_busno; static int need_domain_info; LIST_HEAD(resources); + struct resource *res; + resource_size_t offset; int i; struct pci_bus *bus; - for (i = 0; i < hose->nr_resources; i++) - pci_add_resource(&resources, hose->resources + i); + for (i = 0; i < hose->nr_resources; i++) { + res = hose->resources + i; + offset = 0; + if (res->flags & IORESOURCE_IO) + offset = hose->io_offset; + else if (res->flags & IORESOURCE_MEM) + offset = hose->mem_offset; + pci_add_resource_offset(&resources, res, offset); + } bus = pci_scan_root_bus(NULL, next_busno, hose->pci_ops, hose, &resources); @@ -143,42 +152,12 @@ static int __init pcibios_init(void) } subsys_initcall(pcibios_init); -static void pcibios_fixup_device_resources(struct pci_dev *dev, - struct pci_bus *bus) -{ - /* Update device resources. */ - struct pci_channel *hose = bus->sysdata; - unsigned long offset = 0; - int i; - - for (i = 0; i < PCI_NUM_RESOURCES; i++) { - if (!dev->resource[i].start) - continue; - if (dev->resource[i].flags & IORESOURCE_IO) - offset = hose->io_offset; - else if (dev->resource[i].flags & IORESOURCE_MEM) - offset = hose->mem_offset; - - dev->resource[i].start += offset; - dev->resource[i].end += offset; - } -} - /* * Called after each bus is probed, but before its children * are examined. */ void __devinit pcibios_fixup_bus(struct pci_bus *bus) { - struct pci_dev *dev; - struct list_head *ln; - - for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) { - dev = pci_dev_b(ln); - - if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI) - pcibios_fixup_device_resources(dev, bus); - } } /* @@ -208,36 +187,6 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res, return start; } -void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, - struct resource *res) -{ - struct pci_channel *hose = dev->sysdata; - unsigned long offset = 0; - - if (res->flags & IORESOURCE_IO) - offset = hose->io_offset; - else if (res->flags & IORESOURCE_MEM) - offset = hose->mem_offset; - - region->start = res->start - offset; - region->end = res->end - offset; -} - -void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, - struct pci_bus_region *region) -{ - struct pci_channel *hose = dev->sysdata; - unsigned long offset = 0; - - if (res->flags & IORESOURCE_IO) - offset = hose->io_offset; - else if (res->flags & IORESOURCE_MEM) - offset = hose->mem_offset; - - res->start = region->start + offset; - res->end = region->end + offset; -} - int pcibios_enable_device(struct pci_dev *dev, int mask) { return pci_enable_resources(dev, mask); @@ -381,8 +330,6 @@ EXPORT_SYMBOL(pci_iounmap); #endif /* CONFIG_GENERIC_IOMAP */ #ifdef CONFIG_HOTPLUG -EXPORT_SYMBOL(pcibios_resource_to_bus); -EXPORT_SYMBOL(pcibios_bus_to_resource); EXPORT_SYMBOL(PCIBIOS_MIN_IO); EXPORT_SYMBOL(PCIBIOS_MIN_MEM); #endif diff --git a/arch/sh/include/asm/pci.h b/arch/sh/include/asm/pci.h index cb21e2399dc1..bff96c2e7d25 100644 --- a/arch/sh/include/asm/pci.h +++ b/arch/sh/include/asm/pci.h @@ -114,12 +114,6 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev, /* Board-specific fixup routines. */ int pcibios_map_platform_irq(const struct pci_dev *dev, u8 slot, u8 pin); -extern void pcibios_resource_to_bus(struct pci_dev *dev, - struct pci_bus_region *region, struct resource *res); - -extern void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, - struct pci_bus_region *region); - #define pci_domain_nr(bus) ((struct pci_channel *)(bus)->sysdata)->index static inline int pci_proc_domain(struct pci_bus *bus) diff --git a/arch/sparc/include/asm/pci_32.h b/arch/sparc/include/asm/pci_32.h index 6de7f7bf956a..dc503297481f 100644 --- a/arch/sparc/include/asm/pci_32.h +++ b/arch/sparc/include/asm/pci_32.h @@ -52,14 +52,6 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev, * 64Kbytes by the Host controller. */ -extern void -pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, - struct resource *res); - -extern void -pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, - struct pci_bus_region *region); - static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel) { return PCI_IRQ_NONE; diff --git a/arch/sparc/include/asm/pci_64.h b/arch/sparc/include/asm/pci_64.h index 755a4bb6bcd3..1633b718d3bc 100644 --- a/arch/sparc/include/asm/pci_64.h +++ b/arch/sparc/include/asm/pci_64.h @@ -73,14 +73,6 @@ extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, enum pci_mmap_state mmap_state, int write_combine); -extern void -pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, - struct resource *res); - -extern void -pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, - struct pci_bus_region *region); - static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel) { return PCI_IRQ_NONE; diff --git a/arch/sparc/kernel/leon_pci.c b/arch/sparc/kernel/leon_pci.c index c7bec25fdb1c..aba6b958b2a5 100644 --- a/arch/sparc/kernel/leon_pci.c +++ b/arch/sparc/kernel/leon_pci.c @@ -15,14 +15,19 @@ /* The LEON architecture does not rely on a BIOS or bootloader to setup * PCI for us. The Linux generic routines are used to setup resources, - * reset values of confuration-space registers settings ae preseved. + * reset values of configuration-space register settings are preserved. + * + * PCI Memory and Prefetchable Memory is direct-mapped. However I/O Space is + * accessed through a Window which is translated to low 64KB in PCI space, the + * first 4KB is not used so 60KB is available. */ void leon_pci_init(struct platform_device *ofdev, struct leon_pci_info *info) { LIST_HEAD(resources); struct pci_bus *root_bus; - pci_add_resource(&resources, &info->io_space); + pci_add_resource_offset(&resources, &info->io_space, + info->io_space.start - 0x1000); pci_add_resource(&resources, &info->mem_space); root_bus = pci_scan_root_bus(&ofdev->dev, 0, info->ops, info, @@ -38,44 +43,6 @@ void leon_pci_init(struct platform_device *ofdev, struct leon_pci_info *info) } } -/* PCI Memory and Prefetchable Memory is direct-mapped. However I/O Space is - * accessed through a Window which is translated to low 64KB in PCI space, the - * first 4KB is not used so 60KB is available. - * - * This function is used by generic code to translate resource addresses into - * PCI addresses. - */ -void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, - struct resource *res) -{ - struct leon_pci_info *info = dev->bus->sysdata; - - region->start = res->start; - region->end = res->end; - - if (res->flags & IORESOURCE_IO) { - region->start -= (info->io_space.start - 0x1000); - region->end -= (info->io_space.start - 0x1000); - } -} -EXPORT_SYMBOL(pcibios_resource_to_bus); - -/* see pcibios_resource_to_bus() comment */ -void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, - struct pci_bus_region *region) -{ - struct leon_pci_info *info = dev->bus->sysdata; - - res->start = region->start; - res->end = region->end; - - if (res->flags & IORESOURCE_IO) { - res->start += (info->io_space.start - 0x1000); - res->end += (info->io_space.start - 0x1000); - } -} -EXPORT_SYMBOL(pcibios_bus_to_resource); - void __devinit pcibios_fixup_bus(struct pci_bus *pbus) { struct leon_pci_info *info = pbus->sysdata; diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c index bb8bc2e519ac..fdaf21811670 100644 --- a/arch/sparc/kernel/pci.c +++ b/arch/sparc/kernel/pci.c @@ -375,13 +375,6 @@ static void __devinit apb_calc_first_last(u8 map, u32 *first_p, u32 *last_p) *last_p = last; } -static void pci_resource_adjust(struct resource *res, - struct resource *root) -{ - res->start += root->start; - res->end += root->start; -} - /* For PCI bus devices which lack a 'ranges' property we interrogate * the config space values to set the resources, just like the generic * Linux PCI probing code does. @@ -390,7 +383,8 @@ static void __devinit pci_cfg_fake_ranges(struct pci_dev *dev, struct pci_bus *bus, struct pci_pbm_info *pbm) { - struct resource *res; + struct pci_bus_region region; + struct resource *res, res2; u8 io_base_lo, io_limit_lo; u16 mem_base_lo, mem_limit_lo; unsigned long base, limit; @@ -412,11 +406,14 @@ static void __devinit pci_cfg_fake_ranges(struct pci_dev *dev, res = bus->resource[0]; if (base <= limit) { res->flags = (io_base_lo & PCI_IO_RANGE_TYPE_MASK) | IORESOURCE_IO; + res2.flags = res->flags; + region.start = base; + region.end = limit + 0xfff; + pcibios_bus_to_resource(dev, &res2, ®ion); if (!res->start) - res->start = base; + res->start = res2.start; if (!res->end) - res->end = limit + 0xfff; - pci_resource_adjust(res, &pbm->io_space); + res->end = res2.end; } pci_read_config_word(dev, PCI_MEMORY_BASE, &mem_base_lo); @@ -428,9 +425,9 @@ static void __devinit pci_cfg_fake_ranges(struct pci_dev *dev, if (base <= limit) { res->flags = ((mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM); - res->start = base; - res->end = limit + 0xfffff; - pci_resource_adjust(res, &pbm->mem_space); + region.start = base; + region.end = limit + 0xfffff; + pcibios_bus_to_resource(dev, res, ®ion); } pci_read_config_word(dev, PCI_PREF_MEMORY_BASE, &mem_base_lo); @@ -459,9 +456,9 @@ static void __devinit pci_cfg_fake_ranges(struct pci_dev *dev, if (base <= limit) { res->flags = ((mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM | IORESOURCE_PREFETCH); - res->start = base; - res->end = limit + 0xfffff; - pci_resource_adjust(res, &pbm->mem_space); + region.start = base; + region.end = limit + 0xfffff; + pcibios_bus_to_resource(dev, res, ®ion); } } @@ -472,6 +469,7 @@ static void __devinit apb_fake_ranges(struct pci_dev *dev, struct pci_bus *bus, struct pci_pbm_info *pbm) { + struct pci_bus_region region; struct resource *res; u32 first, last; u8 map; @@ -479,18 +477,18 @@ static void __devinit apb_fake_ranges(struct pci_dev *dev, pci_read_config_byte(dev, APB_IO_ADDRESS_MAP, &map); apb_calc_first_last(map, &first, &last); res = bus->resource[0]; - res->start = (first << 21); - res->end = (last << 21) + ((1 << 21) - 1); res->flags = IORESOURCE_IO; - pci_resource_adjust(res, &pbm->io_space); + region.start = (first << 21); + region.end = (last << 21) + ((1 << 21) - 1); + pcibios_bus_to_resource(dev, res, ®ion); pci_read_config_byte(dev, APB_MEM_ADDRESS_MAP, &map); apb_calc_first_last(map, &first, &last); res = bus->resource[1]; - res->start = (first << 21); - res->end = (last << 21) + ((1 << 21) - 1); res->flags = IORESOURCE_MEM; - pci_resource_adjust(res, &pbm->mem_space); + region.start = (first << 21); + region.end = (last << 21) + ((1 << 21) - 1); + pcibios_bus_to_resource(dev, res, ®ion); } static void __devinit pci_of_scan_bus(struct pci_pbm_info *pbm, @@ -506,6 +504,7 @@ static void __devinit of_scan_pci_bridge(struct pci_pbm_info *pbm, struct pci_bus *bus; const u32 *busrange, *ranges; int len, i, simba; + struct pci_bus_region region; struct resource *res; unsigned int flags; u64 size; @@ -556,8 +555,6 @@ static void __devinit of_scan_pci_bridge(struct pci_pbm_info *pbm, } i = 1; for (; len >= 32; len -= 32, ranges += 8) { - struct resource *root; - flags = pci_parse_of_flags(ranges[0]); size = GET_64BIT(ranges, 6); if (flags == 0 || size == 0) @@ -569,7 +566,6 @@ static void __devinit of_scan_pci_bridge(struct pci_pbm_info *pbm, " for bridge %s\n", node->full_name); continue; } - root = &pbm->io_space; } else { if (i >= PCI_NUM_RESOURCES - PCI_BRIDGE_RESOURCES) { printk(KERN_ERR "PCI: too many memory ranges" @@ -578,18 +574,12 @@ static void __devinit of_scan_pci_bridge(struct pci_pbm_info *pbm, } res = bus->resource[i]; ++i; - root = &pbm->mem_space; } - res->start = GET_64BIT(ranges, 1); - res->end = res->start + size - 1; res->flags = flags; - - /* Another way to implement this would be to add an of_device - * layer routine that can calculate a resource for a given - * range property value in a PCI device. - */ - pci_resource_adjust(res, root); + region.start = GET_64BIT(ranges, 1); + region.end = region.start + size - 1; + pcibios_bus_to_resource(dev, res, ®ion); } after_ranges: sprintf(bus->name, "PCI Bus %04x:%02x", pci_domain_nr(bus), @@ -691,8 +681,10 @@ struct pci_bus * __devinit pci_scan_one_pbm(struct pci_pbm_info *pbm, printk("PCI: Scanning PBM %s\n", node->full_name); - pci_add_resource(&resources, &pbm->io_space); - pci_add_resource(&resources, &pbm->mem_space); + pci_add_resource_offset(&resources, &pbm->io_space, + pbm->io_space.start); + pci_add_resource_offset(&resources, &pbm->mem_space, + pbm->mem_space.start); bus = pci_create_root_bus(parent, pbm->pci_first_busno, pbm->pci_ops, pbm, &resources); if (!bus) { @@ -755,46 +747,6 @@ int pcibios_enable_device(struct pci_dev *dev, int mask) return 0; } -void pcibios_resource_to_bus(struct pci_dev *pdev, struct pci_bus_region *region, - struct resource *res) -{ - struct pci_pbm_info *pbm = pdev->bus->sysdata; - struct resource zero_res, *root; - - zero_res.start = 0; - zero_res.end = 0; - zero_res.flags = res->flags; - - if (res->flags & IORESOURCE_IO) - root = &pbm->io_space; - else - root = &pbm->mem_space; - - pci_resource_adjust(&zero_res, root); - - region->start = res->start - zero_res.start; - region->end = res->end - zero_res.start; -} -EXPORT_SYMBOL(pcibios_resource_to_bus); - -void pcibios_bus_to_resource(struct pci_dev *pdev, struct resource *res, - struct pci_bus_region *region) -{ - struct pci_pbm_info *pbm = pdev->bus->sysdata; - struct resource *root; - - res->start = region->start; - res->end = region->end; - - if (res->flags & IORESOURCE_IO) - root = &pbm->io_space; - else - root = &pbm->mem_space; - - pci_resource_adjust(res, root); -} -EXPORT_SYMBOL(pcibios_bus_to_resource); - char * __devinit pcibios_setup(char *str) { return str; diff --git a/arch/unicore32/include/asm/pci.h b/arch/unicore32/include/asm/pci.h index dd3867727c35..f5e108f4a151 100644 --- a/arch/unicore32/include/asm/pci.h +++ b/arch/unicore32/include/asm/pci.h @@ -14,6 +14,7 @@ #ifdef __KERNEL__ #include <asm-generic/pci-dma-compat.h> +#include <asm-generic/pci-bridge.h> #include <asm-generic/pci.h> #include <mach/hardware.h> /* for PCIBIOS_MIN_* */ diff --git a/arch/unicore32/kernel/pci.c b/arch/unicore32/kernel/pci.c index a8f07fe10cad..2fc2b1ba825e 100644 --- a/arch/unicore32/kernel/pci.c +++ b/arch/unicore32/kernel/pci.c @@ -21,7 +21,6 @@ #include <linux/io.h> static int debug_pci; -static int use_firmware; #define CONFIG_CMD(bus, devfn, where) \ (0x80000000 | (bus->number << 16) | (devfn << 8) | (where & ~3)) @@ -276,7 +275,7 @@ static int __init pci_common_init(void) pci_fixup_irqs(pci_common_swizzle, pci_puv3_map_irq); - if (!use_firmware) { + if (!pci_has_flag(PCI_PROBE_ONLY)) { /* * Size the bridge windows. */ @@ -303,7 +302,7 @@ char * __devinit pcibios_setup(char *str) debug_pci = 1; return NULL; } else if (!strcmp(str, "firmware")) { - use_firmware = 1; + pci_add_flags(PCI_PROBE_ONLY); return NULL; } return str; diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c index 1c4d769e21ea..28e5e06fcba4 100644 --- a/arch/x86/kernel/pci-dma.c +++ b/arch/x86/kernel/pci-dma.c @@ -262,10 +262,11 @@ rootfs_initcall(pci_iommu_init); static __devinit void via_no_dac(struct pci_dev *dev) { - if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI && forbid_dac == 0) { + if (forbid_dac == 0) { dev_info(&dev->dev, "disabling DAC on VIA PCI bridge\n"); forbid_dac = 1; } } -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_ANY_ID, via_no_dac); +DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_VIA, PCI_ANY_ID, + PCI_CLASS_BRIDGE_PCI, 8, via_no_dac); #endif diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c index 49a5cb55429b..ed2835e148b5 100644 --- a/arch/x86/pci/acpi.c +++ b/arch/x86/pci/acpi.c @@ -416,7 +416,12 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root) kfree(sd); } else { get_current_resources(device, busnum, domain, &resources); - if (list_empty(&resources)) + + /* + * _CRS with no apertures is normal, so only fall back to + * defaults or native bridge info if we're ignoring _CRS. + */ + if (!pci_use_crs) x86_pci_root_bus_resources(busnum, &resources); bus = pci_create_root_bus(NULL, busnum, &pci_root_ops, sd, &resources); diff --git a/arch/x86/pci/fixup.c b/arch/x86/pci/fixup.c index 6dd89555fbfa..d0e6e403b4f6 100644 --- a/arch/x86/pci/fixup.c +++ b/arch/x86/pci/fixup.c @@ -164,11 +164,11 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8367_0, pci_fixup_ */ static void __devinit pci_fixup_transparent_bridge(struct pci_dev *dev) { - if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI && - (dev->device & 0xff00) == 0x2400) + if ((dev->device & 0xff00) == 0x2400) dev->transparent = 1; } -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_fixup_transparent_bridge); +DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, + PCI_CLASS_BRIDGE_PCI, 8, pci_fixup_transparent_bridge); /* * Fixup for C1 Halt Disconnect problem on nForce2 systems. @@ -322,9 +322,6 @@ static void __devinit pci_fixup_video(struct pci_dev *pdev) struct pci_bus *bus; u16 config; - if ((pdev->class >> 8) != PCI_CLASS_DISPLAY_VGA) - return; - /* Is VGA routed to us? */ bus = pdev->bus; while (bus) { @@ -353,7 +350,8 @@ static void __devinit pci_fixup_video(struct pci_dev *pdev) dev_printk(KERN_DEBUG, &pdev->dev, "Boot video device\n"); } } -DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_video); +DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_ANY_ID, PCI_ANY_ID, + PCI_CLASS_DISPLAY_VGA, 8, pci_fixup_video); static const struct dmi_system_id __devinitconst msi_k8t_dmi_table[] = { diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c index 91821a1a0c3a..831971e731f7 100644 --- a/arch/x86/pci/i386.c +++ b/arch/x86/pci/i386.c @@ -39,6 +39,87 @@ #include <asm/io_apic.h> +/* + * This list of dynamic mappings is for temporarily maintaining + * original BIOS BAR addresses for possible reinstatement. + */ +struct pcibios_fwaddrmap { + struct list_head list; + struct pci_dev *dev; + resource_size_t fw_addr[DEVICE_COUNT_RESOURCE]; +}; + +static LIST_HEAD(pcibios_fwaddrmappings); +static DEFINE_SPINLOCK(pcibios_fwaddrmap_lock); + +/* Must be called with 'pcibios_fwaddrmap_lock' lock held. */ +static struct pcibios_fwaddrmap *pcibios_fwaddrmap_lookup(struct pci_dev *dev) +{ + struct pcibios_fwaddrmap *map; + + WARN_ON(!spin_is_locked(&pcibios_fwaddrmap_lock)); + + list_for_each_entry(map, &pcibios_fwaddrmappings, list) + if (map->dev == dev) + return map; + + return NULL; +} + +static void +pcibios_save_fw_addr(struct pci_dev *dev, int idx, resource_size_t fw_addr) +{ + unsigned long flags; + struct pcibios_fwaddrmap *map; + + spin_lock_irqsave(&pcibios_fwaddrmap_lock, flags); + map = pcibios_fwaddrmap_lookup(dev); + if (!map) { + spin_unlock_irqrestore(&pcibios_fwaddrmap_lock, flags); + map = kzalloc(sizeof(*map), GFP_KERNEL); + if (!map) + return; + + map->dev = pci_dev_get(dev); + map->fw_addr[idx] = fw_addr; + INIT_LIST_HEAD(&map->list); + + spin_lock_irqsave(&pcibios_fwaddrmap_lock, flags); + list_add_tail(&map->list, &pcibios_fwaddrmappings); + } else + map->fw_addr[idx] = fw_addr; + spin_unlock_irqrestore(&pcibios_fwaddrmap_lock, flags); +} + +resource_size_t pcibios_retrieve_fw_addr(struct pci_dev *dev, int idx) +{ + unsigned long flags; + struct pcibios_fwaddrmap *map; + resource_size_t fw_addr = 0; + + spin_lock_irqsave(&pcibios_fwaddrmap_lock, flags); + map = pcibios_fwaddrmap_lookup(dev); + if (map) + fw_addr = map->fw_addr[idx]; + spin_unlock_irqrestore(&pcibios_fwaddrmap_lock, flags); + + return fw_addr; +} + +static void pcibios_fw_addr_list_del(void) +{ + unsigned long flags; + struct pcibios_fwaddrmap *entry, *next; + + spin_lock_irqsave(&pcibios_fwaddrmap_lock, flags); + list_for_each_entry_safe(entry, next, &pcibios_fwaddrmappings, list) { + list_del(&entry->list); + pci_dev_put(entry->dev); + kfree(entry); + } + spin_unlock_irqrestore(&pcibios_fwaddrmap_lock, flags); +} + static int skip_isa_ioresource_align(struct pci_dev *dev) { @@ -182,7 +263,8 @@ static void __init pcibios_allocate_resources(int pass) idx, r, disabled, pass); if (pci_claim_resource(dev, idx) < 0) { /* We'll assign a new address later */ - dev->fw_addr[idx] = r->start; + pcibios_save_fw_addr(dev, + idx, r->start); r->end -= r->start; r->start = 0; } @@ -228,6 +310,7 @@ static int __init pcibios_assign_resources(void) } pci_assign_unassigned_resources(); + pcibios_fw_addr_list_del(); return 0; } diff --git a/arch/x86/pci/mrst.c b/arch/x86/pci/mrst.c index cb29191cee58..140942f66b31 100644 --- a/arch/x86/pci/mrst.c +++ b/arch/x86/pci/mrst.c @@ -43,6 +43,8 @@ #define PCI_FIXED_BAR_4_SIZE 0x14 #define PCI_FIXED_BAR_5_SIZE 0x1c +static int pci_soc_mode = 0; + /** * fixed_bar_cap - return the offset of the fixed BAR cap if found * @bus: PCI bus @@ -148,7 +150,9 @@ static bool type1_access_ok(unsigned int bus, unsigned int devfn, int reg) */ if (reg >= 0x100 || reg == PCI_STATUS || reg == PCI_HEADER_TYPE) return 0; - if (bus == 0 && (devfn == PCI_DEVFN(2, 0) || devfn == PCI_DEVFN(0, 0))) + if (bus == 0 && (devfn == PCI_DEVFN(2, 0) + || devfn == PCI_DEVFN(0, 0) + || devfn == PCI_DEVFN(3, 0))) return 1; return 0; /* langwell on others */ } @@ -231,14 +235,43 @@ struct pci_ops pci_mrst_ops = { */ int __init pci_mrst_init(void) { - printk(KERN_INFO "Moorestown platform detected, using MRST PCI ops\n"); + printk(KERN_INFO "Intel MID platform detected, using MID PCI ops\n"); pci_mmcfg_late_init(); pcibios_enable_irq = mrst_pci_irq_enable; pci_root_ops = pci_mrst_ops; + pci_soc_mode = 1; /* Continue with standard init */ return 1; } +/* Langwell devices are not true pci devices, they are not subject to 10 ms + * d3 to d0 delay required by pci spec. + */ +static void __devinit pci_d3delay_fixup(struct pci_dev *dev) +{ + /* PCI fixups are effectively decided compile time. If we have a dual + SoC/non-SoC kernel we don't want to mangle d3 on non SoC devices */ + if (!pci_soc_mode) + return; + /* true pci devices in lincroft should allow type 1 access, the rest + * are langwell fake pci devices. + */ + if (type1_access_ok(dev->bus->number, dev->devfn, PCI_DEVICE_ID)) + return; + dev->d3_delay = 0; +} +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_d3delay_fixup); + +static void __devinit mrst_power_off_unused_dev(struct pci_dev *dev) +{ + pci_set_power_state(dev, PCI_D3cold); +} +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0801, mrst_power_off_unused_dev); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0809, mrst_power_off_unused_dev); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x080C, mrst_power_off_unused_dev); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0812, mrst_power_off_unused_dev); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0815, mrst_power_off_unused_dev); + /* * Langwell devices reside at fixed offsets, don't try to move them. */ @@ -248,6 +281,9 @@ static void __devinit pci_fixed_bar_fixup(struct pci_dev *dev) u32 size; int i; + if (!pci_soc_mode) + return; + /* Must have extended configuration space */ if (dev->cfg_size < PCIE_CAP_OFFSET + 4) return; diff --git a/arch/xtensa/kernel/pci.c b/arch/xtensa/kernel/pci.c index 61045c192e88..eb30e356f5be 100644 --- a/arch/xtensa/kernel/pci.c +++ b/arch/xtensa/kernel/pci.c @@ -153,7 +153,7 @@ static void __init pci_controller_apertures(struct pci_controller *pci_ctrl, } res->start += io_offset; res->end += io_offset; - pci_add_resource(resources, res); + pci_add_resource_offset(resources, res, io_offset); for (i = 0; i < 3; i++) { res = &pci_ctrl->mem_resources[i]; @@ -200,24 +200,9 @@ subsys_initcall(pcibios_init); void __init pcibios_fixup_bus(struct pci_bus *bus) { - struct pci_controller *pci_ctrl = bus->sysdata; - struct resource *res; - unsigned long io_offset; - int i; - - io_offset = (unsigned long)pci_ctrl->io_space.base; if (bus->parent) { /* This is a subordinate bridge */ pci_read_bridge_bases(bus); - - for (i = 0; i < 4; i++) { - if ((res = bus->resource[i]) == NULL || !res->flags) - continue; - if (io_offset && (res->flags & IORESOURCE_IO)) { - res->start += io_offset; - res->end += io_offset; - } - } } } |