diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-24 19:17:07 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-24 19:17:07 -0400 |
commit | 6dd53aa4563a2c69e80a24d2cc68d484b5ea2891 (patch) | |
tree | 0cca9f65984b524527910960d972fc6ef85fac88 /arch | |
parent | f14121ab35912e3d2e57ac9a4ce1f9d4b7baeffb (diff) | |
parent | 63b96f7baeba71966c723912c3f8f0274577f877 (diff) |
Merge tag 'for-3.6' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci
Pull PCI changes from Bjorn Helgaas:
"Host bridge hotplug:
- Add MMCONFIG support for hot-added host bridges (Jiang Liu)
Device hotplug:
- Move fixups from __init to __devinit (Sebastian Andrzej Siewior)
- Call FINAL fixups for hot-added devices, too (Myron Stowe)
- Factor out generic code for P2P bridge hot-add (Yinghai Lu)
- Remove all functions in a slot, not just those with _EJx (Amos
Kong)
Dynamic resource management:
- Track bus number allocation (struct resource tree per domain)
(Yinghai Lu)
- Make P2P bridge 1K I/O windows work with resource reassignment
(Bjorn Helgaas, Yinghai Lu)
- Disable decoding while updating 64-bit BARs (Bjorn Helgaas)
Power management:
- Add PCIe runtime D3cold support (Huang Ying)
Virtualization:
- Add VFIO infrastructure (ACS, DMA source ID quirks) (Alex
Williamson)
- Add quirks for devices with broken INTx masking (Jan Kiszka)
Miscellaneous:
- Fix some PCI Express capability version issues (Myron Stowe)
- Factor out some arch code with a weak, generic, pcibios_setup()
(Myron Stowe)"
* tag 'for-3.6' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci: (122 commits)
PCI: hotplug: ensure a consistent return value in error case
PCI: fix undefined reference to 'pci_fixup_final_inited'
PCI: build resource code for M68K architecture
PCI: pciehp: remove unused pciehp_get_max_lnk_width(), pciehp_get_cur_lnk_width()
PCI: reorder __pci_assign_resource() (no change)
PCI: fix truncation of resource size to 32 bits
PCI: acpiphp: merge acpiphp_debug and debug
PCI: acpiphp: remove unused res_lock
sparc/PCI: replace pci_cfg_fake_ranges() with pci_read_bridge_bases()
PCI: call final fixups hot-added devices
PCI: move final fixups from __init to __devinit
x86/PCI: move final fixups from __init to __devinit
MIPS/PCI: move final fixups from __init to __devinit
PCI: support sizing P2P bridge I/O windows with 1K granularity
PCI: reimplement P2P bridge 1K I/O windows (Intel P64H2)
PCI: disable MEM decoding while updating 64-bit MEM BARs
PCI: leave MEM and IO decoding disabled during 64-bit BAR sizing, too
PCI: never discard enable/suspend/resume_early/resume fixups
PCI: release temporary reference in __nv_msi_ht_cap_quirk()
PCI: restructure 'pci_do_fixups()'
...
Diffstat (limited to 'arch')
42 files changed, 502 insertions, 398 deletions
diff --git a/arch/alpha/kernel/pci.c b/arch/alpha/kernel/pci.c index 1a629636cc16..9816d5a4d176 100644 --- a/arch/alpha/kernel/pci.c +++ b/arch/alpha/kernel/pci.c | |||
@@ -59,15 +59,13 @@ struct pci_controller *pci_isa_hose; | |||
59 | * Quirks. | 59 | * Quirks. |
60 | */ | 60 | */ |
61 | 61 | ||
62 | static void __init | 62 | static void __devinit quirk_isa_bridge(struct pci_dev *dev) |
63 | quirk_isa_bridge(struct pci_dev *dev) | ||
64 | { | 63 | { |
65 | dev->class = PCI_CLASS_BRIDGE_ISA << 8; | 64 | dev->class = PCI_CLASS_BRIDGE_ISA << 8; |
66 | } | 65 | } |
67 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82378, quirk_isa_bridge); | 66 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82378, quirk_isa_bridge); |
68 | 67 | ||
69 | static void __init | 68 | static void __devinit quirk_cypress(struct pci_dev *dev) |
70 | quirk_cypress(struct pci_dev *dev) | ||
71 | { | 69 | { |
72 | /* The Notorious Cy82C693 chip. */ | 70 | /* The Notorious Cy82C693 chip. */ |
73 | 71 | ||
@@ -106,8 +104,7 @@ quirk_cypress(struct pci_dev *dev) | |||
106 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_CONTAQ, PCI_DEVICE_ID_CONTAQ_82C693, quirk_cypress); | 104 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_CONTAQ, PCI_DEVICE_ID_CONTAQ_82C693, quirk_cypress); |
107 | 105 | ||
108 | /* Called for each device after PCI setup is done. */ | 106 | /* Called for each device after PCI setup is done. */ |
109 | static void __init | 107 | static void __devinit pcibios_fixup_final(struct pci_dev *dev) |
110 | pcibios_fixup_final(struct pci_dev *dev) | ||
111 | { | 108 | { |
112 | unsigned int class = dev->class >> 8; | 109 | unsigned int class = dev->class >> 8; |
113 | 110 | ||
@@ -198,12 +195,6 @@ pcibios_init(void) | |||
198 | 195 | ||
199 | subsys_initcall(pcibios_init); | 196 | subsys_initcall(pcibios_init); |
200 | 197 | ||
201 | char * __devinit | ||
202 | pcibios_setup(char *str) | ||
203 | { | ||
204 | return str; | ||
205 | } | ||
206 | |||
207 | #ifdef ALPHA_RESTORE_SRM_SETUP | 198 | #ifdef ALPHA_RESTORE_SRM_SETUP |
208 | static struct pdev_srm_saved_conf *srm_saved_configs; | 199 | static struct pdev_srm_saved_conf *srm_saved_configs; |
209 | 200 | ||
@@ -359,7 +350,7 @@ common_init_pci(void) | |||
359 | hose, &resources); | 350 | hose, &resources); |
360 | hose->bus = bus; | 351 | hose->bus = bus; |
361 | hose->need_domain_info = need_domain_info; | 352 | hose->need_domain_info = need_domain_info; |
362 | next_busno = bus->subordinate + 1; | 353 | next_busno = bus->busn_res.end + 1; |
363 | /* Don't allow 8-bit bus number overflow inside the hose - | 354 | /* Don't allow 8-bit bus number overflow inside the hose - |
364 | reserve some space for bridges. */ | 355 | reserve some space for bridges. */ |
365 | if (next_busno > 224) { | 356 | if (next_busno > 224) { |
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c index 25552508c3fd..2b2f25e7fef5 100644 --- a/arch/arm/kernel/bios32.c +++ b/arch/arm/kernel/bios32.c | |||
@@ -253,7 +253,7 @@ static void __devinit pci_fixup_cy82c693(struct pci_dev *dev) | |||
253 | } | 253 | } |
254 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_CONTAQ, PCI_DEVICE_ID_CONTAQ_82C693, pci_fixup_cy82c693); | 254 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_CONTAQ, PCI_DEVICE_ID_CONTAQ_82C693, pci_fixup_cy82c693); |
255 | 255 | ||
256 | static void __init pci_fixup_it8152(struct pci_dev *dev) | 256 | static void __devinit pci_fixup_it8152(struct pci_dev *dev) |
257 | { | 257 | { |
258 | int i; | 258 | int i; |
259 | /* fixup for ITE 8152 devices */ | 259 | /* fixup for ITE 8152 devices */ |
@@ -461,7 +461,7 @@ static void __init pcibios_init_hw(struct hw_pci *hw, struct list_head *head) | |||
461 | if (!sys->bus) | 461 | if (!sys->bus) |
462 | panic("PCI: unable to scan bus!"); | 462 | panic("PCI: unable to scan bus!"); |
463 | 463 | ||
464 | busnr = sys->bus->subordinate + 1; | 464 | busnr = sys->bus->busn_res.end + 1; |
465 | 465 | ||
466 | list_add(&sys->node, head); | 466 | list_add(&sys->node, head); |
467 | } else { | 467 | } else { |
diff --git a/arch/cris/arch-v32/drivers/pci/bios.c b/arch/cris/arch-v32/drivers/pci/bios.c index bc0cfdad1cbc..5b1ee82f63c5 100644 --- a/arch/cris/arch-v32/drivers/pci/bios.c +++ b/arch/cris/arch-v32/drivers/pci/bios.c | |||
@@ -6,11 +6,6 @@ void __devinit pcibios_fixup_bus(struct pci_bus *b) | |||
6 | { | 6 | { |
7 | } | 7 | } |
8 | 8 | ||
9 | char * __devinit pcibios_setup(char *str) | ||
10 | { | ||
11 | return NULL; | ||
12 | } | ||
13 | |||
14 | void pcibios_set_master(struct pci_dev *dev) | 9 | void pcibios_set_master(struct pci_dev *dev) |
15 | { | 10 | { |
16 | u8 lat; | 11 | u8 lat; |
diff --git a/arch/frv/mb93090-mb00/pci-vdk.c b/arch/frv/mb93090-mb00/pci-vdk.c index 6b0b82ff4419..d04ed14bbf0c 100644 --- a/arch/frv/mb93090-mb00/pci-vdk.c +++ b/arch/frv/mb93090-mb00/pci-vdk.c | |||
@@ -268,7 +268,7 @@ static void __init pci_fixup_umc_ide(struct pci_dev *d) | |||
268 | d->resource[i].flags |= PCI_BASE_ADDRESS_SPACE_IO; | 268 | d->resource[i].flags |= PCI_BASE_ADDRESS_SPACE_IO; |
269 | } | 269 | } |
270 | 270 | ||
271 | static void __init pci_fixup_ide_bases(struct pci_dev *d) | 271 | static void __devinit pci_fixup_ide_bases(struct pci_dev *d) |
272 | { | 272 | { |
273 | int i; | 273 | int i; |
274 | 274 | ||
@@ -287,7 +287,7 @@ static void __init pci_fixup_ide_bases(struct pci_dev *d) | |||
287 | } | 287 | } |
288 | } | 288 | } |
289 | 289 | ||
290 | static void __init pci_fixup_ide_trash(struct pci_dev *d) | 290 | static void __devinit pci_fixup_ide_trash(struct pci_dev *d) |
291 | { | 291 | { |
292 | int i; | 292 | int i; |
293 | 293 | ||
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index 524df4295c90..81acc7a57f3e 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c | |||
@@ -351,6 +351,8 @@ pci_acpi_scan_root(struct acpi_pci_root *root) | |||
351 | #endif | 351 | #endif |
352 | 352 | ||
353 | INIT_LIST_HEAD(&info.resources); | 353 | INIT_LIST_HEAD(&info.resources); |
354 | /* insert busn resource at first */ | ||
355 | pci_add_resource(&info.resources, &root->secondary); | ||
354 | acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_window, | 356 | acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_window, |
355 | &windows); | 357 | &windows); |
356 | if (windows) { | 358 | if (windows) { |
@@ -384,7 +386,7 @@ pci_acpi_scan_root(struct acpi_pci_root *root) | |||
384 | return NULL; | 386 | return NULL; |
385 | } | 387 | } |
386 | 388 | ||
387 | pbus->subordinate = pci_scan_child_bus(pbus); | 389 | pci_scan_child_bus(pbus); |
388 | return pbus; | 390 | return pbus; |
389 | 391 | ||
390 | out3: | 392 | out3: |
@@ -496,15 +498,6 @@ pcibios_align_resource (void *data, const struct resource *res, | |||
496 | return res->start; | 498 | return res->start; |
497 | } | 499 | } |
498 | 500 | ||
499 | /* | ||
500 | * PCI BIOS setup, always defaults to SAL interface | ||
501 | */ | ||
502 | char * __init | ||
503 | pcibios_setup (char *str) | ||
504 | { | ||
505 | return str; | ||
506 | } | ||
507 | |||
508 | int | 501 | int |
509 | pci_mmap_page_range (struct pci_dev *dev, struct vm_area_struct *vma, | 502 | pci_mmap_page_range (struct pci_dev *dev, struct vm_area_struct *vma, |
510 | enum pci_mmap_state mmap_state, int write_combine) | 503 | enum pci_mmap_state mmap_state, int write_combine) |
diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c index ca8f6e769960..4dbb5055d04b 100644 --- a/arch/microblaze/pci/pci-common.c +++ b/arch/microblaze/pci/pci-common.c | |||
@@ -192,11 +192,6 @@ void pcibios_set_master(struct pci_dev *dev) | |||
192 | /* No special bus mastering setup handling */ | 192 | /* No special bus mastering setup handling */ |
193 | } | 193 | } |
194 | 194 | ||
195 | char __devinit *pcibios_setup(char *str) | ||
196 | { | ||
197 | return str; | ||
198 | } | ||
199 | |||
200 | /* | 195 | /* |
201 | * Reads the interrupt pin to determine if interrupt is use by card. | 196 | * Reads the interrupt pin to determine if interrupt is use by card. |
202 | * If the interrupt is used, then gets the interrupt line from the | 197 | * If the interrupt is used, then gets the interrupt line from the |
@@ -1504,10 +1499,10 @@ static void __devinit pcibios_scan_phb(struct pci_controller *hose) | |||
1504 | pci_free_resource_list(&resources); | 1499 | pci_free_resource_list(&resources); |
1505 | return; | 1500 | return; |
1506 | } | 1501 | } |
1507 | bus->secondary = hose->first_busno; | 1502 | bus->busn_res.start = hose->first_busno; |
1508 | hose->bus = bus; | 1503 | hose->bus = bus; |
1509 | 1504 | ||
1510 | hose->last_busno = bus->subordinate; | 1505 | hose->last_busno = bus->busn_res.end; |
1511 | } | 1506 | } |
1512 | 1507 | ||
1513 | static int __init pcibios_init(void) | 1508 | static int __init pcibios_init(void) |
diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c index 271e8c4a54c7..690356808f8a 100644 --- a/arch/mips/pci/pci.c +++ b/arch/mips/pci/pci.c | |||
@@ -102,7 +102,7 @@ static void __devinit pcibios_scanbus(struct pci_controller *hose) | |||
102 | need_domain_info = need_domain_info || hose->index; | 102 | need_domain_info = need_domain_info || hose->index; |
103 | hose->need_domain_info = need_domain_info; | 103 | hose->need_domain_info = need_domain_info; |
104 | if (bus) { | 104 | if (bus) { |
105 | next_busno = bus->subordinate + 1; | 105 | next_busno = bus->busn_res.end + 1; |
106 | /* Don't allow 8-bit bus number overflow inside the hose - | 106 | /* Don't allow 8-bit bus number overflow inside the hose - |
107 | reserve some space for bridges. */ | 107 | reserve some space for bridges. */ |
108 | if (next_busno > 224) { | 108 | if (next_busno > 224) { |
@@ -348,9 +348,9 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, | |||
348 | vma->vm_end - vma->vm_start, vma->vm_page_prot); | 348 | vma->vm_end - vma->vm_start, vma->vm_page_prot); |
349 | } | 349 | } |
350 | 350 | ||
351 | char * (*pcibios_plat_setup)(char *str) __devinitdata; | 351 | char * (*pcibios_plat_setup)(char *str) __initdata; |
352 | 352 | ||
353 | char *__devinit pcibios_setup(char *str) | 353 | char *__init pcibios_setup(char *str) |
354 | { | 354 | { |
355 | if (pcibios_plat_setup) | 355 | if (pcibios_plat_setup) |
356 | return pcibios_plat_setup(str); | 356 | return pcibios_plat_setup(str); |
diff --git a/arch/mips/pmc-sierra/yosemite/ht.c b/arch/mips/pmc-sierra/yosemite/ht.c index 63be40e470db..14dc9c8fff0e 100644 --- a/arch/mips/pmc-sierra/yosemite/ht.c +++ b/arch/mips/pmc-sierra/yosemite/ht.c | |||
@@ -395,17 +395,6 @@ void __init pcibios_init(void) | |||
395 | pci_scan_bus(3, &titan_pci_ops, NULL); | 395 | pci_scan_bus(3, &titan_pci_ops, NULL); |
396 | } | 396 | } |
397 | 397 | ||
398 | /* | ||
399 | * for parsing "pci=" kernel boot arguments. | ||
400 | */ | ||
401 | char *pcibios_setup(char *str) | ||
402 | { | ||
403 | printk(KERN_INFO "rr: pcibios_setup\n"); | ||
404 | /* Nothing to do for now. */ | ||
405 | |||
406 | return str; | ||
407 | } | ||
408 | |||
409 | unsigned __init int pcibios_assign_all_busses(void) | 398 | unsigned __init int pcibios_assign_all_busses(void) |
410 | { | 399 | { |
411 | /* We want to use the PCI bus detection done by PMON */ | 400 | /* We want to use the PCI bus detection done by PMON */ |
diff --git a/arch/mips/txx9/generic/pci.c b/arch/mips/txx9/generic/pci.c index 64eb71b15280..125db323ab1e 100644 --- a/arch/mips/txx9/generic/pci.c +++ b/arch/mips/txx9/generic/pci.c | |||
@@ -256,7 +256,7 @@ static irqreturn_t i8259_interrupt(int irq, void *dev_id) | |||
256 | return IRQ_HANDLED; | 256 | return IRQ_HANDLED; |
257 | } | 257 | } |
258 | 258 | ||
259 | static int __init | 259 | static int __devinit |
260 | txx9_i8259_irq_setup(int irq) | 260 | txx9_i8259_irq_setup(int irq) |
261 | { | 261 | { |
262 | int err; | 262 | int err; |
@@ -398,9 +398,9 @@ int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |||
398 | return txx9_board_vec->pci_map_irq(dev, slot, pin); | 398 | return txx9_board_vec->pci_map_irq(dev, slot, pin); |
399 | } | 399 | } |
400 | 400 | ||
401 | char * (*txx9_board_pcibios_setup)(char *str) __devinitdata; | 401 | char * (*txx9_board_pcibios_setup)(char *str) __initdata; |
402 | 402 | ||
403 | char *__devinit txx9_pcibios_setup(char *str) | 403 | char *__init txx9_pcibios_setup(char *str) |
404 | { | 404 | { |
405 | if (txx9_board_pcibios_setup && !txx9_board_pcibios_setup(str)) | 405 | if (txx9_board_pcibios_setup && !txx9_board_pcibios_setup(str)) |
406 | return NULL; | 406 | return NULL; |
diff --git a/arch/parisc/kernel/pci.c b/arch/parisc/kernel/pci.c index 24644aca10cb..60309051875e 100644 --- a/arch/parisc/kernel/pci.c +++ b/arch/parisc/kernel/pci.c | |||
@@ -139,11 +139,6 @@ void pcibios_fixup_bus(struct pci_bus *bus) | |||
139 | } | 139 | } |
140 | 140 | ||
141 | 141 | ||
142 | char *pcibios_setup(char *str) | ||
143 | { | ||
144 | return str; | ||
145 | } | ||
146 | |||
147 | /* | 142 | /* |
148 | * Called by pci_set_master() - a driver interface. | 143 | * Called by pci_set_master() - a driver interface. |
149 | * | 144 | * |
diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h index ac39e6a3b25a..8cccbee61519 100644 --- a/arch/powerpc/include/asm/pci-bridge.h +++ b/arch/powerpc/include/asm/pci-bridge.h | |||
@@ -30,6 +30,7 @@ struct pci_controller { | |||
30 | int first_busno; | 30 | int first_busno; |
31 | int last_busno; | 31 | int last_busno; |
32 | int self_busno; | 32 | int self_busno; |
33 | struct resource busn; | ||
33 | 34 | ||
34 | void __iomem *io_base_virt; | 35 | void __iomem *io_base_virt; |
35 | #ifdef CONFIG_PPC64 | 36 | #ifdef CONFIG_PPC64 |
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index edef9afd8858..2aa04f29e1de 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c | |||
@@ -200,11 +200,6 @@ int pcibios_add_platform_entries(struct pci_dev *pdev) | |||
200 | return device_create_file(&pdev->dev, &dev_attr_devspec); | 200 | return device_create_file(&pdev->dev, &dev_attr_devspec); |
201 | } | 201 | } |
202 | 202 | ||
203 | char __devinit *pcibios_setup(char *str) | ||
204 | { | ||
205 | return str; | ||
206 | } | ||
207 | |||
208 | /* | 203 | /* |
209 | * Reads the interrupt pin to determine if interrupt is use by card. | 204 | * Reads the interrupt pin to determine if interrupt is use by card. |
210 | * If the interrupt is used, then gets the interrupt line from the | 205 | * If the interrupt is used, then gets the interrupt line from the |
@@ -1635,6 +1630,11 @@ void __devinit pcibios_scan_phb(struct pci_controller *hose) | |||
1635 | /* Wire up PHB bus resources */ | 1630 | /* Wire up PHB bus resources */ |
1636 | pcibios_setup_phb_resources(hose, &resources); | 1631 | pcibios_setup_phb_resources(hose, &resources); |
1637 | 1632 | ||
1633 | hose->busn.start = hose->first_busno; | ||
1634 | hose->busn.end = hose->last_busno; | ||
1635 | hose->busn.flags = IORESOURCE_BUS; | ||
1636 | pci_add_resource(&resources, &hose->busn); | ||
1637 | |||
1638 | /* Create an empty bus for the toplevel */ | 1638 | /* Create an empty bus for the toplevel */ |
1639 | bus = pci_create_root_bus(hose->parent, hose->first_busno, | 1639 | bus = pci_create_root_bus(hose->parent, hose->first_busno, |
1640 | hose->ops, hose, &resources); | 1640 | hose->ops, hose, &resources); |
@@ -1651,13 +1651,14 @@ void __devinit pcibios_scan_phb(struct pci_controller *hose) | |||
1651 | if (node && ppc_md.pci_probe_mode) | 1651 | if (node && ppc_md.pci_probe_mode) |
1652 | mode = ppc_md.pci_probe_mode(bus); | 1652 | mode = ppc_md.pci_probe_mode(bus); |
1653 | pr_debug(" probe mode: %d\n", mode); | 1653 | pr_debug(" probe mode: %d\n", mode); |
1654 | if (mode == PCI_PROBE_DEVTREE) { | 1654 | if (mode == PCI_PROBE_DEVTREE) |
1655 | bus->subordinate = hose->last_busno; | ||
1656 | of_scan_bus(node, bus); | 1655 | of_scan_bus(node, bus); |
1657 | } | ||
1658 | 1656 | ||
1659 | if (mode == PCI_PROBE_NORMAL) | 1657 | if (mode == PCI_PROBE_NORMAL) { |
1660 | hose->last_busno = bus->subordinate = pci_scan_child_bus(bus); | 1658 | pci_bus_update_busn_res_end(bus, 255); |
1659 | hose->last_busno = pci_scan_child_bus(bus); | ||
1660 | pci_bus_update_busn_res_end(bus, hose->last_busno); | ||
1661 | } | ||
1661 | 1662 | ||
1662 | /* Platform gets a chance to do some global fixups before | 1663 | /* Platform gets a chance to do some global fixups before |
1663 | * we proceed to resource allocation | 1664 | * we proceed to resource allocation |
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c index 94a54f61d341..4ff190ff24a0 100644 --- a/arch/powerpc/kernel/pci_64.c +++ b/arch/powerpc/kernel/pci_64.c | |||
@@ -236,7 +236,7 @@ long sys_pciconfig_iobase(long which, unsigned long in_bus, | |||
236 | 236 | ||
237 | for (ln = pci_root_buses.next; ln != &pci_root_buses; ln = ln->next) { | 237 | for (ln = pci_root_buses.next; ln != &pci_root_buses; ln = ln->next) { |
238 | bus = pci_bus_b(ln); | 238 | bus = pci_bus_b(ln); |
239 | if (in_bus >= bus->number && in_bus <= bus->subordinate) | 239 | if (in_bus >= bus->number && in_bus <= bus->busn_res.end) |
240 | break; | 240 | break; |
241 | bus = NULL; | 241 | bus = NULL; |
242 | } | 242 | } |
diff --git a/arch/powerpc/kernel/pci_of_scan.c b/arch/powerpc/kernel/pci_of_scan.c index d7dd42bd1452..30378a19f65d 100644 --- a/arch/powerpc/kernel/pci_of_scan.c +++ b/arch/powerpc/kernel/pci_of_scan.c | |||
@@ -239,7 +239,7 @@ void __devinit of_scan_pci_bridge(struct pci_dev *dev) | |||
239 | } | 239 | } |
240 | 240 | ||
241 | bus->primary = dev->bus->number; | 241 | bus->primary = dev->bus->number; |
242 | bus->subordinate = busrange[1]; | 242 | pci_bus_insert_busn_res(bus, busrange[0], busrange[1]); |
243 | bus->bridge_ctl = 0; | 243 | bus->bridge_ctl = 0; |
244 | 244 | ||
245 | /* parse ranges property */ | 245 | /* parse ranges property */ |
diff --git a/arch/powerpc/platforms/85xx/tqm85xx.c b/arch/powerpc/platforms/85xx/tqm85xx.c index 4d786c25d3e5..3e70a2035e53 100644 --- a/arch/powerpc/platforms/85xx/tqm85xx.c +++ b/arch/powerpc/platforms/85xx/tqm85xx.c | |||
@@ -102,7 +102,7 @@ static void tqm85xx_show_cpuinfo(struct seq_file *m) | |||
102 | seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); | 102 | seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); |
103 | } | 103 | } |
104 | 104 | ||
105 | static void __init tqm85xx_ti1520_fixup(struct pci_dev *pdev) | 105 | static void __devinit tqm85xx_ti1520_fixup(struct pci_dev *pdev) |
106 | { | 106 | { |
107 | unsigned int val; | 107 | unsigned int val; |
108 | 108 | ||
diff --git a/arch/powerpc/platforms/86xx/gef_ppc9a.c b/arch/powerpc/platforms/86xx/gef_ppc9a.c index 1fca663f1b25..563aafa8629c 100644 --- a/arch/powerpc/platforms/86xx/gef_ppc9a.c +++ b/arch/powerpc/platforms/86xx/gef_ppc9a.c | |||
@@ -164,7 +164,7 @@ static void gef_ppc9a_show_cpuinfo(struct seq_file *m) | |||
164 | gef_ppc9a_get_vme_is_syscon() ? "yes" : "no"); | 164 | gef_ppc9a_get_vme_is_syscon() ? "yes" : "no"); |
165 | } | 165 | } |
166 | 166 | ||
167 | static void __init gef_ppc9a_nec_fixup(struct pci_dev *pdev) | 167 | static void __devinit gef_ppc9a_nec_fixup(struct pci_dev *pdev) |
168 | { | 168 | { |
169 | unsigned int val; | 169 | unsigned int val; |
170 | 170 | ||
diff --git a/arch/powerpc/platforms/86xx/gef_sbc310.c b/arch/powerpc/platforms/86xx/gef_sbc310.c index 14e0e576bcbd..cc6a91ae0889 100644 --- a/arch/powerpc/platforms/86xx/gef_sbc310.c +++ b/arch/powerpc/platforms/86xx/gef_sbc310.c | |||
@@ -152,7 +152,7 @@ static void gef_sbc310_show_cpuinfo(struct seq_file *m) | |||
152 | 152 | ||
153 | } | 153 | } |
154 | 154 | ||
155 | static void __init gef_sbc310_nec_fixup(struct pci_dev *pdev) | 155 | static void __devinit gef_sbc310_nec_fixup(struct pci_dev *pdev) |
156 | { | 156 | { |
157 | unsigned int val; | 157 | unsigned int val; |
158 | 158 | ||
diff --git a/arch/powerpc/platforms/86xx/gef_sbc610.c b/arch/powerpc/platforms/86xx/gef_sbc610.c index 1638f43599f0..aead6b337f4a 100644 --- a/arch/powerpc/platforms/86xx/gef_sbc610.c +++ b/arch/powerpc/platforms/86xx/gef_sbc610.c | |||
@@ -141,7 +141,7 @@ static void gef_sbc610_show_cpuinfo(struct seq_file *m) | |||
141 | seq_printf(m, "SVR\t\t: 0x%x\n", svid); | 141 | seq_printf(m, "SVR\t\t: 0x%x\n", svid); |
142 | } | 142 | } |
143 | 143 | ||
144 | static void __init gef_sbc610_nec_fixup(struct pci_dev *pdev) | 144 | static void __devinit gef_sbc610_nec_fixup(struct pci_dev *pdev) |
145 | { | 145 | { |
146 | unsigned int val; | 146 | unsigned int val; |
147 | 147 | ||
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index fbdd74dac3ac..9cda6a1ad0cf 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c | |||
@@ -589,7 +589,7 @@ static int __devinit pnv_ioda_configure_pe(struct pnv_phb *phb, | |||
589 | dcomp = OPAL_IGNORE_RID_DEVICE_NUMBER; | 589 | dcomp = OPAL_IGNORE_RID_DEVICE_NUMBER; |
590 | fcomp = OPAL_IGNORE_RID_FUNCTION_NUMBER; | 590 | fcomp = OPAL_IGNORE_RID_FUNCTION_NUMBER; |
591 | parent = pe->pbus->self; | 591 | parent = pe->pbus->self; |
592 | count = pe->pbus->subordinate - pe->pbus->secondary + 1; | 592 | count = pe->pbus->busn_res.end - pe->pbus->busn_res.start + 1; |
593 | switch(count) { | 593 | switch(count) { |
594 | case 1: bcomp = OpalPciBusAll; break; | 594 | case 1: bcomp = OpalPciBusAll; break; |
595 | case 2: bcomp = OpalPciBus7Bits; break; | 595 | case 2: bcomp = OpalPciBus7Bits; break; |
@@ -816,11 +816,11 @@ static void __devinit pnv_ioda_setup_bus_PE(struct pci_dev *dev, | |||
816 | pe->pdev = NULL; | 816 | pe->pdev = NULL; |
817 | pe->tce32_seg = -1; | 817 | pe->tce32_seg = -1; |
818 | pe->mve_number = -1; | 818 | pe->mve_number = -1; |
819 | pe->rid = bus->secondary << 8; | 819 | pe->rid = bus->busn_res.start << 8; |
820 | pe->dma_weight = 0; | 820 | pe->dma_weight = 0; |
821 | 821 | ||
822 | pe_info(pe, "Secondary busses %d..%d associated with PE\n", | 822 | pe_info(pe, "Secondary busses %pR associated with PE\n", |
823 | bus->secondary, bus->subordinate); | 823 | &bus->busn_res); |
824 | 824 | ||
825 | if (pnv_ioda_configure_pe(phb, pe)) { | 825 | if (pnv_ioda_configure_pe(phb, pe)) { |
826 | /* XXX What do we do here ? */ | 826 | /* XXX What do we do here ? */ |
diff --git a/arch/powerpc/platforms/pseries/pci_dlpar.c b/arch/powerpc/platforms/pseries/pci_dlpar.c index 8b7bafa489c2..3ccebc83dc02 100644 --- a/arch/powerpc/platforms/pseries/pci_dlpar.c +++ b/arch/powerpc/platforms/pseries/pci_dlpar.c | |||
@@ -121,7 +121,7 @@ void pcibios_add_pci_devices(struct pci_bus * bus) | |||
121 | if (!num) | 121 | if (!num) |
122 | return; | 122 | return; |
123 | pcibios_setup_bus_devices(bus); | 123 | pcibios_setup_bus_devices(bus); |
124 | max = bus->secondary; | 124 | max = bus->busn_res.start; |
125 | for (pass=0; pass < 2; pass++) | 125 | for (pass=0; pass < 2; pass++) |
126 | list_for_each_entry(dev, &bus->devices, bus_list) { | 126 | list_for_each_entry(dev, &bus->devices, bus_list) { |
127 | if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || | 127 | if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || |
diff --git a/arch/powerpc/sysdev/mv64x60_pci.c b/arch/powerpc/sysdev/mv64x60_pci.c index b0037cefaada..364b14d4754b 100644 --- a/arch/powerpc/sysdev/mv64x60_pci.c +++ b/arch/powerpc/sysdev/mv64x60_pci.c | |||
@@ -104,7 +104,7 @@ subsys_initcall(mv64x60_sysfs_init); | |||
104 | 104 | ||
105 | #endif /* CONFIG_SYSFS */ | 105 | #endif /* CONFIG_SYSFS */ |
106 | 106 | ||
107 | static void __init mv64x60_pci_fixup_early(struct pci_dev *dev) | 107 | static void __devinit mv64x60_pci_fixup_early(struct pci_dev *dev) |
108 | { | 108 | { |
109 | /* | 109 | /* |
110 | * Set the host bridge hdr_type to an invalid value so that | 110 | * Set the host bridge hdr_type to an invalid value so that |
diff --git a/arch/sh/drivers/pci/fixups-dreamcast.c b/arch/sh/drivers/pci/fixups-dreamcast.c index edeea8960c30..a5fe1b54c952 100644 --- a/arch/sh/drivers/pci/fixups-dreamcast.c +++ b/arch/sh/drivers/pci/fixups-dreamcast.c | |||
@@ -28,7 +28,7 @@ | |||
28 | #include <asm/irq.h> | 28 | #include <asm/irq.h> |
29 | #include <mach/pci.h> | 29 | #include <mach/pci.h> |
30 | 30 | ||
31 | static void __init gapspci_fixup_resources(struct pci_dev *dev) | 31 | static void __devinit gapspci_fixup_resources(struct pci_dev *dev) |
32 | { | 32 | { |
33 | struct pci_channel *p = dev->sysdata; | 33 | struct pci_channel *p = dev->sysdata; |
34 | 34 | ||
diff --git a/arch/sh/drivers/pci/fixups-sdk7786.c b/arch/sh/drivers/pci/fixups-sdk7786.c index 0e18ee332553..36eb6fc3c18a 100644 --- a/arch/sh/drivers/pci/fixups-sdk7786.c +++ b/arch/sh/drivers/pci/fixups-sdk7786.c | |||
@@ -23,9 +23,9 @@ | |||
23 | * Misconfigurations can be detected through the FPGA via the slot | 23 | * Misconfigurations can be detected through the FPGA via the slot |
24 | * resistors to determine card presence. Hotplug remains unsupported. | 24 | * resistors to determine card presence. Hotplug remains unsupported. |
25 | */ | 25 | */ |
26 | static unsigned int slot4en __devinitdata; | 26 | static unsigned int slot4en __initdata; |
27 | 27 | ||
28 | char *__devinit pcibios_setup(char *str) | 28 | char *__init pcibios_setup(char *str) |
29 | { | 29 | { |
30 | if (strcmp(str, "slot4en") == 0) { | 30 | if (strcmp(str, "slot4en") == 0) { |
31 | slot4en = 1; | 31 | slot4en = 1; |
diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c index 9d10a3cb8797..40db2d0aef3f 100644 --- a/arch/sh/drivers/pci/pci.c +++ b/arch/sh/drivers/pci/pci.c | |||
@@ -59,7 +59,7 @@ static void __devinit pcibios_scanbus(struct pci_channel *hose) | |||
59 | need_domain_info = need_domain_info || hose->index; | 59 | need_domain_info = need_domain_info || hose->index; |
60 | hose->need_domain_info = need_domain_info; | 60 | hose->need_domain_info = need_domain_info; |
61 | if (bus) { | 61 | if (bus) { |
62 | next_busno = bus->subordinate + 1; | 62 | next_busno = bus->busn_res.end + 1; |
63 | /* Don't allow 8-bit bus number overflow inside the hose - | 63 | /* Don't allow 8-bit bus number overflow inside the hose - |
64 | reserve some space for bridges. */ | 64 | reserve some space for bridges. */ |
65 | if (next_busno > 224) { | 65 | if (next_busno > 224) { |
@@ -197,11 +197,6 @@ void __init pcibios_update_irq(struct pci_dev *dev, int irq) | |||
197 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); | 197 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); |
198 | } | 198 | } |
199 | 199 | ||
200 | char * __devinit __weak pcibios_setup(char *str) | ||
201 | { | ||
202 | return str; | ||
203 | } | ||
204 | |||
205 | static void __init | 200 | static void __init |
206 | pcibios_bus_report_status_early(struct pci_channel *hose, | 201 | pcibios_bus_report_status_early(struct pci_channel *hose, |
207 | int top_bus, int current_bus, | 202 | int top_bus, int current_bus, |
diff --git a/arch/sparc/kernel/leon_pci.c b/arch/sparc/kernel/leon_pci.c index 19f56058742b..21dcda75a520 100644 --- a/arch/sparc/kernel/leon_pci.c +++ b/arch/sparc/kernel/leon_pci.c | |||
@@ -91,14 +91,6 @@ void __devinit pcibios_fixup_bus(struct pci_bus *pbus) | |||
91 | } | 91 | } |
92 | } | 92 | } |
93 | 93 | ||
94 | /* | ||
95 | * Other archs parse arguments here. | ||
96 | */ | ||
97 | char * __devinit pcibios_setup(char *str) | ||
98 | { | ||
99 | return str; | ||
100 | } | ||
101 | |||
102 | resource_size_t pcibios_align_resource(void *data, const struct resource *res, | 94 | resource_size_t pcibios_align_resource(void *data, const struct resource *res, |
103 | resource_size_t size, resource_size_t align) | 95 | resource_size_t size, resource_size_t align) |
104 | { | 96 | { |
diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c index fdaf21811670..065b88c4f868 100644 --- a/arch/sparc/kernel/pci.c +++ b/arch/sparc/kernel/pci.c | |||
@@ -375,93 +375,6 @@ static void __devinit apb_calc_first_last(u8 map, u32 *first_p, u32 *last_p) | |||
375 | *last_p = last; | 375 | *last_p = last; |
376 | } | 376 | } |
377 | 377 | ||
378 | /* For PCI bus devices which lack a 'ranges' property we interrogate | ||
379 | * the config space values to set the resources, just like the generic | ||
380 | * Linux PCI probing code does. | ||
381 | */ | ||
382 | static void __devinit pci_cfg_fake_ranges(struct pci_dev *dev, | ||
383 | struct pci_bus *bus, | ||
384 | struct pci_pbm_info *pbm) | ||
385 | { | ||
386 | struct pci_bus_region region; | ||
387 | struct resource *res, res2; | ||
388 | u8 io_base_lo, io_limit_lo; | ||
389 | u16 mem_base_lo, mem_limit_lo; | ||
390 | unsigned long base, limit; | ||
391 | |||
392 | pci_read_config_byte(dev, PCI_IO_BASE, &io_base_lo); | ||
393 | pci_read_config_byte(dev, PCI_IO_LIMIT, &io_limit_lo); | ||
394 | base = (io_base_lo & PCI_IO_RANGE_MASK) << 8; | ||
395 | limit = (io_limit_lo & PCI_IO_RANGE_MASK) << 8; | ||
396 | |||
397 | if ((io_base_lo & PCI_IO_RANGE_TYPE_MASK) == PCI_IO_RANGE_TYPE_32) { | ||
398 | u16 io_base_hi, io_limit_hi; | ||
399 | |||
400 | pci_read_config_word(dev, PCI_IO_BASE_UPPER16, &io_base_hi); | ||
401 | pci_read_config_word(dev, PCI_IO_LIMIT_UPPER16, &io_limit_hi); | ||
402 | base |= (io_base_hi << 16); | ||
403 | limit |= (io_limit_hi << 16); | ||
404 | } | ||
405 | |||
406 | res = bus->resource[0]; | ||
407 | if (base <= limit) { | ||
408 | res->flags = (io_base_lo & PCI_IO_RANGE_TYPE_MASK) | IORESOURCE_IO; | ||
409 | res2.flags = res->flags; | ||
410 | region.start = base; | ||
411 | region.end = limit + 0xfff; | ||
412 | pcibios_bus_to_resource(dev, &res2, ®ion); | ||
413 | if (!res->start) | ||
414 | res->start = res2.start; | ||
415 | if (!res->end) | ||
416 | res->end = res2.end; | ||
417 | } | ||
418 | |||
419 | pci_read_config_word(dev, PCI_MEMORY_BASE, &mem_base_lo); | ||
420 | pci_read_config_word(dev, PCI_MEMORY_LIMIT, &mem_limit_lo); | ||
421 | base = (mem_base_lo & PCI_MEMORY_RANGE_MASK) << 16; | ||
422 | limit = (mem_limit_lo & PCI_MEMORY_RANGE_MASK) << 16; | ||
423 | |||
424 | res = bus->resource[1]; | ||
425 | if (base <= limit) { | ||
426 | res->flags = ((mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | | ||
427 | IORESOURCE_MEM); | ||
428 | region.start = base; | ||
429 | region.end = limit + 0xfffff; | ||
430 | pcibios_bus_to_resource(dev, res, ®ion); | ||
431 | } | ||
432 | |||
433 | pci_read_config_word(dev, PCI_PREF_MEMORY_BASE, &mem_base_lo); | ||
434 | pci_read_config_word(dev, PCI_PREF_MEMORY_LIMIT, &mem_limit_lo); | ||
435 | base = (mem_base_lo & PCI_PREF_RANGE_MASK) << 16; | ||
436 | limit = (mem_limit_lo & PCI_PREF_RANGE_MASK) << 16; | ||
437 | |||
438 | if ((mem_base_lo & PCI_PREF_RANGE_TYPE_MASK) == PCI_PREF_RANGE_TYPE_64) { | ||
439 | u32 mem_base_hi, mem_limit_hi; | ||
440 | |||
441 | pci_read_config_dword(dev, PCI_PREF_BASE_UPPER32, &mem_base_hi); | ||
442 | pci_read_config_dword(dev, PCI_PREF_LIMIT_UPPER32, &mem_limit_hi); | ||
443 | |||
444 | /* | ||
445 | * Some bridges set the base > limit by default, and some | ||
446 | * (broken) BIOSes do not initialize them. If we find | ||
447 | * this, just assume they are not being used. | ||
448 | */ | ||
449 | if (mem_base_hi <= mem_limit_hi) { | ||
450 | base |= ((long) mem_base_hi) << 32; | ||
451 | limit |= ((long) mem_limit_hi) << 32; | ||
452 | } | ||
453 | } | ||
454 | |||
455 | res = bus->resource[2]; | ||
456 | if (base <= limit) { | ||
457 | res->flags = ((mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | | ||
458 | IORESOURCE_MEM | IORESOURCE_PREFETCH); | ||
459 | region.start = base; | ||
460 | region.end = limit + 0xfffff; | ||
461 | pcibios_bus_to_resource(dev, res, ®ion); | ||
462 | } | ||
463 | } | ||
464 | |||
465 | /* Cook up fake bus resources for SUNW,simba PCI bridges which lack | 378 | /* Cook up fake bus resources for SUNW,simba PCI bridges which lack |
466 | * a proper 'ranges' property. | 379 | * a proper 'ranges' property. |
467 | */ | 380 | */ |
@@ -535,7 +448,7 @@ static void __devinit of_scan_pci_bridge(struct pci_pbm_info *pbm, | |||
535 | } | 448 | } |
536 | 449 | ||
537 | bus->primary = dev->bus->number; | 450 | bus->primary = dev->bus->number; |
538 | bus->subordinate = busrange[1]; | 451 | pci_bus_insert_busn_res(bus, busrange[0], busrange[1]); |
539 | bus->bridge_ctl = 0; | 452 | bus->bridge_ctl = 0; |
540 | 453 | ||
541 | /* parse ranges property, or cook one up by hand for Simba */ | 454 | /* parse ranges property, or cook one up by hand for Simba */ |
@@ -550,7 +463,7 @@ static void __devinit of_scan_pci_bridge(struct pci_pbm_info *pbm, | |||
550 | apb_fake_ranges(dev, bus, pbm); | 463 | apb_fake_ranges(dev, bus, pbm); |
551 | goto after_ranges; | 464 | goto after_ranges; |
552 | } else if (ranges == NULL) { | 465 | } else if (ranges == NULL) { |
553 | pci_cfg_fake_ranges(dev, bus, pbm); | 466 | pci_read_bridge_bases(bus); |
554 | goto after_ranges; | 467 | goto after_ranges; |
555 | } | 468 | } |
556 | i = 1; | 469 | i = 1; |
@@ -685,6 +598,10 @@ struct pci_bus * __devinit pci_scan_one_pbm(struct pci_pbm_info *pbm, | |||
685 | pbm->io_space.start); | 598 | pbm->io_space.start); |
686 | pci_add_resource_offset(&resources, &pbm->mem_space, | 599 | pci_add_resource_offset(&resources, &pbm->mem_space, |
687 | pbm->mem_space.start); | 600 | pbm->mem_space.start); |
601 | pbm->busn.start = pbm->pci_first_busno; | ||
602 | pbm->busn.end = pbm->pci_last_busno; | ||
603 | pbm->busn.flags = IORESOURCE_BUS; | ||
604 | pci_add_resource(&resources, &pbm->busn); | ||
688 | bus = pci_create_root_bus(parent, pbm->pci_first_busno, pbm->pci_ops, | 605 | bus = pci_create_root_bus(parent, pbm->pci_first_busno, pbm->pci_ops, |
689 | pbm, &resources); | 606 | pbm, &resources); |
690 | if (!bus) { | 607 | if (!bus) { |
@@ -693,8 +610,6 @@ struct pci_bus * __devinit pci_scan_one_pbm(struct pci_pbm_info *pbm, | |||
693 | pci_free_resource_list(&resources); | 610 | pci_free_resource_list(&resources); |
694 | return NULL; | 611 | return NULL; |
695 | } | 612 | } |
696 | bus->secondary = pbm->pci_first_busno; | ||
697 | bus->subordinate = pbm->pci_last_busno; | ||
698 | 613 | ||
699 | pci_of_scan_bus(pbm, node, bus); | 614 | pci_of_scan_bus(pbm, node, bus); |
700 | pci_bus_add_devices(bus); | 615 | pci_bus_add_devices(bus); |
@@ -747,11 +662,6 @@ int pcibios_enable_device(struct pci_dev *dev, int mask) | |||
747 | return 0; | 662 | return 0; |
748 | } | 663 | } |
749 | 664 | ||
750 | char * __devinit pcibios_setup(char *str) | ||
751 | { | ||
752 | return str; | ||
753 | } | ||
754 | |||
755 | /* Platform support for /proc/bus/pci/X/Y mmap()s. */ | 665 | /* Platform support for /proc/bus/pci/X/Y mmap()s. */ |
756 | 666 | ||
757 | /* If the user uses a host-bridge as the PCI device, he may use | 667 | /* If the user uses a host-bridge as the PCI device, he may use |
diff --git a/arch/sparc/kernel/pci_impl.h b/arch/sparc/kernel/pci_impl.h index 6beb60df31d0..918a2031c8bb 100644 --- a/arch/sparc/kernel/pci_impl.h +++ b/arch/sparc/kernel/pci_impl.h | |||
@@ -97,6 +97,7 @@ struct pci_pbm_info { | |||
97 | /* PBM I/O and Memory space resources. */ | 97 | /* PBM I/O and Memory space resources. */ |
98 | struct resource io_space; | 98 | struct resource io_space; |
99 | struct resource mem_space; | 99 | struct resource mem_space; |
100 | struct resource busn; | ||
100 | 101 | ||
101 | /* Base of PCI Config space, can be per-PBM or shared. */ | 102 | /* Base of PCI Config space, can be per-PBM or shared. */ |
102 | unsigned long config_space; | 103 | unsigned long config_space; |
diff --git a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c index ded3f6090c3f..521fdf1b20e5 100644 --- a/arch/sparc/kernel/pcic.c +++ b/arch/sparc/kernel/pcic.c | |||
@@ -767,14 +767,6 @@ static void watchdog_reset() { | |||
767 | } | 767 | } |
768 | #endif | 768 | #endif |
769 | 769 | ||
770 | /* | ||
771 | * Other archs parse arguments here. | ||
772 | */ | ||
773 | char * __devinit pcibios_setup(char *str) | ||
774 | { | ||
775 | return str; | ||
776 | } | ||
777 | |||
778 | resource_size_t pcibios_align_resource(void *data, const struct resource *res, | 770 | resource_size_t pcibios_align_resource(void *data, const struct resource *res, |
779 | resource_size_t size, resource_size_t align) | 771 | resource_size_t size, resource_size_t align) |
780 | { | 772 | { |
@@ -884,11 +876,6 @@ void __init sun4m_pci_init_IRQ(void) | |||
884 | sparc_config.load_profile_irq = pcic_load_profile_irq; | 876 | sparc_config.load_profile_irq = pcic_load_profile_irq; |
885 | } | 877 | } |
886 | 878 | ||
887 | int pcibios_assign_resource(struct pci_dev *pdev, int resource) | ||
888 | { | ||
889 | return -ENXIO; | ||
890 | } | ||
891 | |||
892 | /* | 879 | /* |
893 | * This probably belongs here rather than ioport.c because | 880 | * This probably belongs here rather than ioport.c because |
894 | * we do not want this crud linked into SBus kernels. | 881 | * we do not want this crud linked into SBus kernels. |
diff --git a/arch/tile/kernel/pci.c b/arch/tile/kernel/pci.c index b56d12bf5900..0fdd99d0d8b7 100644 --- a/arch/tile/kernel/pci.c +++ b/arch/tile/kernel/pci.c | |||
@@ -310,6 +310,7 @@ int __init pcibios_init(void) | |||
310 | if (pci_scan_flags[i] == 0 && controllers[i].ops != NULL) { | 310 | if (pci_scan_flags[i] == 0 && controllers[i].ops != NULL) { |
311 | struct pci_controller *controller = &controllers[i]; | 311 | struct pci_controller *controller = &controllers[i]; |
312 | struct pci_bus *bus; | 312 | struct pci_bus *bus; |
313 | LIST_HEAD(resources); | ||
313 | 314 | ||
314 | if (tile_init_irqs(i, controller)) { | 315 | if (tile_init_irqs(i, controller)) { |
315 | pr_err("PCI: Could not initialize IRQs\n"); | 316 | pr_err("PCI: Could not initialize IRQs\n"); |
@@ -327,9 +328,11 @@ int __init pcibios_init(void) | |||
327 | * This is inlined in linux/pci.h and calls into | 328 | * This is inlined in linux/pci.h and calls into |
328 | * pci_scan_bus_parented() in probe.c. | 329 | * pci_scan_bus_parented() in probe.c. |
329 | */ | 330 | */ |
330 | bus = pci_scan_bus(0, controller->ops, controller); | 331 | pci_add_resource(&resources, &ioport_resource); |
332 | pci_add_resource(&resources, &iomem_resource); | ||
333 | bus = pci_scan_root_bus(NULL, 0, controller->ops, controller, &resources); | ||
331 | controller->root_bus = bus; | 334 | controller->root_bus = bus; |
332 | controller->last_busno = bus->subordinate; | 335 | controller->last_busno = bus->busn_res.end; |
333 | } | 336 | } |
334 | } | 337 | } |
335 | 338 | ||
@@ -366,7 +369,7 @@ int __init pcibios_init(void) | |||
366 | */ | 369 | */ |
367 | if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI && | 370 | if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI && |
368 | (PCI_SLOT(dev->devfn) == 0)) { | 371 | (PCI_SLOT(dev->devfn) == 0)) { |
369 | next_bus = dev->subordinate; | 372 | next_bus = dev->busn_res.end; |
370 | controllers[i].mem_resources[0] = | 373 | controllers[i].mem_resources[0] = |
371 | *next_bus->resource[0]; | 374 | *next_bus->resource[0]; |
372 | controllers[i].mem_resources[1] = | 375 | controllers[i].mem_resources[1] = |
@@ -401,16 +404,6 @@ void pcibios_set_master(struct pci_dev *dev) | |||
401 | } | 404 | } |
402 | 405 | ||
403 | /* | 406 | /* |
404 | * This can be called from the generic PCI layer, but doesn't need to | ||
405 | * do anything. | ||
406 | */ | ||
407 | char __devinit *pcibios_setup(char *str) | ||
408 | { | ||
409 | /* Nothing needs to be done. */ | ||
410 | return str; | ||
411 | } | ||
412 | |||
413 | /* | ||
414 | * This is called from the generic Linux layer. | 407 | * This is called from the generic Linux layer. |
415 | */ | 408 | */ |
416 | void __devinit pcibios_update_irq(struct pci_dev *dev, int irq) | 409 | void __devinit pcibios_update_irq(struct pci_dev *dev, int irq) |
diff --git a/arch/unicore32/kernel/pci.c b/arch/unicore32/kernel/pci.c index 2fc2b1ba825e..46cb6c9de6c9 100644 --- a/arch/unicore32/kernel/pci.c +++ b/arch/unicore32/kernel/pci.c | |||
@@ -296,7 +296,7 @@ static int __init pci_common_init(void) | |||
296 | } | 296 | } |
297 | subsys_initcall(pci_common_init); | 297 | subsys_initcall(pci_common_init); |
298 | 298 | ||
299 | char * __devinit pcibios_setup(char *str) | 299 | char * __init pcibios_setup(char *str) |
300 | { | 300 | { |
301 | if (!strcmp(str, "debug")) { | 301 | if (!strcmp(str, "debug")) { |
302 | debug_pci = 1; | 302 | debug_pci = 1; |
diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h index 5ad24a89b19b..73e8eeff22ee 100644 --- a/arch/x86/include/asm/pci_x86.h +++ b/arch/x86/include/asm/pci_x86.h | |||
@@ -104,6 +104,7 @@ struct pci_raw_ops { | |||
104 | extern const struct pci_raw_ops *raw_pci_ops; | 104 | extern const struct pci_raw_ops *raw_pci_ops; |
105 | extern const struct pci_raw_ops *raw_pci_ext_ops; | 105 | extern const struct pci_raw_ops *raw_pci_ext_ops; |
106 | 106 | ||
107 | extern const struct pci_raw_ops pci_mmcfg; | ||
107 | extern const struct pci_raw_ops pci_direct_conf1; | 108 | extern const struct pci_raw_ops pci_direct_conf1; |
108 | extern bool port_cf9_safe; | 109 | extern bool port_cf9_safe; |
109 | 110 | ||
@@ -139,6 +140,12 @@ struct pci_mmcfg_region { | |||
139 | 140 | ||
140 | extern int __init pci_mmcfg_arch_init(void); | 141 | extern int __init pci_mmcfg_arch_init(void); |
141 | extern void __init pci_mmcfg_arch_free(void); | 142 | extern void __init pci_mmcfg_arch_free(void); |
143 | extern int __devinit pci_mmcfg_arch_map(struct pci_mmcfg_region *cfg); | ||
144 | extern void pci_mmcfg_arch_unmap(struct pci_mmcfg_region *cfg); | ||
145 | extern int __devinit pci_mmconfig_insert(struct device *dev, | ||
146 | u16 seg, u8 start, | ||
147 | u8 end, phys_addr_t addr); | ||
148 | extern int pci_mmconfig_delete(u16 seg, u8 start, u8 end); | ||
142 | extern struct pci_mmcfg_region *pci_mmconfig_lookup(int segment, int bus); | 149 | extern struct pci_mmcfg_region *pci_mmconfig_lookup(int segment, int bus); |
143 | 150 | ||
144 | extern struct list_head pci_mmcfg_list; | 151 | extern struct list_head pci_mmcfg_list; |
diff --git a/arch/x86/kernel/quirks.c b/arch/x86/kernel/quirks.c index 03920a15a632..1b27de563561 100644 --- a/arch/x86/kernel/quirks.c +++ b/arch/x86/kernel/quirks.c | |||
@@ -512,7 +512,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SBX00_SMBUS, | |||
512 | 512 | ||
513 | #if defined(CONFIG_PCI) && defined(CONFIG_NUMA) | 513 | #if defined(CONFIG_PCI) && defined(CONFIG_NUMA) |
514 | /* Set correct numa_node information for AMD NB functions */ | 514 | /* Set correct numa_node information for AMD NB functions */ |
515 | static void __init quirk_amd_nb_node(struct pci_dev *dev) | 515 | static void __devinit quirk_amd_nb_node(struct pci_dev *dev) |
516 | { | 516 | { |
517 | struct pci_dev *nb_ht; | 517 | struct pci_dev *nb_ht; |
518 | unsigned int devfn; | 518 | unsigned int devfn; |
diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c index fc09c2754e08..505acdd6d600 100644 --- a/arch/x86/pci/acpi.c +++ b/arch/x86/pci/acpi.c | |||
@@ -12,8 +12,13 @@ struct pci_root_info { | |||
12 | char name[16]; | 12 | char name[16]; |
13 | unsigned int res_num; | 13 | unsigned int res_num; |
14 | struct resource *res; | 14 | struct resource *res; |
15 | int busnum; | ||
16 | struct pci_sysdata sd; | 15 | struct pci_sysdata sd; |
16 | #ifdef CONFIG_PCI_MMCONFIG | ||
17 | bool mcfg_added; | ||
18 | u16 segment; | ||
19 | u8 start_bus; | ||
20 | u8 end_bus; | ||
21 | #endif | ||
17 | }; | 22 | }; |
18 | 23 | ||
19 | static bool pci_use_crs = true; | 24 | static bool pci_use_crs = true; |
@@ -120,6 +125,81 @@ void __init pci_acpi_crs_quirks(void) | |||
120 | pci_use_crs ? "nocrs" : "use_crs"); | 125 | pci_use_crs ? "nocrs" : "use_crs"); |
121 | } | 126 | } |
122 | 127 | ||
128 | #ifdef CONFIG_PCI_MMCONFIG | ||
129 | static int __devinit check_segment(u16 seg, struct device *dev, char *estr) | ||
130 | { | ||
131 | if (seg) { | ||
132 | dev_err(dev, | ||
133 | "%s can't access PCI configuration " | ||
134 | "space under this host bridge.\n", | ||
135 | estr); | ||
136 | return -EIO; | ||
137 | } | ||
138 | |||
139 | /* | ||
140 | * Failure in adding MMCFG information is not fatal, | ||
141 | * just can't access extended configuration space of | ||
142 | * devices under this host bridge. | ||
143 | */ | ||
144 | dev_warn(dev, | ||
145 | "%s can't access extended PCI configuration " | ||
146 | "space under this bridge.\n", | ||
147 | estr); | ||
148 | |||
149 | return 0; | ||
150 | } | ||
151 | |||
152 | static int __devinit setup_mcfg_map(struct pci_root_info *info, | ||
153 | u16 seg, u8 start, u8 end, | ||
154 | phys_addr_t addr) | ||
155 | { | ||
156 | int result; | ||
157 | struct device *dev = &info->bridge->dev; | ||
158 | |||
159 | info->start_bus = start; | ||
160 | info->end_bus = end; | ||
161 | info->mcfg_added = false; | ||
162 | |||
163 | /* return success if MMCFG is not in use */ | ||
164 | if (raw_pci_ext_ops && raw_pci_ext_ops != &pci_mmcfg) | ||
165 | return 0; | ||
166 | |||
167 | if (!(pci_probe & PCI_PROBE_MMCONF)) | ||
168 | return check_segment(seg, dev, "MMCONFIG is disabled,"); | ||
169 | |||
170 | result = pci_mmconfig_insert(dev, seg, start, end, addr); | ||
171 | if (result == 0) { | ||
172 | /* enable MMCFG if it hasn't been enabled yet */ | ||
173 | if (raw_pci_ext_ops == NULL) | ||
174 | raw_pci_ext_ops = &pci_mmcfg; | ||
175 | info->mcfg_added = true; | ||
176 | } else if (result != -EEXIST) | ||
177 | return check_segment(seg, dev, | ||
178 | "fail to add MMCONFIG information,"); | ||
179 | |||
180 | return 0; | ||
181 | } | ||
182 | |||
183 | static void teardown_mcfg_map(struct pci_root_info *info) | ||
184 | { | ||
185 | if (info->mcfg_added) { | ||
186 | pci_mmconfig_delete(info->segment, info->start_bus, | ||
187 | info->end_bus); | ||
188 | info->mcfg_added = false; | ||
189 | } | ||
190 | } | ||
191 | #else | ||
192 | static int __devinit setup_mcfg_map(struct pci_root_info *info, | ||
193 | u16 seg, u8 start, u8 end, | ||
194 | phys_addr_t addr) | ||
195 | { | ||
196 | return 0; | ||
197 | } | ||
198 | static void teardown_mcfg_map(struct pci_root_info *info) | ||
199 | { | ||
200 | } | ||
201 | #endif | ||
202 | |||
123 | static acpi_status | 203 | static acpi_status |
124 | resource_to_addr(struct acpi_resource *resource, | 204 | resource_to_addr(struct acpi_resource *resource, |
125 | struct acpi_resource_address64 *addr) | 205 | struct acpi_resource_address64 *addr) |
@@ -234,13 +314,6 @@ setup_resource(struct acpi_resource *acpi_res, void *data) | |||
234 | } | 314 | } |
235 | 315 | ||
236 | info->res_num++; | 316 | info->res_num++; |
237 | if (addr.translation_offset) | ||
238 | dev_info(&info->bridge->dev, "host bridge window %pR " | ||
239 | "(PCI address [%#llx-%#llx])\n", | ||
240 | res, res->start - addr.translation_offset, | ||
241 | res->end - addr.translation_offset); | ||
242 | else | ||
243 | dev_info(&info->bridge->dev, "host bridge window %pR\n", res); | ||
244 | 317 | ||
245 | return AE_OK; | 318 | return AE_OK; |
246 | } | 319 | } |
@@ -332,8 +405,11 @@ static void __release_pci_root_info(struct pci_root_info *info) | |||
332 | 405 | ||
333 | free_pci_root_info_res(info); | 406 | free_pci_root_info_res(info); |
334 | 407 | ||
408 | teardown_mcfg_map(info); | ||
409 | |||
335 | kfree(info); | 410 | kfree(info); |
336 | } | 411 | } |
412 | |||
337 | static void release_pci_root_info(struct pci_host_bridge *bridge) | 413 | static void release_pci_root_info(struct pci_host_bridge *bridge) |
338 | { | 414 | { |
339 | struct pci_root_info *info = bridge->release_data; | 415 | struct pci_root_info *info = bridge->release_data; |
@@ -347,7 +423,9 @@ probe_pci_root_info(struct pci_root_info *info, struct acpi_device *device, | |||
347 | { | 423 | { |
348 | size_t size; | 424 | size_t size; |
349 | 425 | ||
426 | sprintf(info->name, "PCI Bus %04x:%02x", domain, busnum); | ||
350 | info->bridge = device; | 427 | info->bridge = device; |
428 | |||
351 | info->res_num = 0; | 429 | info->res_num = 0; |
352 | acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_resource, | 430 | acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_resource, |
353 | info); | 431 | info); |
@@ -360,8 +438,6 @@ probe_pci_root_info(struct pci_root_info *info, struct acpi_device *device, | |||
360 | if (!info->res) | 438 | if (!info->res) |
361 | return; | 439 | return; |
362 | 440 | ||
363 | sprintf(info->name, "PCI Bus %04x:%02x", domain, busnum); | ||
364 | |||
365 | acpi_walk_resources(device->handle, METHOD_NAME__CRS, setup_resource, | 441 | acpi_walk_resources(device->handle, METHOD_NAME__CRS, setup_resource, |
366 | info); | 442 | info); |
367 | } | 443 | } |
@@ -373,7 +449,7 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root) | |||
373 | int domain = root->segment; | 449 | int domain = root->segment; |
374 | int busnum = root->secondary.start; | 450 | int busnum = root->secondary.start; |
375 | LIST_HEAD(resources); | 451 | LIST_HEAD(resources); |
376 | struct pci_bus *bus; | 452 | struct pci_bus *bus = NULL; |
377 | struct pci_sysdata *sd; | 453 | struct pci_sysdata *sd; |
378 | int node; | 454 | int node; |
379 | #ifdef CONFIG_ACPI_NUMA | 455 | #ifdef CONFIG_ACPI_NUMA |
@@ -426,6 +502,8 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root) | |||
426 | } else { | 502 | } else { |
427 | probe_pci_root_info(info, device, busnum, domain); | 503 | probe_pci_root_info(info, device, busnum, domain); |
428 | 504 | ||
505 | /* insert busn res at first */ | ||
506 | pci_add_resource(&resources, &root->secondary); | ||
429 | /* | 507 | /* |
430 | * _CRS with no apertures is normal, so only fall back to | 508 | * _CRS with no apertures is normal, so only fall back to |
431 | * defaults or native bridge info if we're ignoring _CRS. | 509 | * defaults or native bridge info if we're ignoring _CRS. |
@@ -437,10 +515,13 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root) | |||
437 | x86_pci_root_bus_resources(busnum, &resources); | 515 | x86_pci_root_bus_resources(busnum, &resources); |
438 | } | 516 | } |
439 | 517 | ||
440 | bus = pci_create_root_bus(NULL, busnum, &pci_root_ops, sd, | 518 | if (!setup_mcfg_map(info, domain, (u8)root->secondary.start, |
441 | &resources); | 519 | (u8)root->secondary.end, root->mcfg_addr)) |
520 | bus = pci_create_root_bus(NULL, busnum, &pci_root_ops, | ||
521 | sd, &resources); | ||
522 | |||
442 | if (bus) { | 523 | if (bus) { |
443 | bus->subordinate = pci_scan_child_bus(bus); | 524 | pci_scan_child_bus(bus); |
444 | pci_set_host_bridge_release( | 525 | pci_set_host_bridge_release( |
445 | to_pci_host_bridge(bus->bridge), | 526 | to_pci_host_bridge(bus->bridge), |
446 | release_pci_root_info, info); | 527 | release_pci_root_info, info); |
diff --git a/arch/x86/pci/amd_bus.c b/arch/x86/pci/amd_bus.c index 5aed49bff058..e9e6ed5cdf94 100644 --- a/arch/x86/pci/amd_bus.c +++ b/arch/x86/pci/amd_bus.c | |||
@@ -121,7 +121,6 @@ static int __init early_fill_mp_bus_info(void) | |||
121 | link = (reg >> 8) & 0x03; | 121 | link = (reg >> 8) & 0x03; |
122 | 122 | ||
123 | info = alloc_pci_root_info(min_bus, max_bus, node, link); | 123 | info = alloc_pci_root_info(min_bus, max_bus, node, link); |
124 | sprintf(info->name, "PCI Bus #%02x", min_bus); | ||
125 | } | 124 | } |
126 | 125 | ||
127 | /* get the default node and link for left over res */ | 126 | /* get the default node and link for left over res */ |
@@ -300,9 +299,9 @@ static int __init early_fill_mp_bus_info(void) | |||
300 | int busnum; | 299 | int busnum; |
301 | struct pci_root_res *root_res; | 300 | struct pci_root_res *root_res; |
302 | 301 | ||
303 | busnum = info->bus_min; | 302 | busnum = info->busn.start; |
304 | printk(KERN_DEBUG "bus: [%02x, %02x] on node %x link %x\n", | 303 | printk(KERN_DEBUG "bus: %pR on node %x link %x\n", |
305 | info->bus_min, info->bus_max, info->node, info->link); | 304 | &info->busn, info->node, info->link); |
306 | list_for_each_entry(root_res, &info->resources, list) | 305 | list_for_each_entry(root_res, &info->resources, list) |
307 | printk(KERN_DEBUG "bus: %02x %pR\n", | 306 | printk(KERN_DEBUG "bus: %02x %pR\n", |
308 | busnum, &root_res->res); | 307 | busnum, &root_res->res); |
diff --git a/arch/x86/pci/bus_numa.c b/arch/x86/pci/bus_numa.c index 306579f7d0fd..d37e2fec97e5 100644 --- a/arch/x86/pci/bus_numa.c +++ b/arch/x86/pci/bus_numa.c | |||
@@ -14,7 +14,7 @@ static struct pci_root_info *x86_find_pci_root_info(int bus) | |||
14 | return NULL; | 14 | return NULL; |
15 | 15 | ||
16 | list_for_each_entry(info, &pci_root_infos, list) | 16 | list_for_each_entry(info, &pci_root_infos, list) |
17 | if (info->bus_min == bus) | 17 | if (info->busn.start == bus) |
18 | return info; | 18 | return info; |
19 | 19 | ||
20 | return NULL; | 20 | return NULL; |
@@ -24,6 +24,8 @@ void x86_pci_root_bus_resources(int bus, struct list_head *resources) | |||
24 | { | 24 | { |
25 | struct pci_root_info *info = x86_find_pci_root_info(bus); | 25 | struct pci_root_info *info = x86_find_pci_root_info(bus); |
26 | struct pci_root_res *root_res; | 26 | struct pci_root_res *root_res; |
27 | struct pci_host_bridge_window *window; | ||
28 | bool found = false; | ||
27 | 29 | ||
28 | if (!info) | 30 | if (!info) |
29 | goto default_resources; | 31 | goto default_resources; |
@@ -31,6 +33,16 @@ void x86_pci_root_bus_resources(int bus, struct list_head *resources) | |||
31 | printk(KERN_DEBUG "PCI: root bus %02x: hardware-probed resources\n", | 33 | printk(KERN_DEBUG "PCI: root bus %02x: hardware-probed resources\n", |
32 | bus); | 34 | bus); |
33 | 35 | ||
36 | /* already added by acpi ? */ | ||
37 | list_for_each_entry(window, resources, list) | ||
38 | if (window->res->flags & IORESOURCE_BUS) { | ||
39 | found = true; | ||
40 | break; | ||
41 | } | ||
42 | |||
43 | if (!found) | ||
44 | pci_add_resource(resources, &info->busn); | ||
45 | |||
34 | list_for_each_entry(root_res, &info->resources, list) { | 46 | list_for_each_entry(root_res, &info->resources, list) { |
35 | struct resource *res; | 47 | struct resource *res; |
36 | struct resource *root; | 48 | struct resource *root; |
@@ -66,9 +78,13 @@ struct pci_root_info __init *alloc_pci_root_info(int bus_min, int bus_max, | |||
66 | if (!info) | 78 | if (!info) |
67 | return info; | 79 | return info; |
68 | 80 | ||
81 | sprintf(info->name, "PCI Bus #%02x", bus_min); | ||
82 | |||
69 | INIT_LIST_HEAD(&info->resources); | 83 | INIT_LIST_HEAD(&info->resources); |
70 | info->bus_min = bus_min; | 84 | info->busn.name = info->name; |
71 | info->bus_max = bus_max; | 85 | info->busn.start = bus_min; |
86 | info->busn.end = bus_max; | ||
87 | info->busn.flags = IORESOURCE_BUS; | ||
72 | info->node = node; | 88 | info->node = node; |
73 | info->link = link; | 89 | info->link = link; |
74 | 90 | ||
diff --git a/arch/x86/pci/bus_numa.h b/arch/x86/pci/bus_numa.h index 226a466b2b2b..ff8f65b04574 100644 --- a/arch/x86/pci/bus_numa.h +++ b/arch/x86/pci/bus_numa.h | |||
@@ -13,8 +13,7 @@ struct pci_root_info { | |||
13 | struct list_head list; | 13 | struct list_head list; |
14 | char name[12]; | 14 | char name[12]; |
15 | struct list_head resources; | 15 | struct list_head resources; |
16 | int bus_min; | 16 | struct resource busn; |
17 | int bus_max; | ||
18 | int node; | 17 | int node; |
19 | int link; | 18 | int link; |
20 | }; | 19 | }; |
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c index 0ad990a20d4a..720e973fc34a 100644 --- a/arch/x86/pci/common.c +++ b/arch/x86/pci/common.c | |||
@@ -494,7 +494,7 @@ int __init pcibios_init(void) | |||
494 | return 0; | 494 | return 0; |
495 | } | 495 | } |
496 | 496 | ||
497 | char * __devinit pcibios_setup(char *str) | 497 | char * __init pcibios_setup(char *str) |
498 | { | 498 | { |
499 | if (!strcmp(str, "off")) { | 499 | if (!strcmp(str, "off")) { |
500 | pci_probe = 0; | 500 | pci_probe = 0; |
diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c index 301e325992f6..937bcece7006 100644 --- a/arch/x86/pci/mmconfig-shared.c +++ b/arch/x86/pci/mmconfig-shared.c | |||
@@ -17,6 +17,8 @@ | |||
17 | #include <linux/bitmap.h> | 17 | #include <linux/bitmap.h> |
18 | #include <linux/dmi.h> | 18 | #include <linux/dmi.h> |
19 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
20 | #include <linux/mutex.h> | ||
21 | #include <linux/rculist.h> | ||
20 | #include <asm/e820.h> | 22 | #include <asm/e820.h> |
21 | #include <asm/pci_x86.h> | 23 | #include <asm/pci_x86.h> |
22 | #include <asm/acpi.h> | 24 | #include <asm/acpi.h> |
@@ -24,7 +26,9 @@ | |||
24 | #define PREFIX "PCI: " | 26 | #define PREFIX "PCI: " |
25 | 27 | ||
26 | /* Indicate if the mmcfg resources have been placed into the resource table. */ | 28 | /* Indicate if the mmcfg resources have been placed into the resource table. */ |
27 | static int __initdata pci_mmcfg_resources_inserted; | 29 | static bool pci_mmcfg_running_state; |
30 | static bool pci_mmcfg_arch_init_failed; | ||
31 | static DEFINE_MUTEX(pci_mmcfg_lock); | ||
28 | 32 | ||
29 | LIST_HEAD(pci_mmcfg_list); | 33 | LIST_HEAD(pci_mmcfg_list); |
30 | 34 | ||
@@ -45,24 +49,25 @@ static __init void free_all_mmcfg(void) | |||
45 | pci_mmconfig_remove(cfg); | 49 | pci_mmconfig_remove(cfg); |
46 | } | 50 | } |
47 | 51 | ||
48 | static __init void list_add_sorted(struct pci_mmcfg_region *new) | 52 | static __devinit void list_add_sorted(struct pci_mmcfg_region *new) |
49 | { | 53 | { |
50 | struct pci_mmcfg_region *cfg; | 54 | struct pci_mmcfg_region *cfg; |
51 | 55 | ||
52 | /* keep list sorted by segment and starting bus number */ | 56 | /* keep list sorted by segment and starting bus number */ |
53 | list_for_each_entry(cfg, &pci_mmcfg_list, list) { | 57 | list_for_each_entry_rcu(cfg, &pci_mmcfg_list, list) { |
54 | if (cfg->segment > new->segment || | 58 | if (cfg->segment > new->segment || |
55 | (cfg->segment == new->segment && | 59 | (cfg->segment == new->segment && |
56 | cfg->start_bus >= new->start_bus)) { | 60 | cfg->start_bus >= new->start_bus)) { |
57 | list_add_tail(&new->list, &cfg->list); | 61 | list_add_tail_rcu(&new->list, &cfg->list); |
58 | return; | 62 | return; |
59 | } | 63 | } |
60 | } | 64 | } |
61 | list_add_tail(&new->list, &pci_mmcfg_list); | 65 | list_add_tail_rcu(&new->list, &pci_mmcfg_list); |
62 | } | 66 | } |
63 | 67 | ||
64 | static __init struct pci_mmcfg_region *pci_mmconfig_add(int segment, int start, | 68 | static __devinit struct pci_mmcfg_region *pci_mmconfig_alloc(int segment, |
65 | int end, u64 addr) | 69 | int start, |
70 | int end, u64 addr) | ||
66 | { | 71 | { |
67 | struct pci_mmcfg_region *new; | 72 | struct pci_mmcfg_region *new; |
68 | struct resource *res; | 73 | struct resource *res; |
@@ -79,8 +84,6 @@ static __init struct pci_mmcfg_region *pci_mmconfig_add(int segment, int start, | |||
79 | new->start_bus = start; | 84 | new->start_bus = start; |
80 | new->end_bus = end; | 85 | new->end_bus = end; |
81 | 86 | ||
82 | list_add_sorted(new); | ||
83 | |||
84 | res = &new->res; | 87 | res = &new->res; |
85 | res->start = addr + PCI_MMCFG_BUS_OFFSET(start); | 88 | res->start = addr + PCI_MMCFG_BUS_OFFSET(start); |
86 | res->end = addr + PCI_MMCFG_BUS_OFFSET(end + 1) - 1; | 89 | res->end = addr + PCI_MMCFG_BUS_OFFSET(end + 1) - 1; |
@@ -89,9 +92,25 @@ static __init struct pci_mmcfg_region *pci_mmconfig_add(int segment, int start, | |||
89 | "PCI MMCONFIG %04x [bus %02x-%02x]", segment, start, end); | 92 | "PCI MMCONFIG %04x [bus %02x-%02x]", segment, start, end); |
90 | res->name = new->name; | 93 | res->name = new->name; |
91 | 94 | ||
92 | printk(KERN_INFO PREFIX "MMCONFIG for domain %04x [bus %02x-%02x] at " | 95 | return new; |
93 | "%pR (base %#lx)\n", segment, start, end, &new->res, | 96 | } |
94 | (unsigned long) addr); | 97 | |
98 | static __init struct pci_mmcfg_region *pci_mmconfig_add(int segment, int start, | ||
99 | int end, u64 addr) | ||
100 | { | ||
101 | struct pci_mmcfg_region *new; | ||
102 | |||
103 | new = pci_mmconfig_alloc(segment, start, end, addr); | ||
104 | if (new) { | ||
105 | mutex_lock(&pci_mmcfg_lock); | ||
106 | list_add_sorted(new); | ||
107 | mutex_unlock(&pci_mmcfg_lock); | ||
108 | |||
109 | pr_info(PREFIX | ||
110 | "MMCONFIG for domain %04x [bus %02x-%02x] at %pR " | ||
111 | "(base %#lx)\n", | ||
112 | segment, start, end, &new->res, (unsigned long)addr); | ||
113 | } | ||
95 | 114 | ||
96 | return new; | 115 | return new; |
97 | } | 116 | } |
@@ -100,7 +119,7 @@ struct pci_mmcfg_region *pci_mmconfig_lookup(int segment, int bus) | |||
100 | { | 119 | { |
101 | struct pci_mmcfg_region *cfg; | 120 | struct pci_mmcfg_region *cfg; |
102 | 121 | ||
103 | list_for_each_entry(cfg, &pci_mmcfg_list, list) | 122 | list_for_each_entry_rcu(cfg, &pci_mmcfg_list, list) |
104 | if (cfg->segment == segment && | 123 | if (cfg->segment == segment && |
105 | cfg->start_bus <= bus && bus <= cfg->end_bus) | 124 | cfg->start_bus <= bus && bus <= cfg->end_bus) |
106 | return cfg; | 125 | return cfg; |
@@ -343,8 +362,7 @@ static int __init pci_mmcfg_check_hostbridge(void) | |||
343 | name = pci_mmcfg_probes[i].probe(); | 362 | name = pci_mmcfg_probes[i].probe(); |
344 | 363 | ||
345 | if (name) | 364 | if (name) |
346 | printk(KERN_INFO PREFIX "%s with MMCONFIG support\n", | 365 | pr_info(PREFIX "%s with MMCONFIG support\n", name); |
347 | name); | ||
348 | } | 366 | } |
349 | 367 | ||
350 | /* some end_bus_number is crazy, fix it */ | 368 | /* some end_bus_number is crazy, fix it */ |
@@ -353,19 +371,8 @@ static int __init pci_mmcfg_check_hostbridge(void) | |||
353 | return !list_empty(&pci_mmcfg_list); | 371 | return !list_empty(&pci_mmcfg_list); |
354 | } | 372 | } |
355 | 373 | ||
356 | static void __init pci_mmcfg_insert_resources(void) | 374 | static acpi_status __devinit check_mcfg_resource(struct acpi_resource *res, |
357 | { | 375 | void *data) |
358 | struct pci_mmcfg_region *cfg; | ||
359 | |||
360 | list_for_each_entry(cfg, &pci_mmcfg_list, list) | ||
361 | insert_resource(&iomem_resource, &cfg->res); | ||
362 | |||
363 | /* Mark that the resources have been inserted. */ | ||
364 | pci_mmcfg_resources_inserted = 1; | ||
365 | } | ||
366 | |||
367 | static acpi_status __init check_mcfg_resource(struct acpi_resource *res, | ||
368 | void *data) | ||
369 | { | 376 | { |
370 | struct resource *mcfg_res = data; | 377 | struct resource *mcfg_res = data; |
371 | struct acpi_resource_address64 address; | 378 | struct acpi_resource_address64 address; |
@@ -401,8 +408,8 @@ static acpi_status __init check_mcfg_resource(struct acpi_resource *res, | |||
401 | return AE_OK; | 408 | return AE_OK; |
402 | } | 409 | } |
403 | 410 | ||
404 | static acpi_status __init find_mboard_resource(acpi_handle handle, u32 lvl, | 411 | static acpi_status __devinit find_mboard_resource(acpi_handle handle, u32 lvl, |
405 | void *context, void **rv) | 412 | void *context, void **rv) |
406 | { | 413 | { |
407 | struct resource *mcfg_res = context; | 414 | struct resource *mcfg_res = context; |
408 | 415 | ||
@@ -415,7 +422,7 @@ static acpi_status __init find_mboard_resource(acpi_handle handle, u32 lvl, | |||
415 | return AE_OK; | 422 | return AE_OK; |
416 | } | 423 | } |
417 | 424 | ||
418 | static int __init is_acpi_reserved(u64 start, u64 end, unsigned not_used) | 425 | static int __devinit is_acpi_reserved(u64 start, u64 end, unsigned not_used) |
419 | { | 426 | { |
420 | struct resource mcfg_res; | 427 | struct resource mcfg_res; |
421 | 428 | ||
@@ -434,13 +441,15 @@ static int __init is_acpi_reserved(u64 start, u64 end, unsigned not_used) | |||
434 | 441 | ||
435 | typedef int (*check_reserved_t)(u64 start, u64 end, unsigned type); | 442 | typedef int (*check_reserved_t)(u64 start, u64 end, unsigned type); |
436 | 443 | ||
437 | static int __init is_mmconf_reserved(check_reserved_t is_reserved, | 444 | static int __ref is_mmconf_reserved(check_reserved_t is_reserved, |
438 | struct pci_mmcfg_region *cfg, int with_e820) | 445 | struct pci_mmcfg_region *cfg, |
446 | struct device *dev, int with_e820) | ||
439 | { | 447 | { |
440 | u64 addr = cfg->res.start; | 448 | u64 addr = cfg->res.start; |
441 | u64 size = resource_size(&cfg->res); | 449 | u64 size = resource_size(&cfg->res); |
442 | u64 old_size = size; | 450 | u64 old_size = size; |
443 | int valid = 0, num_buses; | 451 | int num_buses; |
452 | char *method = with_e820 ? "E820" : "ACPI motherboard resources"; | ||
444 | 453 | ||
445 | while (!is_reserved(addr, addr + size, E820_RESERVED)) { | 454 | while (!is_reserved(addr, addr + size, E820_RESERVED)) { |
446 | size >>= 1; | 455 | size >>= 1; |
@@ -448,30 +457,76 @@ static int __init is_mmconf_reserved(check_reserved_t is_reserved, | |||
448 | break; | 457 | break; |
449 | } | 458 | } |
450 | 459 | ||
451 | if (size >= (16UL<<20) || size == old_size) { | 460 | if (size < (16UL<<20) && size != old_size) |
452 | printk(KERN_INFO PREFIX "MMCONFIG at %pR reserved in %s\n", | 461 | return 0; |
453 | &cfg->res, | 462 | |
454 | with_e820 ? "E820" : "ACPI motherboard resources"); | 463 | if (dev) |
455 | valid = 1; | 464 | dev_info(dev, "MMCONFIG at %pR reserved in %s\n", |
456 | 465 | &cfg->res, method); | |
457 | if (old_size != size) { | 466 | else |
458 | /* update end_bus */ | 467 | pr_info(PREFIX "MMCONFIG at %pR reserved in %s\n", |
459 | cfg->end_bus = cfg->start_bus + ((size>>20) - 1); | 468 | &cfg->res, method); |
460 | num_buses = cfg->end_bus - cfg->start_bus + 1; | 469 | |
461 | cfg->res.end = cfg->res.start + | 470 | if (old_size != size) { |
462 | PCI_MMCFG_BUS_OFFSET(num_buses) - 1; | 471 | /* update end_bus */ |
463 | snprintf(cfg->name, PCI_MMCFG_RESOURCE_NAME_LEN, | 472 | cfg->end_bus = cfg->start_bus + ((size>>20) - 1); |
464 | "PCI MMCONFIG %04x [bus %02x-%02x]", | 473 | num_buses = cfg->end_bus - cfg->start_bus + 1; |
465 | cfg->segment, cfg->start_bus, cfg->end_bus); | 474 | cfg->res.end = cfg->res.start + |
466 | printk(KERN_INFO PREFIX | 475 | PCI_MMCFG_BUS_OFFSET(num_buses) - 1; |
467 | "MMCONFIG for %04x [bus%02x-%02x] " | 476 | snprintf(cfg->name, PCI_MMCFG_RESOURCE_NAME_LEN, |
468 | "at %pR (base %#lx) (size reduced!)\n", | 477 | "PCI MMCONFIG %04x [bus %02x-%02x]", |
469 | cfg->segment, cfg->start_bus, cfg->end_bus, | 478 | cfg->segment, cfg->start_bus, cfg->end_bus); |
470 | &cfg->res, (unsigned long) cfg->address); | 479 | |
471 | } | 480 | if (dev) |
481 | dev_info(dev, | ||
482 | "MMCONFIG " | ||
483 | "at %pR (base %#lx) (size reduced!)\n", | ||
484 | &cfg->res, (unsigned long) cfg->address); | ||
485 | else | ||
486 | pr_info(PREFIX | ||
487 | "MMCONFIG for %04x [bus%02x-%02x] " | ||
488 | "at %pR (base %#lx) (size reduced!)\n", | ||
489 | cfg->segment, cfg->start_bus, cfg->end_bus, | ||
490 | &cfg->res, (unsigned long) cfg->address); | ||
472 | } | 491 | } |
473 | 492 | ||
474 | return valid; | 493 | return 1; |
494 | } | ||
495 | |||
496 | static int __ref pci_mmcfg_check_reserved(struct device *dev, | ||
497 | struct pci_mmcfg_region *cfg, int early) | ||
498 | { | ||
499 | if (!early && !acpi_disabled) { | ||
500 | if (is_mmconf_reserved(is_acpi_reserved, cfg, dev, 0)) | ||
501 | return 1; | ||
502 | |||
503 | if (dev) | ||
504 | dev_info(dev, FW_INFO | ||
505 | "MMCONFIG at %pR not reserved in " | ||
506 | "ACPI motherboard resources\n", | ||
507 | &cfg->res); | ||
508 | else | ||
509 | pr_info(FW_INFO PREFIX | ||
510 | "MMCONFIG at %pR not reserved in " | ||
511 | "ACPI motherboard resources\n", | ||
512 | &cfg->res); | ||
513 | } | ||
514 | |||
515 | /* | ||
516 | * e820_all_mapped() is marked as __init. | ||
517 | * All entries from ACPI MCFG table have been checked at boot time. | ||
518 | * For MCFG information constructed from hotpluggable host bridge's | ||
519 | * _CBA method, just assume it's reserved. | ||
520 | */ | ||
521 | if (pci_mmcfg_running_state) | ||
522 | return 1; | ||
523 | |||
524 | /* Don't try to do this check unless configuration | ||
525 | type 1 is available. how about type 2 ?*/ | ||
526 | if (raw_pci_ops) | ||
527 | return is_mmconf_reserved(e820_all_mapped, cfg, dev, 1); | ||
528 | |||
529 | return 0; | ||
475 | } | 530 | } |
476 | 531 | ||
477 | static void __init pci_mmcfg_reject_broken(int early) | 532 | static void __init pci_mmcfg_reject_broken(int early) |
@@ -479,38 +534,14 @@ static void __init pci_mmcfg_reject_broken(int early) | |||
479 | struct pci_mmcfg_region *cfg; | 534 | struct pci_mmcfg_region *cfg; |
480 | 535 | ||
481 | list_for_each_entry(cfg, &pci_mmcfg_list, list) { | 536 | list_for_each_entry(cfg, &pci_mmcfg_list, list) { |
482 | int valid = 0; | 537 | if (pci_mmcfg_check_reserved(NULL, cfg, early) == 0) { |
483 | 538 | pr_info(PREFIX "not using MMCONFIG\n"); | |
484 | if (!early && !acpi_disabled) { | 539 | free_all_mmcfg(); |
485 | valid = is_mmconf_reserved(is_acpi_reserved, cfg, 0); | 540 | return; |
486 | |||
487 | if (valid) | ||
488 | continue; | ||
489 | else | ||
490 | printk(KERN_ERR FW_BUG PREFIX | ||
491 | "MMCONFIG at %pR not reserved in " | ||
492 | "ACPI motherboard resources\n", | ||
493 | &cfg->res); | ||
494 | } | 541 | } |
495 | |||
496 | /* Don't try to do this check unless configuration | ||
497 | type 1 is available. how about type 2 ?*/ | ||
498 | if (raw_pci_ops) | ||
499 | valid = is_mmconf_reserved(e820_all_mapped, cfg, 1); | ||
500 | |||
501 | if (!valid) | ||
502 | goto reject; | ||
503 | } | 542 | } |
504 | |||
505 | return; | ||
506 | |||
507 | reject: | ||
508 | printk(KERN_INFO PREFIX "not using MMCONFIG\n"); | ||
509 | free_all_mmcfg(); | ||
510 | } | 543 | } |
511 | 544 | ||
512 | static int __initdata known_bridge; | ||
513 | |||
514 | static int __init acpi_mcfg_check_entry(struct acpi_table_mcfg *mcfg, | 545 | static int __init acpi_mcfg_check_entry(struct acpi_table_mcfg *mcfg, |
515 | struct acpi_mcfg_allocation *cfg) | 546 | struct acpi_mcfg_allocation *cfg) |
516 | { | 547 | { |
@@ -529,7 +560,7 @@ static int __init acpi_mcfg_check_entry(struct acpi_table_mcfg *mcfg, | |||
529 | return 0; | 560 | return 0; |
530 | } | 561 | } |
531 | 562 | ||
532 | printk(KERN_ERR PREFIX "MCFG region for %04x [bus %02x-%02x] at %#llx " | 563 | pr_err(PREFIX "MCFG region for %04x [bus %02x-%02x] at %#llx " |
533 | "is above 4GB, ignored\n", cfg->pci_segment, | 564 | "is above 4GB, ignored\n", cfg->pci_segment, |
534 | cfg->start_bus_number, cfg->end_bus_number, cfg->address); | 565 | cfg->start_bus_number, cfg->end_bus_number, cfg->address); |
535 | return -EINVAL; | 566 | return -EINVAL; |
@@ -556,7 +587,7 @@ static int __init pci_parse_mcfg(struct acpi_table_header *header) | |||
556 | i -= sizeof(struct acpi_mcfg_allocation); | 587 | i -= sizeof(struct acpi_mcfg_allocation); |
557 | }; | 588 | }; |
558 | if (entries == 0) { | 589 | if (entries == 0) { |
559 | printk(KERN_ERR PREFIX "MMCONFIG has no entries\n"); | 590 | pr_err(PREFIX "MMCONFIG has no entries\n"); |
560 | return -ENODEV; | 591 | return -ENODEV; |
561 | } | 592 | } |
562 | 593 | ||
@@ -570,8 +601,7 @@ static int __init pci_parse_mcfg(struct acpi_table_header *header) | |||
570 | 601 | ||
571 | if (pci_mmconfig_add(cfg->pci_segment, cfg->start_bus_number, | 602 | if (pci_mmconfig_add(cfg->pci_segment, cfg->start_bus_number, |
572 | cfg->end_bus_number, cfg->address) == NULL) { | 603 | cfg->end_bus_number, cfg->address) == NULL) { |
573 | printk(KERN_WARNING PREFIX | 604 | pr_warn(PREFIX "no memory for MCFG entries\n"); |
574 | "no memory for MCFG entries\n"); | ||
575 | free_all_mmcfg(); | 605 | free_all_mmcfg(); |
576 | return -ENOMEM; | 606 | return -ENOMEM; |
577 | } | 607 | } |
@@ -582,28 +612,7 @@ static int __init pci_parse_mcfg(struct acpi_table_header *header) | |||
582 | 612 | ||
583 | static void __init __pci_mmcfg_init(int early) | 613 | static void __init __pci_mmcfg_init(int early) |
584 | { | 614 | { |
585 | /* MMCONFIG disabled */ | ||
586 | if ((pci_probe & PCI_PROBE_MMCONF) == 0) | ||
587 | return; | ||
588 | |||
589 | /* MMCONFIG already enabled */ | ||
590 | if (!early && !(pci_probe & PCI_PROBE_MASK & ~PCI_PROBE_MMCONF)) | ||
591 | return; | ||
592 | |||
593 | /* for late to exit */ | ||
594 | if (known_bridge) | ||
595 | return; | ||
596 | |||
597 | if (early) { | ||
598 | if (pci_mmcfg_check_hostbridge()) | ||
599 | known_bridge = 1; | ||
600 | } | ||
601 | |||
602 | if (!known_bridge) | ||
603 | acpi_sfi_table_parse(ACPI_SIG_MCFG, pci_parse_mcfg); | ||
604 | |||
605 | pci_mmcfg_reject_broken(early); | 615 | pci_mmcfg_reject_broken(early); |
606 | |||
607 | if (list_empty(&pci_mmcfg_list)) | 616 | if (list_empty(&pci_mmcfg_list)) |
608 | return; | 617 | return; |
609 | 618 | ||
@@ -620,33 +629,48 @@ static void __init __pci_mmcfg_init(int early) | |||
620 | if (pci_mmcfg_arch_init()) | 629 | if (pci_mmcfg_arch_init()) |
621 | pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF; | 630 | pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF; |
622 | else { | 631 | else { |
623 | /* | 632 | free_all_mmcfg(); |
624 | * Signal not to attempt to insert mmcfg resources because | 633 | pci_mmcfg_arch_init_failed = true; |
625 | * the architecture mmcfg setup could not initialize. | ||
626 | */ | ||
627 | pci_mmcfg_resources_inserted = 1; | ||
628 | } | 634 | } |
629 | } | 635 | } |
630 | 636 | ||
637 | static int __initdata known_bridge; | ||
638 | |||
631 | void __init pci_mmcfg_early_init(void) | 639 | void __init pci_mmcfg_early_init(void) |
632 | { | 640 | { |
633 | __pci_mmcfg_init(1); | 641 | if (pci_probe & PCI_PROBE_MMCONF) { |
642 | if (pci_mmcfg_check_hostbridge()) | ||
643 | known_bridge = 1; | ||
644 | else | ||
645 | acpi_sfi_table_parse(ACPI_SIG_MCFG, pci_parse_mcfg); | ||
646 | __pci_mmcfg_init(1); | ||
647 | } | ||
634 | } | 648 | } |
635 | 649 | ||
636 | void __init pci_mmcfg_late_init(void) | 650 | void __init pci_mmcfg_late_init(void) |
637 | { | 651 | { |
638 | __pci_mmcfg_init(0); | 652 | /* MMCONFIG disabled */ |
653 | if ((pci_probe & PCI_PROBE_MMCONF) == 0) | ||
654 | return; | ||
655 | |||
656 | if (known_bridge) | ||
657 | return; | ||
658 | |||
659 | /* MMCONFIG hasn't been enabled yet, try again */ | ||
660 | if (pci_probe & PCI_PROBE_MASK & ~PCI_PROBE_MMCONF) { | ||
661 | acpi_sfi_table_parse(ACPI_SIG_MCFG, pci_parse_mcfg); | ||
662 | __pci_mmcfg_init(0); | ||
663 | } | ||
639 | } | 664 | } |
640 | 665 | ||
641 | static int __init pci_mmcfg_late_insert_resources(void) | 666 | static int __init pci_mmcfg_late_insert_resources(void) |
642 | { | 667 | { |
643 | /* | 668 | struct pci_mmcfg_region *cfg; |
644 | * If resources are already inserted or we are not using MMCONFIG, | 669 | |
645 | * don't insert the resources. | 670 | pci_mmcfg_running_state = true; |
646 | */ | 671 | |
647 | if ((pci_mmcfg_resources_inserted == 1) || | 672 | /* If we are not using MMCONFIG, don't insert the resources. */ |
648 | (pci_probe & PCI_PROBE_MMCONF) == 0 || | 673 | if ((pci_probe & PCI_PROBE_MMCONF) == 0) |
649 | list_empty(&pci_mmcfg_list)) | ||
650 | return 1; | 674 | return 1; |
651 | 675 | ||
652 | /* | 676 | /* |
@@ -654,7 +678,9 @@ static int __init pci_mmcfg_late_insert_resources(void) | |||
654 | * marked so it won't cause request errors when __request_region is | 678 | * marked so it won't cause request errors when __request_region is |
655 | * called. | 679 | * called. |
656 | */ | 680 | */ |
657 | pci_mmcfg_insert_resources(); | 681 | list_for_each_entry(cfg, &pci_mmcfg_list, list) |
682 | if (!cfg->res.parent) | ||
683 | insert_resource(&iomem_resource, &cfg->res); | ||
658 | 684 | ||
659 | return 0; | 685 | return 0; |
660 | } | 686 | } |
@@ -665,3 +691,101 @@ static int __init pci_mmcfg_late_insert_resources(void) | |||
665 | * with other system resources. | 691 | * with other system resources. |
666 | */ | 692 | */ |
667 | late_initcall(pci_mmcfg_late_insert_resources); | 693 | late_initcall(pci_mmcfg_late_insert_resources); |
694 | |||
695 | /* Add MMCFG information for host bridges */ | ||
696 | int __devinit pci_mmconfig_insert(struct device *dev, | ||
697 | u16 seg, u8 start, u8 end, | ||
698 | phys_addr_t addr) | ||
699 | { | ||
700 | int rc; | ||
701 | struct resource *tmp = NULL; | ||
702 | struct pci_mmcfg_region *cfg; | ||
703 | |||
704 | if (!(pci_probe & PCI_PROBE_MMCONF) || pci_mmcfg_arch_init_failed) | ||
705 | return -ENODEV; | ||
706 | |||
707 | if (start > end) | ||
708 | return -EINVAL; | ||
709 | |||
710 | mutex_lock(&pci_mmcfg_lock); | ||
711 | cfg = pci_mmconfig_lookup(seg, start); | ||
712 | if (cfg) { | ||
713 | if (cfg->end_bus < end) | ||
714 | dev_info(dev, FW_INFO | ||
715 | "MMCONFIG for " | ||
716 | "domain %04x [bus %02x-%02x] " | ||
717 | "only partially covers this bridge\n", | ||
718 | cfg->segment, cfg->start_bus, cfg->end_bus); | ||
719 | mutex_unlock(&pci_mmcfg_lock); | ||
720 | return -EEXIST; | ||
721 | } | ||
722 | |||
723 | if (!addr) { | ||
724 | mutex_unlock(&pci_mmcfg_lock); | ||
725 | return -EINVAL; | ||
726 | } | ||
727 | |||
728 | rc = -EBUSY; | ||
729 | cfg = pci_mmconfig_alloc(seg, start, end, addr); | ||
730 | if (cfg == NULL) { | ||
731 | dev_warn(dev, "fail to add MMCONFIG (out of memory)\n"); | ||
732 | rc = -ENOMEM; | ||
733 | } else if (!pci_mmcfg_check_reserved(dev, cfg, 0)) { | ||
734 | dev_warn(dev, FW_BUG "MMCONFIG %pR isn't reserved\n", | ||
735 | &cfg->res); | ||
736 | } else { | ||
737 | /* Insert resource if it's not in boot stage */ | ||
738 | if (pci_mmcfg_running_state) | ||
739 | tmp = insert_resource_conflict(&iomem_resource, | ||
740 | &cfg->res); | ||
741 | |||
742 | if (tmp) { | ||
743 | dev_warn(dev, | ||
744 | "MMCONFIG %pR conflicts with " | ||
745 | "%s %pR\n", | ||
746 | &cfg->res, tmp->name, tmp); | ||
747 | } else if (pci_mmcfg_arch_map(cfg)) { | ||
748 | dev_warn(dev, "fail to map MMCONFIG %pR.\n", | ||
749 | &cfg->res); | ||
750 | } else { | ||
751 | list_add_sorted(cfg); | ||
752 | dev_info(dev, "MMCONFIG at %pR (base %#lx)\n", | ||
753 | &cfg->res, (unsigned long)addr); | ||
754 | cfg = NULL; | ||
755 | rc = 0; | ||
756 | } | ||
757 | } | ||
758 | |||
759 | if (cfg) { | ||
760 | if (cfg->res.parent) | ||
761 | release_resource(&cfg->res); | ||
762 | kfree(cfg); | ||
763 | } | ||
764 | |||
765 | mutex_unlock(&pci_mmcfg_lock); | ||
766 | |||
767 | return rc; | ||
768 | } | ||
769 | |||
770 | /* Delete MMCFG information for host bridges */ | ||
771 | int pci_mmconfig_delete(u16 seg, u8 start, u8 end) | ||
772 | { | ||
773 | struct pci_mmcfg_region *cfg; | ||
774 | |||
775 | mutex_lock(&pci_mmcfg_lock); | ||
776 | list_for_each_entry_rcu(cfg, &pci_mmcfg_list, list) | ||
777 | if (cfg->segment == seg && cfg->start_bus == start && | ||
778 | cfg->end_bus == end) { | ||
779 | list_del_rcu(&cfg->list); | ||
780 | synchronize_rcu(); | ||
781 | pci_mmcfg_arch_unmap(cfg); | ||
782 | if (cfg->res.parent) | ||
783 | release_resource(&cfg->res); | ||
784 | mutex_unlock(&pci_mmcfg_lock); | ||
785 | kfree(cfg); | ||
786 | return 0; | ||
787 | } | ||
788 | mutex_unlock(&pci_mmcfg_lock); | ||
789 | |||
790 | return -ENOENT; | ||
791 | } | ||
diff --git a/arch/x86/pci/mmconfig_32.c b/arch/x86/pci/mmconfig_32.c index 5372e86834c0..db63ac23e3d9 100644 --- a/arch/x86/pci/mmconfig_32.c +++ b/arch/x86/pci/mmconfig_32.c | |||
@@ -11,6 +11,7 @@ | |||
11 | 11 | ||
12 | #include <linux/pci.h> | 12 | #include <linux/pci.h> |
13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
14 | #include <linux/rcupdate.h> | ||
14 | #include <asm/e820.h> | 15 | #include <asm/e820.h> |
15 | #include <asm/pci_x86.h> | 16 | #include <asm/pci_x86.h> |
16 | #include <acpi/acpi.h> | 17 | #include <acpi/acpi.h> |
@@ -60,9 +61,12 @@ err: *value = -1; | |||
60 | return -EINVAL; | 61 | return -EINVAL; |
61 | } | 62 | } |
62 | 63 | ||
64 | rcu_read_lock(); | ||
63 | base = get_base_addr(seg, bus, devfn); | 65 | base = get_base_addr(seg, bus, devfn); |
64 | if (!base) | 66 | if (!base) { |
67 | rcu_read_unlock(); | ||
65 | goto err; | 68 | goto err; |
69 | } | ||
66 | 70 | ||
67 | raw_spin_lock_irqsave(&pci_config_lock, flags); | 71 | raw_spin_lock_irqsave(&pci_config_lock, flags); |
68 | 72 | ||
@@ -80,6 +84,7 @@ err: *value = -1; | |||
80 | break; | 84 | break; |
81 | } | 85 | } |
82 | raw_spin_unlock_irqrestore(&pci_config_lock, flags); | 86 | raw_spin_unlock_irqrestore(&pci_config_lock, flags); |
87 | rcu_read_unlock(); | ||
83 | 88 | ||
84 | return 0; | 89 | return 0; |
85 | } | 90 | } |
@@ -93,9 +98,12 @@ static int pci_mmcfg_write(unsigned int seg, unsigned int bus, | |||
93 | if ((bus > 255) || (devfn > 255) || (reg > 4095)) | 98 | if ((bus > 255) || (devfn > 255) || (reg > 4095)) |
94 | return -EINVAL; | 99 | return -EINVAL; |
95 | 100 | ||
101 | rcu_read_lock(); | ||
96 | base = get_base_addr(seg, bus, devfn); | 102 | base = get_base_addr(seg, bus, devfn); |
97 | if (!base) | 103 | if (!base) { |
104 | rcu_read_unlock(); | ||
98 | return -EINVAL; | 105 | return -EINVAL; |
106 | } | ||
99 | 107 | ||
100 | raw_spin_lock_irqsave(&pci_config_lock, flags); | 108 | raw_spin_lock_irqsave(&pci_config_lock, flags); |
101 | 109 | ||
@@ -113,11 +121,12 @@ static int pci_mmcfg_write(unsigned int seg, unsigned int bus, | |||
113 | break; | 121 | break; |
114 | } | 122 | } |
115 | raw_spin_unlock_irqrestore(&pci_config_lock, flags); | 123 | raw_spin_unlock_irqrestore(&pci_config_lock, flags); |
124 | rcu_read_unlock(); | ||
116 | 125 | ||
117 | return 0; | 126 | return 0; |
118 | } | 127 | } |
119 | 128 | ||
120 | static const struct pci_raw_ops pci_mmcfg = { | 129 | const struct pci_raw_ops pci_mmcfg = { |
121 | .read = pci_mmcfg_read, | 130 | .read = pci_mmcfg_read, |
122 | .write = pci_mmcfg_write, | 131 | .write = pci_mmcfg_write, |
123 | }; | 132 | }; |
@@ -132,3 +141,18 @@ int __init pci_mmcfg_arch_init(void) | |||
132 | void __init pci_mmcfg_arch_free(void) | 141 | void __init pci_mmcfg_arch_free(void) |
133 | { | 142 | { |
134 | } | 143 | } |
144 | |||
145 | int __devinit pci_mmcfg_arch_map(struct pci_mmcfg_region *cfg) | ||
146 | { | ||
147 | return 0; | ||
148 | } | ||
149 | |||
150 | void pci_mmcfg_arch_unmap(struct pci_mmcfg_region *cfg) | ||
151 | { | ||
152 | unsigned long flags; | ||
153 | |||
154 | /* Invalidate the cached mmcfg map entry. */ | ||
155 | raw_spin_lock_irqsave(&pci_config_lock, flags); | ||
156 | mmcfg_last_accessed_device = 0; | ||
157 | raw_spin_unlock_irqrestore(&pci_config_lock, flags); | ||
158 | } | ||
diff --git a/arch/x86/pci/mmconfig_64.c b/arch/x86/pci/mmconfig_64.c index 915a493502cb..d4ebd07c306d 100644 --- a/arch/x86/pci/mmconfig_64.c +++ b/arch/x86/pci/mmconfig_64.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <linux/init.h> | 9 | #include <linux/init.h> |
10 | #include <linux/acpi.h> | 10 | #include <linux/acpi.h> |
11 | #include <linux/bitmap.h> | 11 | #include <linux/bitmap.h> |
12 | #include <linux/rcupdate.h> | ||
12 | #include <asm/e820.h> | 13 | #include <asm/e820.h> |
13 | #include <asm/pci_x86.h> | 14 | #include <asm/pci_x86.h> |
14 | 15 | ||
@@ -34,9 +35,12 @@ err: *value = -1; | |||
34 | return -EINVAL; | 35 | return -EINVAL; |
35 | } | 36 | } |
36 | 37 | ||
38 | rcu_read_lock(); | ||
37 | addr = pci_dev_base(seg, bus, devfn); | 39 | addr = pci_dev_base(seg, bus, devfn); |
38 | if (!addr) | 40 | if (!addr) { |
41 | rcu_read_unlock(); | ||
39 | goto err; | 42 | goto err; |
43 | } | ||
40 | 44 | ||
41 | switch (len) { | 45 | switch (len) { |
42 | case 1: | 46 | case 1: |
@@ -49,6 +53,7 @@ err: *value = -1; | |||
49 | *value = mmio_config_readl(addr + reg); | 53 | *value = mmio_config_readl(addr + reg); |
50 | break; | 54 | break; |
51 | } | 55 | } |
56 | rcu_read_unlock(); | ||
52 | 57 | ||
53 | return 0; | 58 | return 0; |
54 | } | 59 | } |
@@ -62,9 +67,12 @@ static int pci_mmcfg_write(unsigned int seg, unsigned int bus, | |||
62 | if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095))) | 67 | if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095))) |
63 | return -EINVAL; | 68 | return -EINVAL; |
64 | 69 | ||
70 | rcu_read_lock(); | ||
65 | addr = pci_dev_base(seg, bus, devfn); | 71 | addr = pci_dev_base(seg, bus, devfn); |
66 | if (!addr) | 72 | if (!addr) { |
73 | rcu_read_unlock(); | ||
67 | return -EINVAL; | 74 | return -EINVAL; |
75 | } | ||
68 | 76 | ||
69 | switch (len) { | 77 | switch (len) { |
70 | case 1: | 78 | case 1: |
@@ -77,16 +85,17 @@ static int pci_mmcfg_write(unsigned int seg, unsigned int bus, | |||
77 | mmio_config_writel(addr + reg, value); | 85 | mmio_config_writel(addr + reg, value); |
78 | break; | 86 | break; |
79 | } | 87 | } |
88 | rcu_read_unlock(); | ||
80 | 89 | ||
81 | return 0; | 90 | return 0; |
82 | } | 91 | } |
83 | 92 | ||
84 | static const struct pci_raw_ops pci_mmcfg = { | 93 | const struct pci_raw_ops pci_mmcfg = { |
85 | .read = pci_mmcfg_read, | 94 | .read = pci_mmcfg_read, |
86 | .write = pci_mmcfg_write, | 95 | .write = pci_mmcfg_write, |
87 | }; | 96 | }; |
88 | 97 | ||
89 | static void __iomem * __init mcfg_ioremap(struct pci_mmcfg_region *cfg) | 98 | static void __iomem * __devinit mcfg_ioremap(struct pci_mmcfg_region *cfg) |
90 | { | 99 | { |
91 | void __iomem *addr; | 100 | void __iomem *addr; |
92 | u64 start, size; | 101 | u64 start, size; |
@@ -105,16 +114,14 @@ int __init pci_mmcfg_arch_init(void) | |||
105 | { | 114 | { |
106 | struct pci_mmcfg_region *cfg; | 115 | struct pci_mmcfg_region *cfg; |
107 | 116 | ||
108 | list_for_each_entry(cfg, &pci_mmcfg_list, list) { | 117 | list_for_each_entry(cfg, &pci_mmcfg_list, list) |
109 | cfg->virt = mcfg_ioremap(cfg); | 118 | if (pci_mmcfg_arch_map(cfg)) { |
110 | if (!cfg->virt) { | ||
111 | printk(KERN_ERR PREFIX "can't map MMCONFIG at %pR\n", | ||
112 | &cfg->res); | ||
113 | pci_mmcfg_arch_free(); | 119 | pci_mmcfg_arch_free(); |
114 | return 0; | 120 | return 0; |
115 | } | 121 | } |
116 | } | 122 | |
117 | raw_pci_ext_ops = &pci_mmcfg; | 123 | raw_pci_ext_ops = &pci_mmcfg; |
124 | |||
118 | return 1; | 125 | return 1; |
119 | } | 126 | } |
120 | 127 | ||
@@ -122,10 +129,25 @@ void __init pci_mmcfg_arch_free(void) | |||
122 | { | 129 | { |
123 | struct pci_mmcfg_region *cfg; | 130 | struct pci_mmcfg_region *cfg; |
124 | 131 | ||
125 | list_for_each_entry(cfg, &pci_mmcfg_list, list) { | 132 | list_for_each_entry(cfg, &pci_mmcfg_list, list) |
126 | if (cfg->virt) { | 133 | pci_mmcfg_arch_unmap(cfg); |
127 | iounmap(cfg->virt + PCI_MMCFG_BUS_OFFSET(cfg->start_bus)); | 134 | } |
128 | cfg->virt = NULL; | 135 | |
129 | } | 136 | int __devinit pci_mmcfg_arch_map(struct pci_mmcfg_region *cfg) |
137 | { | ||
138 | cfg->virt = mcfg_ioremap(cfg); | ||
139 | if (!cfg->virt) { | ||
140 | pr_err(PREFIX "can't map MMCONFIG at %pR\n", &cfg->res); | ||
141 | return -ENOMEM; | ||
142 | } | ||
143 | |||
144 | return 0; | ||
145 | } | ||
146 | |||
147 | void pci_mmcfg_arch_unmap(struct pci_mmcfg_region *cfg) | ||
148 | { | ||
149 | if (cfg && cfg->virt) { | ||
150 | iounmap(cfg->virt + PCI_MMCFG_BUS_OFFSET(cfg->start_bus)); | ||
151 | cfg->virt = NULL; | ||
130 | } | 152 | } |
131 | } | 153 | } |
diff --git a/arch/x86/pci/mrst.c b/arch/x86/pci/mrst.c index 140942f66b31..e14a2ff708b5 100644 --- a/arch/x86/pci/mrst.c +++ b/arch/x86/pci/mrst.c | |||
@@ -264,7 +264,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_d3delay_fixup); | |||
264 | 264 | ||
265 | static void __devinit mrst_power_off_unused_dev(struct pci_dev *dev) | 265 | static void __devinit mrst_power_off_unused_dev(struct pci_dev *dev) |
266 | { | 266 | { |
267 | pci_set_power_state(dev, PCI_D3cold); | 267 | pci_set_power_state(dev, PCI_D3hot); |
268 | } | 268 | } |
269 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0801, mrst_power_off_unused_dev); | 269 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0801, mrst_power_off_unused_dev); |
270 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0809, mrst_power_off_unused_dev); | 270 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0809, mrst_power_off_unused_dev); |
diff --git a/arch/xtensa/kernel/pci.c b/arch/xtensa/kernel/pci.c index eb30e356f5be..69759e9cb3ea 100644 --- a/arch/xtensa/kernel/pci.c +++ b/arch/xtensa/kernel/pci.c | |||
@@ -46,7 +46,6 @@ | |||
46 | * pcibios_fixups | 46 | * pcibios_fixups |
47 | * pcibios_align_resource | 47 | * pcibios_align_resource |
48 | * pcibios_fixup_bus | 48 | * pcibios_fixup_bus |
49 | * pcibios_setup | ||
50 | * pci_bus_add_device | 49 | * pci_bus_add_device |
51 | * pci_mmap_page_range | 50 | * pci_mmap_page_range |
52 | */ | 51 | */ |
@@ -187,7 +186,7 @@ static int __init pcibios_init(void) | |||
187 | bus = pci_scan_root_bus(NULL, pci_ctrl->first_busno, | 186 | bus = pci_scan_root_bus(NULL, pci_ctrl->first_busno, |
188 | pci_ctrl->ops, pci_ctrl, &resources); | 187 | pci_ctrl->ops, pci_ctrl, &resources); |
189 | pci_ctrl->bus = bus; | 188 | pci_ctrl->bus = bus; |
190 | pci_ctrl->last_busno = bus->subordinate; | 189 | pci_ctrl->last_busno = bus->busn_res.end; |
191 | if (next_busno <= pci_ctrl->last_busno) | 190 | if (next_busno <= pci_ctrl->last_busno) |
192 | next_busno = pci_ctrl->last_busno+1; | 191 | next_busno = pci_ctrl->last_busno+1; |
193 | } | 192 | } |
@@ -206,11 +205,6 @@ void __init pcibios_fixup_bus(struct pci_bus *bus) | |||
206 | } | 205 | } |
207 | } | 206 | } |
208 | 207 | ||
209 | char __init *pcibios_setup(char *str) | ||
210 | { | ||
211 | return str; | ||
212 | } | ||
213 | |||
214 | void pcibios_set_master(struct pci_dev *dev) | 208 | void pcibios_set_master(struct pci_dev *dev) |
215 | { | 209 | { |
216 | /* No special bus mastering setup handling */ | 210 | /* No special bus mastering setup handling */ |