diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-01 18:14:04 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-01 18:14:04 -0400 |
commit | 4b1779c2cf030c68aefe939d946475e4136c1895 (patch) | |
tree | 27e4bda2f6c8d269d02dec52a62dd1443880c6dc | |
parent | 62ff577fa2fec87edbf26f53e87210ba726d4d44 (diff) | |
parent | 30723cbf6f7aec2ab4810bdc4bf12c5749a09e33 (diff) |
Merge tag 'pci-v3.15-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci
Pull PCI changes from Bjorn Helgaas:
"Enumeration
- Increment max correctly in pci_scan_bridge() (Andreas Noever)
- Clarify the "scan anyway" comment in pci_scan_bridge() (Andreas Noever)
- Assign CardBus bus number only during the second pass (Andreas Noever)
- Use request_resource_conflict() instead of insert_ for bus numbers (Andreas Noever)
- Make sure bus number resources stay within their parents bounds (Andreas Noever)
- Remove pci_fixup_parent_subordinate_busnr() (Andreas Noever)
- Check for child busses which use more bus numbers than allocated (Andreas Noever)
- Don't scan random busses in pci_scan_bridge() (Andreas Noever)
- x86: Drop pcibios_scan_root() check for bus already scanned (Bjorn Helgaas)
- x86: Use pcibios_scan_root() instead of pci_scan_bus_with_sysdata() (Bjorn Helgaas)
- x86: Use pcibios_scan_root() instead of pci_scan_bus_on_node() (Bjorn Helgaas)
- x86: Merge pci_scan_bus_on_node() into pcibios_scan_root() (Bjorn Helgaas)
- x86: Drop return value of pcibios_scan_root() (Bjorn Helgaas)
NUMA
- x86: Add x86_pci_root_bus_node() to look up NUMA node from PCI bus (Bjorn Helgaas)
- x86: Use x86_pci_root_bus_node() instead of get_mp_bus_to_node() (Bjorn Helgaas)
- x86: Remove mp_bus_to_node[], set_mp_bus_to_node(), get_mp_bus_to_node() (Bjorn Helgaas)
- x86: Use NUMA_NO_NODE, not -1, for unknown node (Bjorn Helgaas)
- x86: Remove acpi_get_pxm() usage (Bjorn Helgaas)
- ia64: Use NUMA_NO_NODE, not MAX_NUMNODES, for unknown node (Bjorn Helgaas)
- ia64: Remove acpi_get_pxm() usage (Bjorn Helgaas)
- ACPI: Fix acpi_get_node() prototype (Bjorn Helgaas)
Resource management
- i2o: Fix and refactor PCI space allocation (Bjorn Helgaas)
- Add resource_contains() (Bjorn Helgaas)
- Add %pR support for IORESOURCE_UNSET (Bjorn Helgaas)
- Mark resources as IORESOURCE_UNSET if we can't assign them (Bjorn Helgaas)
- Don't clear IORESOURCE_UNSET when updating BAR (Bjorn Helgaas)
- Check IORESOURCE_UNSET before updating BAR (Bjorn Helgaas)
- Don't try to claim IORESOURCE_UNSET resources (Bjorn Helgaas)
- Mark 64-bit resource as IORESOURCE_UNSET if we only support 32-bit (Bjorn Helgaas)
- Don't enable decoding if BAR hasn't been assigned an address (Bjorn Helgaas)
- Add "weak" generic pcibios_enable_device() implementation (Bjorn Helgaas)
- alpha, microblaze, sh, sparc, tile: Use default pcibios_enable_device() (Bjorn Helgaas)
- s390: Use generic pci_enable_resources() (Bjorn Helgaas)
- Don't check resource_size() in pci_bus_alloc_resource() (Bjorn Helgaas)
- Set type in __request_region() (Bjorn Helgaas)
- Check all IORESOURCE_TYPE_BITS in pci_bus_alloc_from_region() (Bjorn Helgaas)
- Change pci_bus_alloc_resource() type_mask to unsigned long (Bjorn Helgaas)
- Log IDE resource quirk in dmesg (Bjorn Helgaas)
- Revert "[PATCH] Insert GART region into resource map" (Bjorn Helgaas)
PCI device hotplug
- Make check_link_active() non-static (Rajat Jain)
- Use link change notifications for hot-plug and removal (Rajat Jain)
- Enable link state change notifications (Rajat Jain)
- Don't disable the link permanently during removal (Rajat Jain)
- Don't check adapter or latch status while disabling (Rajat Jain)
- Disable link notification across slot reset (Rajat Jain)
- Ensure very fast hotplug events are also processed (Rajat Jain)
- Add hotplug_lock to serialize hotplug events (Rajat Jain)
- Remove a non-existent card, regardless of "surprise" capability (Rajat Jain)
- Don't turn slot off when hot-added device already exists (Yijing Wang)
MSI
- Keep pci_enable_msi() documentation (Alexander Gordeev)
- ahci: Fix broken single MSI fallback (Alexander Gordeev)
- ahci, vfio: Use pci_enable_msi_range() (Alexander Gordeev)
- Check kmalloc() return value, fix leak of name (Greg Kroah-Hartman)
- Fix leak of msi_attrs (Greg Kroah-Hartman)
- Fix pci_msix_vec_count() htmldocs failure (Masanari Iida)
Virtualization
- Device-specific ACS support (Alex Williamson)
Freescale i.MX6
- Wait for retraining (Marek Vasut)
Marvell MVEBU
- Use Device ID and revision from underlying endpoint (Andrew Lunn)
- Fix incorrect size for PCI aperture resources (Jason Gunthorpe)
- Call request_resource() on the apertures (Jason Gunthorpe)
- Fix potential issue in range parsing (Jean-Jacques Hiblot)
Renesas R-Car
- Check platform_get_irq() return code (Ben Dooks)
- Add error interrupt handling (Ben Dooks)
- Fix bridge logic configuration accesses (Ben Dooks)
- Register each instance independently (Magnus Damm)
- Break out window size handling (Magnus Damm)
- Make the Kconfig dependencies more generic (Magnus Damm)
Synopsys DesignWare
- Fix RC BAR to be single 64-bit non-prefetchable memory (Mohit Kumar)
Miscellaneous
- Remove unused SR-IOV VF Migration support (Bjorn Helgaas)
- Enable INTx if BIOS left them disabled (Bjorn Helgaas)
- Fix hex vs decimal typo in cpqhpc_probe() (Dan Carpenter)
- Clean up par-arch object file list (Liviu Dudau)
- Set IORESOURCE_ROM_SHADOW only for the default VGA device (Sander Eikelenboom)
- ACPI, ARM, drm, powerpc, pcmcia, PCI: Use list_for_each_entry() for bus traversal (Yijing Wang)
- Fix pci_bus_b() build failure (Paul Gortmaker)"
* tag 'pci-v3.15-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci: (108 commits)
Revert "[PATCH] Insert GART region into resource map"
PCI: Log IDE resource quirk in dmesg
PCI: Change pci_bus_alloc_resource() type_mask to unsigned long
PCI: Check all IORESOURCE_TYPE_BITS in pci_bus_alloc_from_region()
resources: Set type in __request_region()
PCI: Don't check resource_size() in pci_bus_alloc_resource()
s390/PCI: Use generic pci_enable_resources()
tile PCI RC: Use default pcibios_enable_device()
sparc/PCI: Use default pcibios_enable_device() (Leon only)
sh/PCI: Use default pcibios_enable_device()
microblaze/PCI: Use default pcibios_enable_device()
alpha/PCI: Use default pcibios_enable_device()
PCI: Add "weak" generic pcibios_enable_device() implementation
PCI: Don't enable decoding if BAR hasn't been assigned an address
PCI: Enable INTx in pci_reenable_device() only when MSI/MSI-X not enabled
PCI: Mark 64-bit resource as IORESOURCE_UNSET if we only support 32-bit
PCI: Don't try to claim IORESOURCE_UNSET resources
PCI: Check IORESOURCE_UNSET before updating BAR
PCI: Don't clear IORESOURCE_UNSET when updating BAR
PCI: Mark resources as IORESOURCE_UNSET if we can't assign them
...
Conflicts:
arch/x86/include/asm/topology.h
drivers/ata/ahci.c
68 files changed, 943 insertions, 863 deletions
diff --git a/Documentation/PCI/pci-iov-howto.txt b/Documentation/PCI/pci-iov-howto.txt index 86551cc72e03..2d91ae251982 100644 --- a/Documentation/PCI/pci-iov-howto.txt +++ b/Documentation/PCI/pci-iov-howto.txt | |||
@@ -68,10 +68,6 @@ To disable SR-IOV capability: | |||
68 | echo 0 > \ | 68 | echo 0 > \ |
69 | /sys/bus/pci/devices/<DOMAIN:BUS:DEVICE.FUNCTION>/sriov_numvfs | 69 | /sys/bus/pci/devices/<DOMAIN:BUS:DEVICE.FUNCTION>/sriov_numvfs |
70 | 70 | ||
71 | To notify SR-IOV core of Virtual Function Migration: | ||
72 | (a) In the driver: | ||
73 | irqreturn_t pci_sriov_migration(struct pci_dev *dev); | ||
74 | |||
75 | 3.2 Usage example | 71 | 3.2 Usage example |
76 | 72 | ||
77 | Following piece of code illustrates the usage of the SR-IOV API. | 73 | Following piece of code illustrates the usage of the SR-IOV API. |
diff --git a/arch/alpha/kernel/pci.c b/arch/alpha/kernel/pci.c index edb4e0097b75..076c35cd6cde 100644 --- a/arch/alpha/kernel/pci.c +++ b/arch/alpha/kernel/pci.c | |||
@@ -254,12 +254,6 @@ void pcibios_fixup_bus(struct pci_bus *bus) | |||
254 | } | 254 | } |
255 | } | 255 | } |
256 | 256 | ||
257 | int | ||
258 | pcibios_enable_device(struct pci_dev *dev, int mask) | ||
259 | { | ||
260 | return pci_enable_resources(dev, mask); | ||
261 | } | ||
262 | |||
263 | /* | 257 | /* |
264 | * If we set up a device for bus mastering, we need to check the latency | 258 | * If we set up a device for bus mastering, we need to check the latency |
265 | * timer as certain firmware forgets to set it properly, as seen | 259 | * timer as certain firmware forgets to set it properly, as seen |
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c index 317da88ae65b..d0d46786892c 100644 --- a/arch/arm/kernel/bios32.c +++ b/arch/arm/kernel/bios32.c | |||
@@ -19,7 +19,7 @@ | |||
19 | static int debug_pci; | 19 | static int debug_pci; |
20 | 20 | ||
21 | /* | 21 | /* |
22 | * We can't use pci_find_device() here since we are | 22 | * We can't use pci_get_device() here since we are |
23 | * called from interrupt context. | 23 | * called from interrupt context. |
24 | */ | 24 | */ |
25 | static void pcibios_bus_report_status(struct pci_bus *bus, u_int status_mask, int warn) | 25 | static void pcibios_bus_report_status(struct pci_bus *bus, u_int status_mask, int warn) |
@@ -57,13 +57,10 @@ static void pcibios_bus_report_status(struct pci_bus *bus, u_int status_mask, in | |||
57 | 57 | ||
58 | void pcibios_report_status(u_int status_mask, int warn) | 58 | void pcibios_report_status(u_int status_mask, int warn) |
59 | { | 59 | { |
60 | struct list_head *l; | 60 | struct pci_bus *bus; |
61 | |||
62 | list_for_each(l, &pci_root_buses) { | ||
63 | struct pci_bus *bus = pci_bus_b(l); | ||
64 | 61 | ||
62 | list_for_each_entry(bus, &pci_root_buses, node) | ||
65 | pcibios_bus_report_status(bus, status_mask, warn); | 63 | pcibios_bus_report_status(bus, status_mask, warn); |
66 | } | ||
67 | } | 64 | } |
68 | 65 | ||
69 | /* | 66 | /* |
diff --git a/arch/frv/mb93090-mb00/pci-frv.c b/arch/frv/mb93090-mb00/pci-frv.c index c28121765448..67b1d1685759 100644 --- a/arch/frv/mb93090-mb00/pci-frv.c +++ b/arch/frv/mb93090-mb00/pci-frv.c | |||
@@ -88,7 +88,7 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list) | |||
88 | 88 | ||
89 | /* Depth-First Search on bus tree */ | 89 | /* Depth-First Search on bus tree */ |
90 | for (ln=bus_list->next; ln != bus_list; ln=ln->next) { | 90 | for (ln=bus_list->next; ln != bus_list; ln=ln->next) { |
91 | bus = pci_bus_b(ln); | 91 | bus = list_entry(ln, struct pci_bus, node); |
92 | if ((dev = bus->self)) { | 92 | if ((dev = bus->self)) { |
93 | for (idx = PCI_BRIDGE_RESOURCES; idx < PCI_NUM_RESOURCES; idx++) { | 93 | for (idx = PCI_BRIDGE_RESOURCES; idx < PCI_NUM_RESOURCES; idx++) { |
94 | r = &dev->resource[idx]; | 94 | r = &dev->resource[idx]; |
diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c index 30c43d39dede..1a871b78e570 100644 --- a/arch/ia64/hp/common/sba_iommu.c +++ b/arch/ia64/hp/common/sba_iommu.c | |||
@@ -1140,11 +1140,13 @@ sba_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, | |||
1140 | 1140 | ||
1141 | #ifdef CONFIG_NUMA | 1141 | #ifdef CONFIG_NUMA |
1142 | { | 1142 | { |
1143 | int node = ioc->node; | ||
1143 | struct page *page; | 1144 | struct page *page; |
1144 | page = alloc_pages_exact_node(ioc->node == MAX_NUMNODES ? | ||
1145 | numa_node_id() : ioc->node, flags, | ||
1146 | get_order(size)); | ||
1147 | 1145 | ||
1146 | if (node == NUMA_NO_NODE) | ||
1147 | node = numa_node_id(); | ||
1148 | |||
1149 | page = alloc_pages_exact_node(node, flags, get_order(size)); | ||
1148 | if (unlikely(!page)) | 1150 | if (unlikely(!page)) |
1149 | return NULL; | 1151 | return NULL; |
1150 | 1152 | ||
@@ -1914,7 +1916,7 @@ ioc_show(struct seq_file *s, void *v) | |||
1914 | seq_printf(s, "Hewlett Packard %s IOC rev %d.%d\n", | 1916 | seq_printf(s, "Hewlett Packard %s IOC rev %d.%d\n", |
1915 | ioc->name, ((ioc->rev >> 4) & 0xF), (ioc->rev & 0xF)); | 1917 | ioc->name, ((ioc->rev >> 4) & 0xF), (ioc->rev & 0xF)); |
1916 | #ifdef CONFIG_NUMA | 1918 | #ifdef CONFIG_NUMA |
1917 | if (ioc->node != MAX_NUMNODES) | 1919 | if (ioc->node != NUMA_NO_NODE) |
1918 | seq_printf(s, "NUMA node : %d\n", ioc->node); | 1920 | seq_printf(s, "NUMA node : %d\n", ioc->node); |
1919 | #endif | 1921 | #endif |
1920 | seq_printf(s, "IOVA size : %ld MB\n", ((ioc->pdir_size >> 3) * iovp_size)/(1024*1024)); | 1922 | seq_printf(s, "IOVA size : %ld MB\n", ((ioc->pdir_size >> 3) * iovp_size)/(1024*1024)); |
@@ -2015,31 +2017,19 @@ sba_connect_bus(struct pci_bus *bus) | |||
2015 | printk(KERN_WARNING "No IOC for PCI Bus %04x:%02x in ACPI\n", pci_domain_nr(bus), bus->number); | 2017 | printk(KERN_WARNING "No IOC for PCI Bus %04x:%02x in ACPI\n", pci_domain_nr(bus), bus->number); |
2016 | } | 2018 | } |
2017 | 2019 | ||
2018 | #ifdef CONFIG_NUMA | ||
2019 | static void __init | 2020 | static void __init |
2020 | sba_map_ioc_to_node(struct ioc *ioc, acpi_handle handle) | 2021 | sba_map_ioc_to_node(struct ioc *ioc, acpi_handle handle) |
2021 | { | 2022 | { |
2023 | #ifdef CONFIG_NUMA | ||
2022 | unsigned int node; | 2024 | unsigned int node; |
2023 | int pxm; | ||
2024 | |||
2025 | ioc->node = MAX_NUMNODES; | ||
2026 | |||
2027 | pxm = acpi_get_pxm(handle); | ||
2028 | |||
2029 | if (pxm < 0) | ||
2030 | return; | ||
2031 | |||
2032 | node = pxm_to_node(pxm); | ||
2033 | 2025 | ||
2034 | if (node >= MAX_NUMNODES || !node_online(node)) | 2026 | node = acpi_get_node(handle); |
2035 | return; | 2027 | if (node != NUMA_NO_NODE && !node_online(node)) |
2028 | node = NUMA_NO_NODE; | ||
2036 | 2029 | ||
2037 | ioc->node = node; | 2030 | ioc->node = node; |
2038 | return; | ||
2039 | } | ||
2040 | #else | ||
2041 | #define sba_map_ioc_to_node(ioc, handle) | ||
2042 | #endif | 2031 | #endif |
2032 | } | ||
2043 | 2033 | ||
2044 | static int | 2034 | static int |
2045 | acpi_sba_ioc_add(struct acpi_device *device, | 2035 | acpi_sba_ioc_add(struct acpi_device *device, |
diff --git a/arch/ia64/include/asm/pci.h b/arch/ia64/include/asm/pci.h index 71fbaaa495cc..7d41cc089822 100644 --- a/arch/ia64/include/asm/pci.h +++ b/arch/ia64/include/asm/pci.h | |||
@@ -98,7 +98,7 @@ struct pci_controller { | |||
98 | struct acpi_device *companion; | 98 | struct acpi_device *companion; |
99 | void *iommu; | 99 | void *iommu; |
100 | int segment; | 100 | int segment; |
101 | int node; /* nearest node with memory or -1 for global allocation */ | 101 | int node; /* nearest node with memory or NUMA_NO_NODE for global allocation */ |
102 | 102 | ||
103 | void *platform_data; | 103 | void *platform_data; |
104 | }; | 104 | }; |
diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c index 467497ade45f..0d407b300762 100644 --- a/arch/ia64/kernel/acpi.c +++ b/arch/ia64/kernel/acpi.c | |||
@@ -799,14 +799,9 @@ int acpi_isa_irq_to_gsi(unsigned isa_irq, u32 *gsi) | |||
799 | * ACPI based hotplug CPU support | 799 | * ACPI based hotplug CPU support |
800 | */ | 800 | */ |
801 | #ifdef CONFIG_ACPI_HOTPLUG_CPU | 801 | #ifdef CONFIG_ACPI_HOTPLUG_CPU |
802 | static | 802 | static int acpi_map_cpu2node(acpi_handle handle, int cpu, int physid) |
803 | int acpi_map_cpu2node(acpi_handle handle, int cpu, int physid) | ||
804 | { | 803 | { |
805 | #ifdef CONFIG_ACPI_NUMA | 804 | #ifdef CONFIG_ACPI_NUMA |
806 | int pxm_id; | ||
807 | int nid; | ||
808 | |||
809 | pxm_id = acpi_get_pxm(handle); | ||
810 | /* | 805 | /* |
811 | * We don't have cpu-only-node hotadd. But if the system equips | 806 | * We don't have cpu-only-node hotadd. But if the system equips |
812 | * SRAT table, pxm is already found and node is ready. | 807 | * SRAT table, pxm is already found and node is ready. |
@@ -814,11 +809,10 @@ int acpi_map_cpu2node(acpi_handle handle, int cpu, int physid) | |||
814 | * This code here is for the system which doesn't have full SRAT | 809 | * This code here is for the system which doesn't have full SRAT |
815 | * table for possible cpus. | 810 | * table for possible cpus. |
816 | */ | 811 | */ |
817 | nid = acpi_map_pxm_to_node(pxm_id); | ||
818 | node_cpuid[cpu].phys_id = physid; | 812 | node_cpuid[cpu].phys_id = physid; |
819 | node_cpuid[cpu].nid = nid; | 813 | node_cpuid[cpu].nid = acpi_get_node(handle); |
820 | #endif | 814 | #endif |
821 | return (0); | 815 | return 0; |
822 | } | 816 | } |
823 | 817 | ||
824 | int additional_cpus __initdata = -1; | 818 | int additional_cpus __initdata = -1; |
@@ -925,7 +919,7 @@ static acpi_status acpi_map_iosapic(acpi_handle handle, u32 depth, | |||
925 | union acpi_object *obj; | 919 | union acpi_object *obj; |
926 | struct acpi_madt_io_sapic *iosapic; | 920 | struct acpi_madt_io_sapic *iosapic; |
927 | unsigned int gsi_base; | 921 | unsigned int gsi_base; |
928 | int pxm, node; | 922 | int node; |
929 | 923 | ||
930 | /* Only care about objects w/ a method that returns the MADT */ | 924 | /* Only care about objects w/ a method that returns the MADT */ |
931 | if (ACPI_FAILURE(acpi_evaluate_object(handle, "_MAT", NULL, &buffer))) | 925 | if (ACPI_FAILURE(acpi_evaluate_object(handle, "_MAT", NULL, &buffer))) |
@@ -952,17 +946,9 @@ static acpi_status acpi_map_iosapic(acpi_handle handle, u32 depth, | |||
952 | 946 | ||
953 | kfree(buffer.pointer); | 947 | kfree(buffer.pointer); |
954 | 948 | ||
955 | /* | 949 | /* OK, it's an IOSAPIC MADT entry; associate it with a node */ |
956 | * OK, it's an IOSAPIC MADT entry, look for a _PXM value to tell | 950 | node = acpi_get_node(handle); |
957 | * us which node to associate this with. | 951 | if (node == NUMA_NO_NODE || !node_online(node) || |
958 | */ | ||
959 | pxm = acpi_get_pxm(handle); | ||
960 | if (pxm < 0) | ||
961 | return AE_OK; | ||
962 | |||
963 | node = pxm_to_node(pxm); | ||
964 | |||
965 | if (node >= MAX_NUMNODES || !node_online(node) || | ||
966 | cpumask_empty(cpumask_of_node(node))) | 952 | cpumask_empty(cpumask_of_node(node))) |
967 | return AE_OK; | 953 | return AE_OK; |
968 | 954 | ||
diff --git a/arch/ia64/pci/fixup.c b/arch/ia64/pci/fixup.c index 5dc969dd4ac0..eee069a0b539 100644 --- a/arch/ia64/pci/fixup.c +++ b/arch/ia64/pci/fixup.c | |||
@@ -5,6 +5,7 @@ | |||
5 | 5 | ||
6 | #include <linux/pci.h> | 6 | #include <linux/pci.h> |
7 | #include <linux/init.h> | 7 | #include <linux/init.h> |
8 | #include <linux/vgaarb.h> | ||
8 | 9 | ||
9 | #include <asm/machvec.h> | 10 | #include <asm/machvec.h> |
10 | 11 | ||
@@ -19,9 +20,10 @@ | |||
19 | * IORESOURCE_ROM_SHADOW is used to associate the boot video | 20 | * IORESOURCE_ROM_SHADOW is used to associate the boot video |
20 | * card with this copy. On laptops this copy has to be used since | 21 | * card with this copy. On laptops this copy has to be used since |
21 | * the main ROM may be compressed or combined with another image. | 22 | * the main ROM may be compressed or combined with another image. |
22 | * See pci_map_rom() for use of this flag. IORESOURCE_ROM_SHADOW | 23 | * See pci_map_rom() for use of this flag. Before marking the device |
23 | * is marked here since the boot video device will be the only enabled | 24 | * with IORESOURCE_ROM_SHADOW check if a vga_default_device is already set |
24 | * video device at this point. | 25 | * by either arch cde or vga-arbitration, if so only apply the fixup to this |
26 | * already determined primary video card. | ||
25 | */ | 27 | */ |
26 | 28 | ||
27 | static void pci_fixup_video(struct pci_dev *pdev) | 29 | static void pci_fixup_video(struct pci_dev *pdev) |
@@ -35,9 +37,6 @@ static void pci_fixup_video(struct pci_dev *pdev) | |||
35 | return; | 37 | return; |
36 | /* Maybe, this machine supports legacy memory map. */ | 38 | /* Maybe, this machine supports legacy memory map. */ |
37 | 39 | ||
38 | if ((pdev->class >> 8) != PCI_CLASS_DISPLAY_VGA) | ||
39 | return; | ||
40 | |||
41 | /* Is VGA routed to us? */ | 40 | /* Is VGA routed to us? */ |
42 | bus = pdev->bus; | 41 | bus = pdev->bus; |
43 | while (bus) { | 42 | while (bus) { |
@@ -60,10 +59,14 @@ static void pci_fixup_video(struct pci_dev *pdev) | |||
60 | } | 59 | } |
61 | bus = bus->parent; | 60 | bus = bus->parent; |
62 | } | 61 | } |
63 | pci_read_config_word(pdev, PCI_COMMAND, &config); | 62 | if (!vga_default_device() || pdev == vga_default_device()) { |
64 | if (config & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) { | 63 | pci_read_config_word(pdev, PCI_COMMAND, &config); |
65 | pdev->resource[PCI_ROM_RESOURCE].flags |= IORESOURCE_ROM_SHADOW; | 64 | if (config & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) { |
66 | dev_printk(KERN_DEBUG, &pdev->dev, "Boot video device\n"); | 65 | pdev->resource[PCI_ROM_RESOURCE].flags |= IORESOURCE_ROM_SHADOW; |
66 | dev_printk(KERN_DEBUG, &pdev->dev, "Boot video device\n"); | ||
67 | vga_set_default_device(pdev); | ||
68 | } | ||
67 | } | 69 | } |
68 | } | 70 | } |
69 | DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_video); | 71 | DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_ANY_ID, PCI_ANY_ID, |
72 | PCI_CLASS_DISPLAY_VGA, 8, pci_fixup_video); | ||
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index 9e4938d8ca4d..291a582777cf 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c | |||
@@ -126,7 +126,6 @@ static struct pci_controller *alloc_pci_controller(int seg) | |||
126 | return NULL; | 126 | return NULL; |
127 | 127 | ||
128 | controller->segment = seg; | 128 | controller->segment = seg; |
129 | controller->node = -1; | ||
130 | return controller; | 129 | return controller; |
131 | } | 130 | } |
132 | 131 | ||
@@ -430,19 +429,14 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root) | |||
430 | struct pci_root_info *info = NULL; | 429 | struct pci_root_info *info = NULL; |
431 | int busnum = root->secondary.start; | 430 | int busnum = root->secondary.start; |
432 | struct pci_bus *pbus; | 431 | struct pci_bus *pbus; |
433 | int pxm, ret; | 432 | int ret; |
434 | 433 | ||
435 | controller = alloc_pci_controller(domain); | 434 | controller = alloc_pci_controller(domain); |
436 | if (!controller) | 435 | if (!controller) |
437 | return NULL; | 436 | return NULL; |
438 | 437 | ||
439 | controller->companion = device; | 438 | controller->companion = device; |
440 | 439 | controller->node = acpi_get_node(device->handle); | |
441 | pxm = acpi_get_pxm(device->handle); | ||
442 | #ifdef CONFIG_NUMA | ||
443 | if (pxm >= 0) | ||
444 | controller->node = pxm_to_node(pxm); | ||
445 | #endif | ||
446 | 440 | ||
447 | info = kzalloc(sizeof(*info), GFP_KERNEL); | 441 | info = kzalloc(sizeof(*info), GFP_KERNEL); |
448 | if (!info) { | 442 | if (!info) { |
diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c index 66804adcacf0..70996cc66aa2 100644 --- a/arch/microblaze/pci/pci-common.c +++ b/arch/microblaze/pci/pci-common.c | |||
@@ -1294,11 +1294,6 @@ void pcibios_finish_adding_to_bus(struct pci_bus *bus) | |||
1294 | } | 1294 | } |
1295 | EXPORT_SYMBOL_GPL(pcibios_finish_adding_to_bus); | 1295 | EXPORT_SYMBOL_GPL(pcibios_finish_adding_to_bus); |
1296 | 1296 | ||
1297 | int pcibios_enable_device(struct pci_dev *dev, int mask) | ||
1298 | { | ||
1299 | return pci_enable_resources(dev, mask); | ||
1300 | } | ||
1301 | |||
1302 | static void pcibios_setup_phb_resources(struct pci_controller *hose, | 1297 | static void pcibios_setup_phb_resources(struct pci_controller *hose, |
1303 | struct list_head *resources) | 1298 | struct list_head *resources) |
1304 | { | 1299 | { |
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c index a9e311f7a9dd..2a4779091a58 100644 --- a/arch/powerpc/kernel/pci_64.c +++ b/arch/powerpc/kernel/pci_64.c | |||
@@ -208,7 +208,6 @@ long sys_pciconfig_iobase(long which, unsigned long in_bus, | |||
208 | unsigned long in_devfn) | 208 | unsigned long in_devfn) |
209 | { | 209 | { |
210 | struct pci_controller* hose; | 210 | struct pci_controller* hose; |
211 | struct list_head *ln; | ||
212 | struct pci_bus *bus = NULL; | 211 | struct pci_bus *bus = NULL; |
213 | struct device_node *hose_node; | 212 | struct device_node *hose_node; |
214 | 213 | ||
@@ -230,8 +229,7 @@ long sys_pciconfig_iobase(long which, unsigned long in_bus, | |||
230 | * used on pre-domains setup. We return the first match | 229 | * used on pre-domains setup. We return the first match |
231 | */ | 230 | */ |
232 | 231 | ||
233 | for (ln = pci_root_buses.next; ln != &pci_root_buses; ln = ln->next) { | 232 | list_for_each_entry(bus, &pci_root_buses, node) { |
234 | bus = pci_bus_b(ln); | ||
235 | if (in_bus >= bus->number && in_bus <= bus->busn_res.end) | 233 | if (in_bus >= bus->number && in_bus <= bus->busn_res.end) |
236 | break; | 234 | break; |
237 | bus = NULL; | 235 | bus = NULL; |
diff --git a/arch/powerpc/platforms/pseries/pci_dlpar.c b/arch/powerpc/platforms/pseries/pci_dlpar.c index efe61374f6ea..203cbf0dc101 100644 --- a/arch/powerpc/platforms/pseries/pci_dlpar.c +++ b/arch/powerpc/platforms/pseries/pci_dlpar.c | |||
@@ -37,15 +37,15 @@ find_bus_among_children(struct pci_bus *bus, | |||
37 | struct device_node *dn) | 37 | struct device_node *dn) |
38 | { | 38 | { |
39 | struct pci_bus *child = NULL; | 39 | struct pci_bus *child = NULL; |
40 | struct list_head *tmp; | 40 | struct pci_bus *tmp; |
41 | struct device_node *busdn; | 41 | struct device_node *busdn; |
42 | 42 | ||
43 | busdn = pci_bus_to_OF_node(bus); | 43 | busdn = pci_bus_to_OF_node(bus); |
44 | if (busdn == dn) | 44 | if (busdn == dn) |
45 | return bus; | 45 | return bus; |
46 | 46 | ||
47 | list_for_each(tmp, &bus->children) { | 47 | list_for_each_entry(tmp, &bus->children, node) { |
48 | child = find_bus_among_children(pci_bus_b(tmp), dn); | 48 | child = find_bus_among_children(tmp, dn); |
49 | if (child) | 49 | if (child) |
50 | break; | 50 | break; |
51 | }; | 51 | }; |
diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c index 66670ff262a0..1df1d29ac81d 100644 --- a/arch/s390/pci/pci.c +++ b/arch/s390/pci/pci.c | |||
@@ -686,27 +686,13 @@ int pcibios_add_device(struct pci_dev *pdev) | |||
686 | int pcibios_enable_device(struct pci_dev *pdev, int mask) | 686 | int pcibios_enable_device(struct pci_dev *pdev, int mask) |
687 | { | 687 | { |
688 | struct zpci_dev *zdev = get_zdev(pdev); | 688 | struct zpci_dev *zdev = get_zdev(pdev); |
689 | struct resource *res; | ||
690 | u16 cmd; | ||
691 | int i; | ||
692 | 689 | ||
693 | zdev->pdev = pdev; | 690 | zdev->pdev = pdev; |
694 | zpci_debug_init_device(zdev); | 691 | zpci_debug_init_device(zdev); |
695 | zpci_fmb_enable_device(zdev); | 692 | zpci_fmb_enable_device(zdev); |
696 | zpci_map_resources(zdev); | 693 | zpci_map_resources(zdev); |
697 | 694 | ||
698 | pci_read_config_word(pdev, PCI_COMMAND, &cmd); | 695 | return pci_enable_resources(pdev, mask); |
699 | for (i = 0; i < PCI_BAR_COUNT; i++) { | ||
700 | res = &pdev->resource[i]; | ||
701 | |||
702 | if (res->flags & IORESOURCE_IO) | ||
703 | return -EINVAL; | ||
704 | |||
705 | if (res->flags & IORESOURCE_MEM) | ||
706 | cmd |= PCI_COMMAND_MEMORY; | ||
707 | } | ||
708 | pci_write_config_word(pdev, PCI_COMMAND, cmd); | ||
709 | return 0; | ||
710 | } | 696 | } |
711 | 697 | ||
712 | void pcibios_disable_device(struct pci_dev *pdev) | 698 | void pcibios_disable_device(struct pci_dev *pdev) |
diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c index 60ed3e1c4b75..1bc09ee7948f 100644 --- a/arch/sh/drivers/pci/pci.c +++ b/arch/sh/drivers/pci/pci.c | |||
@@ -186,11 +186,6 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res, | |||
186 | return start; | 186 | return start; |
187 | } | 187 | } |
188 | 188 | ||
189 | int pcibios_enable_device(struct pci_dev *dev, int mask) | ||
190 | { | ||
191 | return pci_enable_resources(dev, mask); | ||
192 | } | ||
193 | |||
194 | static void __init | 189 | static void __init |
195 | pcibios_bus_report_status_early(struct pci_channel *hose, | 190 | pcibios_bus_report_status_early(struct pci_channel *hose, |
196 | int top_bus, int current_bus, | 191 | int top_bus, int current_bus, |
diff --git a/arch/sparc/kernel/leon_pci.c b/arch/sparc/kernel/leon_pci.c index 88aaaa57bb64..e16c4157e1ae 100644 --- a/arch/sparc/kernel/leon_pci.c +++ b/arch/sparc/kernel/leon_pci.c | |||
@@ -99,11 +99,6 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res, | |||
99 | return res->start; | 99 | return res->start; |
100 | } | 100 | } |
101 | 101 | ||
102 | int pcibios_enable_device(struct pci_dev *dev, int mask) | ||
103 | { | ||
104 | return pci_enable_resources(dev, mask); | ||
105 | } | ||
106 | |||
107 | /* in/out routines taken from pcic.c | 102 | /* in/out routines taken from pcic.c |
108 | * | 103 | * |
109 | * This probably belongs here rather than ioport.c because | 104 | * This probably belongs here rather than ioport.c because |
diff --git a/arch/tile/kernel/pci_gx.c b/arch/tile/kernel/pci_gx.c index a97a6452b812..077b7bc437e5 100644 --- a/arch/tile/kernel/pci_gx.c +++ b/arch/tile/kernel/pci_gx.c | |||
@@ -1065,18 +1065,6 @@ char *__init pcibios_setup(char *str) | |||
1065 | } | 1065 | } |
1066 | 1066 | ||
1067 | /* | 1067 | /* |
1068 | * Enable memory address decoding, as appropriate, for the | ||
1069 | * device described by the 'dev' struct. | ||
1070 | * | ||
1071 | * This is called from the generic PCI layer, and can be called | ||
1072 | * for bridges or endpoints. | ||
1073 | */ | ||
1074 | int pcibios_enable_device(struct pci_dev *dev, int mask) | ||
1075 | { | ||
1076 | return pci_enable_resources(dev, mask); | ||
1077 | } | ||
1078 | |||
1079 | /* | ||
1080 | * Called for each device after PCI setup is done. | 1068 | * Called for each device after PCI setup is done. |
1081 | * We initialize the PCI device capabilities conservatively, assuming that | 1069 | * We initialize the PCI device capabilities conservatively, assuming that |
1082 | * all devices can only address the 32-bit DMA space. The exception here is | 1070 | * all devices can only address the 32-bit DMA space. The exception here is |
diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h index 1ac6114c9ea5..96ae4f4040bb 100644 --- a/arch/x86/include/asm/pci.h +++ b/arch/x86/include/asm/pci.h | |||
@@ -26,11 +26,6 @@ extern int pci_routeirq; | |||
26 | extern int noioapicquirk; | 26 | extern int noioapicquirk; |
27 | extern int noioapicreroute; | 27 | extern int noioapicreroute; |
28 | 28 | ||
29 | /* scan a bus after allocating a pci_sysdata for it */ | ||
30 | extern struct pci_bus *pci_scan_bus_on_node(int busno, struct pci_ops *ops, | ||
31 | int node); | ||
32 | extern struct pci_bus *pci_scan_bus_with_sysdata(int busno); | ||
33 | |||
34 | #ifdef CONFIG_PCI | 29 | #ifdef CONFIG_PCI |
35 | 30 | ||
36 | #ifdef CONFIG_PCI_DOMAINS | 31 | #ifdef CONFIG_PCI_DOMAINS |
@@ -70,7 +65,7 @@ extern unsigned long pci_mem_start; | |||
70 | 65 | ||
71 | extern int pcibios_enabled; | 66 | extern int pcibios_enabled; |
72 | void pcibios_config_init(void); | 67 | void pcibios_config_init(void); |
73 | struct pci_bus *pcibios_scan_root(int bus); | 68 | void pcibios_scan_root(int bus); |
74 | 69 | ||
75 | void pcibios_set_master(struct pci_dev *dev); | 70 | void pcibios_set_master(struct pci_dev *dev); |
76 | void pcibios_penalize_isa_irq(int irq, int active); | 71 | void pcibios_penalize_isa_irq(int irq, int active); |
diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h index b28097e4c8c3..0e8f04f2c26f 100644 --- a/arch/x86/include/asm/topology.h +++ b/arch/x86/include/asm/topology.h | |||
@@ -132,19 +132,7 @@ static inline void arch_fix_phys_package_id(int num, u32 slot) | |||
132 | } | 132 | } |
133 | 133 | ||
134 | struct pci_bus; | 134 | struct pci_bus; |
135 | int x86_pci_root_bus_node(int bus); | ||
135 | void x86_pci_root_bus_resources(int bus, struct list_head *resources); | 136 | void x86_pci_root_bus_resources(int bus, struct list_head *resources); |
136 | 137 | ||
137 | #ifdef CONFIG_NUMA | ||
138 | extern int get_mp_bus_to_node(int busnum); | ||
139 | extern void set_mp_bus_to_node(int busnum, int node); | ||
140 | #else | ||
141 | static inline int get_mp_bus_to_node(int busnum) | ||
142 | { | ||
143 | return 0; | ||
144 | } | ||
145 | static inline void set_mp_bus_to_node(int busnum, int node) | ||
146 | { | ||
147 | } | ||
148 | #endif | ||
149 | |||
150 | #endif /* _ASM_X86_TOPOLOGY_H */ | 138 | #endif /* _ASM_X86_TOPOLOGY_H */ |
diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c index 4f25ec077552..01edac6c5e18 100644 --- a/arch/x86/pci/acpi.c +++ b/arch/x86/pci/acpi.c | |||
@@ -218,9 +218,8 @@ static void teardown_mcfg_map(struct pci_root_info *info) | |||
218 | } | 218 | } |
219 | #endif | 219 | #endif |
220 | 220 | ||
221 | static acpi_status | 221 | static acpi_status resource_to_addr(struct acpi_resource *resource, |
222 | resource_to_addr(struct acpi_resource *resource, | 222 | struct acpi_resource_address64 *addr) |
223 | struct acpi_resource_address64 *addr) | ||
224 | { | 223 | { |
225 | acpi_status status; | 224 | acpi_status status; |
226 | struct acpi_resource_memory24 *memory24; | 225 | struct acpi_resource_memory24 *memory24; |
@@ -265,8 +264,7 @@ resource_to_addr(struct acpi_resource *resource, | |||
265 | return AE_ERROR; | 264 | return AE_ERROR; |
266 | } | 265 | } |
267 | 266 | ||
268 | static acpi_status | 267 | static acpi_status count_resource(struct acpi_resource *acpi_res, void *data) |
269 | count_resource(struct acpi_resource *acpi_res, void *data) | ||
270 | { | 268 | { |
271 | struct pci_root_info *info = data; | 269 | struct pci_root_info *info = data; |
272 | struct acpi_resource_address64 addr; | 270 | struct acpi_resource_address64 addr; |
@@ -278,8 +276,7 @@ count_resource(struct acpi_resource *acpi_res, void *data) | |||
278 | return AE_OK; | 276 | return AE_OK; |
279 | } | 277 | } |
280 | 278 | ||
281 | static acpi_status | 279 | static acpi_status setup_resource(struct acpi_resource *acpi_res, void *data) |
282 | setup_resource(struct acpi_resource *acpi_res, void *data) | ||
283 | { | 280 | { |
284 | struct pci_root_info *info = data; | 281 | struct pci_root_info *info = data; |
285 | struct resource *res; | 282 | struct resource *res; |
@@ -435,9 +432,9 @@ static void release_pci_root_info(struct pci_host_bridge *bridge) | |||
435 | __release_pci_root_info(info); | 432 | __release_pci_root_info(info); |
436 | } | 433 | } |
437 | 434 | ||
438 | static void | 435 | static void probe_pci_root_info(struct pci_root_info *info, |
439 | probe_pci_root_info(struct pci_root_info *info, struct acpi_device *device, | 436 | struct acpi_device *device, |
440 | int busnum, int domain) | 437 | int busnum, int domain) |
441 | { | 438 | { |
442 | size_t size; | 439 | size_t size; |
443 | 440 | ||
@@ -473,16 +470,13 @@ probe_pci_root_info(struct pci_root_info *info, struct acpi_device *device, | |||
473 | struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root) | 470 | struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root) |
474 | { | 471 | { |
475 | struct acpi_device *device = root->device; | 472 | struct acpi_device *device = root->device; |
476 | struct pci_root_info *info = NULL; | 473 | struct pci_root_info *info; |
477 | int domain = root->segment; | 474 | int domain = root->segment; |
478 | int busnum = root->secondary.start; | 475 | int busnum = root->secondary.start; |
479 | LIST_HEAD(resources); | 476 | LIST_HEAD(resources); |
480 | struct pci_bus *bus = NULL; | 477 | struct pci_bus *bus; |
481 | struct pci_sysdata *sd; | 478 | struct pci_sysdata *sd; |
482 | int node; | 479 | int node; |
483 | #ifdef CONFIG_ACPI_NUMA | ||
484 | int pxm; | ||
485 | #endif | ||
486 | 480 | ||
487 | if (pci_ignore_seg) | 481 | if (pci_ignore_seg) |
488 | domain = 0; | 482 | domain = 0; |
@@ -494,19 +488,12 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root) | |||
494 | return NULL; | 488 | return NULL; |
495 | } | 489 | } |
496 | 490 | ||
497 | node = -1; | 491 | node = acpi_get_node(device->handle); |
498 | #ifdef CONFIG_ACPI_NUMA | 492 | if (node == NUMA_NO_NODE) |
499 | pxm = acpi_get_pxm(device->handle); | 493 | node = x86_pci_root_bus_node(busnum); |
500 | if (pxm >= 0) | ||
501 | node = pxm_to_node(pxm); | ||
502 | if (node != -1) | ||
503 | set_mp_bus_to_node(busnum, node); | ||
504 | else | ||
505 | #endif | ||
506 | node = get_mp_bus_to_node(busnum); | ||
507 | 494 | ||
508 | if (node != -1 && !node_online(node)) | 495 | if (node != NUMA_NO_NODE && !node_online(node)) |
509 | node = -1; | 496 | node = NUMA_NO_NODE; |
510 | 497 | ||
511 | info = kzalloc(sizeof(*info), GFP_KERNEL); | 498 | info = kzalloc(sizeof(*info), GFP_KERNEL); |
512 | if (!info) { | 499 | if (!info) { |
@@ -519,15 +506,12 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root) | |||
519 | sd->domain = domain; | 506 | sd->domain = domain; |
520 | sd->node = node; | 507 | sd->node = node; |
521 | sd->companion = device; | 508 | sd->companion = device; |
522 | /* | 509 | |
523 | * Maybe the desired pci bus has been already scanned. In such case | ||
524 | * it is unnecessary to scan the pci bus with the given domain,busnum. | ||
525 | */ | ||
526 | bus = pci_find_bus(domain, busnum); | 510 | bus = pci_find_bus(domain, busnum); |
527 | if (bus) { | 511 | if (bus) { |
528 | /* | 512 | /* |
529 | * If the desired bus exits, the content of bus->sysdata will | 513 | * If the desired bus has been scanned already, replace |
530 | * be replaced by sd. | 514 | * its bus->sysdata. |
531 | */ | 515 | */ |
532 | memcpy(bus->sysdata, sd, sizeof(*sd)); | 516 | memcpy(bus->sysdata, sd, sizeof(*sd)); |
533 | kfree(info); | 517 | kfree(info); |
@@ -572,15 +556,8 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root) | |||
572 | pcie_bus_configure_settings(child); | 556 | pcie_bus_configure_settings(child); |
573 | } | 557 | } |
574 | 558 | ||
575 | if (bus && node != -1) { | 559 | if (bus && node != NUMA_NO_NODE) |
576 | #ifdef CONFIG_ACPI_NUMA | ||
577 | if (pxm >= 0) | ||
578 | dev_printk(KERN_DEBUG, &bus->dev, | ||
579 | "on NUMA node %d (pxm %d)\n", node, pxm); | ||
580 | #else | ||
581 | dev_printk(KERN_DEBUG, &bus->dev, "on NUMA node %d\n", node); | 560 | dev_printk(KERN_DEBUG, &bus->dev, "on NUMA node %d\n", node); |
582 | #endif | ||
583 | } | ||
584 | 561 | ||
585 | return bus; | 562 | return bus; |
586 | } | 563 | } |
diff --git a/arch/x86/pci/amd_bus.c b/arch/x86/pci/amd_bus.c index a48be98e9ded..a313a7fb6b86 100644 --- a/arch/x86/pci/amd_bus.c +++ b/arch/x86/pci/amd_bus.c | |||
@@ -44,15 +44,6 @@ static struct pci_root_info __init *find_pci_root_info(int node, int link) | |||
44 | return NULL; | 44 | return NULL; |
45 | } | 45 | } |
46 | 46 | ||
47 | static void __init set_mp_bus_range_to_node(int min_bus, int max_bus, int node) | ||
48 | { | ||
49 | #ifdef CONFIG_NUMA | ||
50 | int j; | ||
51 | |||
52 | for (j = min_bus; j <= max_bus; j++) | ||
53 | set_mp_bus_to_node(j, node); | ||
54 | #endif | ||
55 | } | ||
56 | /** | 47 | /** |
57 | * early_fill_mp_bus_to_node() | 48 | * early_fill_mp_bus_to_node() |
58 | * called before pcibios_scan_root and pci_scan_bus | 49 | * called before pcibios_scan_root and pci_scan_bus |
@@ -117,7 +108,6 @@ static int __init early_fill_mp_bus_info(void) | |||
117 | min_bus = (reg >> 16) & 0xff; | 108 | min_bus = (reg >> 16) & 0xff; |
118 | max_bus = (reg >> 24) & 0xff; | 109 | max_bus = (reg >> 24) & 0xff; |
119 | node = (reg >> 4) & 0x07; | 110 | node = (reg >> 4) & 0x07; |
120 | set_mp_bus_range_to_node(min_bus, max_bus, node); | ||
121 | link = (reg >> 8) & 0x03; | 111 | link = (reg >> 8) & 0x03; |
122 | 112 | ||
123 | info = alloc_pci_root_info(min_bus, max_bus, node, link); | 113 | info = alloc_pci_root_info(min_bus, max_bus, node, link); |
diff --git a/arch/x86/pci/bus_numa.c b/arch/x86/pci/bus_numa.c index c2735feb2508..f3a2cfc14125 100644 --- a/arch/x86/pci/bus_numa.c +++ b/arch/x86/pci/bus_numa.c | |||
@@ -10,9 +10,6 @@ static struct pci_root_info *x86_find_pci_root_info(int bus) | |||
10 | { | 10 | { |
11 | struct pci_root_info *info; | 11 | struct pci_root_info *info; |
12 | 12 | ||
13 | if (list_empty(&pci_root_infos)) | ||
14 | return NULL; | ||
15 | |||
16 | list_for_each_entry(info, &pci_root_infos, list) | 13 | list_for_each_entry(info, &pci_root_infos, list) |
17 | if (info->busn.start == bus) | 14 | if (info->busn.start == bus) |
18 | return info; | 15 | return info; |
@@ -20,6 +17,16 @@ static struct pci_root_info *x86_find_pci_root_info(int bus) | |||
20 | return NULL; | 17 | return NULL; |
21 | } | 18 | } |
22 | 19 | ||
20 | int x86_pci_root_bus_node(int bus) | ||
21 | { | ||
22 | struct pci_root_info *info = x86_find_pci_root_info(bus); | ||
23 | |||
24 | if (!info) | ||
25 | return NUMA_NO_NODE; | ||
26 | |||
27 | return info->node; | ||
28 | } | ||
29 | |||
23 | void x86_pci_root_bus_resources(int bus, struct list_head *resources) | 30 | void x86_pci_root_bus_resources(int bus, struct list_head *resources) |
24 | { | 31 | { |
25 | struct pci_root_info *info = x86_find_pci_root_info(bus); | 32 | struct pci_root_info *info = x86_find_pci_root_info(bus); |
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c index 981c2dbd72cc..d491deddebae 100644 --- a/arch/x86/pci/common.c +++ b/arch/x86/pci/common.c | |||
@@ -456,19 +456,25 @@ void __init dmi_check_pciprobe(void) | |||
456 | dmi_check_system(pciprobe_dmi_table); | 456 | dmi_check_system(pciprobe_dmi_table); |
457 | } | 457 | } |
458 | 458 | ||
459 | struct pci_bus *pcibios_scan_root(int busnum) | 459 | void pcibios_scan_root(int busnum) |
460 | { | 460 | { |
461 | struct pci_bus *bus = NULL; | 461 | struct pci_bus *bus; |
462 | struct pci_sysdata *sd; | ||
463 | LIST_HEAD(resources); | ||
462 | 464 | ||
463 | while ((bus = pci_find_next_bus(bus)) != NULL) { | 465 | sd = kzalloc(sizeof(*sd), GFP_KERNEL); |
464 | if (bus->number == busnum) { | 466 | if (!sd) { |
465 | /* Already scanned */ | 467 | printk(KERN_ERR "PCI: OOM, skipping PCI bus %02x\n", busnum); |
466 | return bus; | 468 | return; |
467 | } | 469 | } |
470 | sd->node = x86_pci_root_bus_node(busnum); | ||
471 | x86_pci_root_bus_resources(busnum, &resources); | ||
472 | printk(KERN_DEBUG "PCI: Probing PCI hardware (bus %02x)\n", busnum); | ||
473 | bus = pci_scan_root_bus(NULL, busnum, &pci_root_ops, sd, &resources); | ||
474 | if (!bus) { | ||
475 | pci_free_resource_list(&resources); | ||
476 | kfree(sd); | ||
468 | } | 477 | } |
469 | |||
470 | return pci_scan_bus_on_node(busnum, &pci_root_ops, | ||
471 | get_mp_bus_to_node(busnum)); | ||
472 | } | 478 | } |
473 | 479 | ||
474 | void __init pcibios_set_cache_line_size(void) | 480 | void __init pcibios_set_cache_line_size(void) |
@@ -677,105 +683,3 @@ int pci_ext_cfg_avail(void) | |||
677 | else | 683 | else |
678 | return 0; | 684 | return 0; |
679 | } | 685 | } |
680 | |||
681 | struct pci_bus *pci_scan_bus_on_node(int busno, struct pci_ops *ops, int node) | ||
682 | { | ||
683 | LIST_HEAD(resources); | ||
684 | struct pci_bus *bus = NULL; | ||
685 | struct pci_sysdata *sd; | ||
686 | |||
687 | /* | ||
688 | * Allocate per-root-bus (not per bus) arch-specific data. | ||
689 | * TODO: leak; this memory is never freed. | ||
690 | * It's arguable whether it's worth the trouble to care. | ||
691 | */ | ||
692 | sd = kzalloc(sizeof(*sd), GFP_KERNEL); | ||
693 | if (!sd) { | ||
694 | printk(KERN_ERR "PCI: OOM, skipping PCI bus %02x\n", busno); | ||
695 | return NULL; | ||
696 | } | ||
697 | sd->node = node; | ||
698 | x86_pci_root_bus_resources(busno, &resources); | ||
699 | printk(KERN_DEBUG "PCI: Probing PCI hardware (bus %02x)\n", busno); | ||
700 | bus = pci_scan_root_bus(NULL, busno, ops, sd, &resources); | ||
701 | if (!bus) { | ||
702 | pci_free_resource_list(&resources); | ||
703 | kfree(sd); | ||
704 | } | ||
705 | |||
706 | return bus; | ||
707 | } | ||
708 | |||
709 | struct pci_bus *pci_scan_bus_with_sysdata(int busno) | ||
710 | { | ||
711 | return pci_scan_bus_on_node(busno, &pci_root_ops, -1); | ||
712 | } | ||
713 | |||
714 | /* | ||
715 | * NUMA info for PCI busses | ||
716 | * | ||
717 | * Early arch code is responsible for filling in reasonable values here. | ||
718 | * A node id of "-1" means "use current node". In other words, if a bus | ||
719 | * has a -1 node id, it's not tightly coupled to any particular chunk | ||
720 | * of memory (as is the case on some Nehalem systems). | ||
721 | */ | ||
722 | #ifdef CONFIG_NUMA | ||
723 | |||
724 | #define BUS_NR 256 | ||
725 | |||
726 | #ifdef CONFIG_X86_64 | ||
727 | |||
728 | static int mp_bus_to_node[BUS_NR] = { | ||
729 | [0 ... BUS_NR - 1] = -1 | ||
730 | }; | ||
731 | |||
732 | void set_mp_bus_to_node(int busnum, int node) | ||
733 | { | ||
734 | if (busnum >= 0 && busnum < BUS_NR) | ||
735 | mp_bus_to_node[busnum] = node; | ||
736 | } | ||
737 | |||
738 | int get_mp_bus_to_node(int busnum) | ||
739 | { | ||
740 | int node = -1; | ||
741 | |||
742 | if (busnum < 0 || busnum > (BUS_NR - 1)) | ||
743 | return node; | ||
744 | |||
745 | node = mp_bus_to_node[busnum]; | ||
746 | |||
747 | /* | ||
748 | * let numa_node_id to decide it later in dma_alloc_pages | ||
749 | * if there is no ram on that node | ||
750 | */ | ||
751 | if (node != -1 && !node_online(node)) | ||
752 | node = -1; | ||
753 | |||
754 | return node; | ||
755 | } | ||
756 | |||
757 | #else /* CONFIG_X86_32 */ | ||
758 | |||
759 | static int mp_bus_to_node[BUS_NR] = { | ||
760 | [0 ... BUS_NR - 1] = -1 | ||
761 | }; | ||
762 | |||
763 | void set_mp_bus_to_node(int busnum, int node) | ||
764 | { | ||
765 | if (busnum >= 0 && busnum < BUS_NR) | ||
766 | mp_bus_to_node[busnum] = (unsigned char) node; | ||
767 | } | ||
768 | |||
769 | int get_mp_bus_to_node(int busnum) | ||
770 | { | ||
771 | int node; | ||
772 | |||
773 | if (busnum < 0 || busnum > (BUS_NR - 1)) | ||
774 | return 0; | ||
775 | node = mp_bus_to_node[busnum]; | ||
776 | return node; | ||
777 | } | ||
778 | |||
779 | #endif /* CONFIG_X86_32 */ | ||
780 | |||
781 | #endif /* CONFIG_NUMA */ | ||
diff --git a/arch/x86/pci/fixup.c b/arch/x86/pci/fixup.c index bca9e85daaa5..94ae9ae9574f 100644 --- a/arch/x86/pci/fixup.c +++ b/arch/x86/pci/fixup.c | |||
@@ -25,9 +25,9 @@ static void pci_fixup_i450nx(struct pci_dev *d) | |||
25 | dev_dbg(&d->dev, "i450NX PXB %d: %02x/%02x/%02x\n", pxb, busno, | 25 | dev_dbg(&d->dev, "i450NX PXB %d: %02x/%02x/%02x\n", pxb, busno, |
26 | suba, subb); | 26 | suba, subb); |
27 | if (busno) | 27 | if (busno) |
28 | pci_scan_bus_with_sysdata(busno); /* Bus A */ | 28 | pcibios_scan_root(busno); /* Bus A */ |
29 | if (suba < subb) | 29 | if (suba < subb) |
30 | pci_scan_bus_with_sysdata(suba+1); /* Bus B */ | 30 | pcibios_scan_root(suba+1); /* Bus B */ |
31 | } | 31 | } |
32 | pcibios_last_bus = -1; | 32 | pcibios_last_bus = -1; |
33 | } | 33 | } |
@@ -42,7 +42,7 @@ static void pci_fixup_i450gx(struct pci_dev *d) | |||
42 | u8 busno; | 42 | u8 busno; |
43 | pci_read_config_byte(d, 0x4a, &busno); | 43 | pci_read_config_byte(d, 0x4a, &busno); |
44 | dev_info(&d->dev, "i440KX/GX host bridge; secondary bus %02x\n", busno); | 44 | dev_info(&d->dev, "i440KX/GX host bridge; secondary bus %02x\n", busno); |
45 | pci_scan_bus_with_sysdata(busno); | 45 | pcibios_scan_root(busno); |
46 | pcibios_last_bus = -1; | 46 | pcibios_last_bus = -1; |
47 | } | 47 | } |
48 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454GX, pci_fixup_i450gx); | 48 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454GX, pci_fixup_i450gx); |
@@ -313,9 +313,10 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MCH_PC1, pcie_r | |||
313 | * IORESOURCE_ROM_SHADOW is used to associate the boot video | 313 | * IORESOURCE_ROM_SHADOW is used to associate the boot video |
314 | * card with this copy. On laptops this copy has to be used since | 314 | * card with this copy. On laptops this copy has to be used since |
315 | * the main ROM may be compressed or combined with another image. | 315 | * the main ROM may be compressed or combined with another image. |
316 | * See pci_map_rom() for use of this flag. IORESOURCE_ROM_SHADOW | 316 | * See pci_map_rom() for use of this flag. Before marking the device |
317 | * is marked here since the boot video device will be the only enabled | 317 | * with IORESOURCE_ROM_SHADOW check if a vga_default_device is already set |
318 | * video device at this point. | 318 | * by either arch cde or vga-arbitration, if so only apply the fixup to this |
319 | * already determined primary video card. | ||
319 | */ | 320 | */ |
320 | 321 | ||
321 | static void pci_fixup_video(struct pci_dev *pdev) | 322 | static void pci_fixup_video(struct pci_dev *pdev) |
@@ -346,12 +347,13 @@ static void pci_fixup_video(struct pci_dev *pdev) | |||
346 | } | 347 | } |
347 | bus = bus->parent; | 348 | bus = bus->parent; |
348 | } | 349 | } |
349 | pci_read_config_word(pdev, PCI_COMMAND, &config); | 350 | if (!vga_default_device() || pdev == vga_default_device()) { |
350 | if (config & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) { | 351 | pci_read_config_word(pdev, PCI_COMMAND, &config); |
351 | pdev->resource[PCI_ROM_RESOURCE].flags |= IORESOURCE_ROM_SHADOW; | 352 | if (config & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) { |
352 | dev_printk(KERN_DEBUG, &pdev->dev, "Boot video device\n"); | 353 | pdev->resource[PCI_ROM_RESOURCE].flags |= IORESOURCE_ROM_SHADOW; |
353 | if (!vga_default_device()) | 354 | dev_printk(KERN_DEBUG, &pdev->dev, "Boot video device\n"); |
354 | vga_set_default_device(pdev); | 355 | vga_set_default_device(pdev); |
356 | } | ||
355 | } | 357 | } |
356 | } | 358 | } |
357 | DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_ANY_ID, PCI_ANY_ID, | 359 | DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_ANY_ID, PCI_ANY_ID, |
diff --git a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c index 372e9b8989b3..84112f55dd7a 100644 --- a/arch/x86/pci/irq.c +++ b/arch/x86/pci/irq.c | |||
@@ -136,13 +136,9 @@ static void __init pirq_peer_trick(void) | |||
136 | busmap[e->bus] = 1; | 136 | busmap[e->bus] = 1; |
137 | } | 137 | } |
138 | for (i = 1; i < 256; i++) { | 138 | for (i = 1; i < 256; i++) { |
139 | int node; | ||
140 | if (!busmap[i] || pci_find_bus(0, i)) | 139 | if (!busmap[i] || pci_find_bus(0, i)) |
141 | continue; | 140 | continue; |
142 | node = get_mp_bus_to_node(i); | 141 | pcibios_scan_root(i); |
143 | if (pci_scan_bus_on_node(i, &pci_root_ops, node)) | ||
144 | printk(KERN_INFO "PCI: Discovered primary peer " | ||
145 | "bus %02x [IRQ]\n", i); | ||
146 | } | 142 | } |
147 | pcibios_last_bus = -1; | 143 | pcibios_last_bus = -1; |
148 | } | 144 | } |
diff --git a/arch/x86/pci/legacy.c b/arch/x86/pci/legacy.c index 4db96fb1c232..5b662c0faf8c 100644 --- a/arch/x86/pci/legacy.c +++ b/arch/x86/pci/legacy.c | |||
@@ -37,19 +37,17 @@ int __init pci_legacy_init(void) | |||
37 | void pcibios_scan_specific_bus(int busn) | 37 | void pcibios_scan_specific_bus(int busn) |
38 | { | 38 | { |
39 | int devfn; | 39 | int devfn; |
40 | long node; | ||
41 | u32 l; | 40 | u32 l; |
42 | 41 | ||
43 | if (pci_find_bus(0, busn)) | 42 | if (pci_find_bus(0, busn)) |
44 | return; | 43 | return; |
45 | 44 | ||
46 | node = get_mp_bus_to_node(busn); | ||
47 | for (devfn = 0; devfn < 256; devfn += 8) { | 45 | for (devfn = 0; devfn < 256; devfn += 8) { |
48 | if (!raw_pci_read(0, busn, devfn, PCI_VENDOR_ID, 2, &l) && | 46 | if (!raw_pci_read(0, busn, devfn, PCI_VENDOR_ID, 2, &l) && |
49 | l != 0x0000 && l != 0xffff) { | 47 | l != 0x0000 && l != 0xffff) { |
50 | DBG("Found device at %02x:%02x [%04x]\n", busn, devfn, l); | 48 | DBG("Found device at %02x:%02x [%04x]\n", busn, devfn, l); |
51 | printk(KERN_INFO "PCI: Discovered peer bus %02x\n", busn); | 49 | printk(KERN_INFO "PCI: Discovered peer bus %02x\n", busn); |
52 | pci_scan_bus_on_node(busn, &pci_root_ops, node); | 50 | pcibios_scan_root(busn); |
53 | return; | 51 | return; |
54 | } | 52 | } |
55 | } | 53 | } |
diff --git a/arch/x86/pci/numaq_32.c b/arch/x86/pci/numaq_32.c index 72c229f9ebcf..080eb0374fff 100644 --- a/arch/x86/pci/numaq_32.c +++ b/arch/x86/pci/numaq_32.c | |||
@@ -135,11 +135,11 @@ static void pci_fixup_i450nx(struct pci_dev *d) | |||
135 | pxb, busno, suba, subb); | 135 | pxb, busno, suba, subb); |
136 | if (busno) { | 136 | if (busno) { |
137 | /* Bus A */ | 137 | /* Bus A */ |
138 | pci_scan_bus_with_sysdata(QUADLOCAL2BUS(quad, busno)); | 138 | pcibios_scan_root(QUADLOCAL2BUS(quad, busno)); |
139 | } | 139 | } |
140 | if (suba < subb) { | 140 | if (suba < subb) { |
141 | /* Bus B */ | 141 | /* Bus B */ |
142 | pci_scan_bus_with_sysdata(QUADLOCAL2BUS(quad, suba+1)); | 142 | pcibios_scan_root(QUADLOCAL2BUS(quad, suba+1)); |
143 | } | 143 | } |
144 | } | 144 | } |
145 | pcibios_last_bus = -1; | 145 | pcibios_last_bus = -1; |
@@ -159,7 +159,7 @@ int __init pci_numaq_init(void) | |||
159 | continue; | 159 | continue; |
160 | printk("Scanning PCI bus %d for quad %d\n", | 160 | printk("Scanning PCI bus %d for quad %d\n", |
161 | QUADLOCAL2BUS(quad,0), quad); | 161 | QUADLOCAL2BUS(quad,0), quad); |
162 | pci_scan_bus_with_sysdata(QUADLOCAL2BUS(quad, 0)); | 162 | pcibios_scan_root(QUADLOCAL2BUS(quad, 0)); |
163 | } | 163 | } |
164 | return 0; | 164 | return 0; |
165 | } | 165 | } |
diff --git a/arch/x86/pci/visws.c b/arch/x86/pci/visws.c index 3e6d2a6db866..cd9d4d1681d2 100644 --- a/arch/x86/pci/visws.c +++ b/arch/x86/pci/visws.c | |||
@@ -78,8 +78,8 @@ int __init pci_visws_init(void) | |||
78 | "bridge B (PIIX4) bus: %u\n", pci_bus1, pci_bus0); | 78 | "bridge B (PIIX4) bus: %u\n", pci_bus1, pci_bus0); |
79 | 79 | ||
80 | raw_pci_ops = &pci_direct_conf1; | 80 | raw_pci_ops = &pci_direct_conf1; |
81 | pci_scan_bus_with_sysdata(pci_bus0); | 81 | pcibios_scan_root(pci_bus0); |
82 | pci_scan_bus_with_sysdata(pci_bus1); | 82 | pcibios_scan_root(pci_bus1); |
83 | pci_fixup_irqs(pci_common_swizzle, visws_map_irq); | 83 | pci_fixup_irqs(pci_common_swizzle, visws_map_irq); |
84 | pcibios_resource_survey(); | 84 | pcibios_resource_survey(); |
85 | /* Request bus scan */ | 85 | /* Request bus scan */ |
diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c index 9e6816ef280a..24b5476449a1 100644 --- a/drivers/acpi/numa.c +++ b/drivers/acpi/numa.c | |||
@@ -60,7 +60,7 @@ int node_to_pxm(int node) | |||
60 | return node_to_pxm_map[node]; | 60 | return node_to_pxm_map[node]; |
61 | } | 61 | } |
62 | 62 | ||
63 | void __acpi_map_pxm_to_node(int pxm, int node) | 63 | static void __acpi_map_pxm_to_node(int pxm, int node) |
64 | { | 64 | { |
65 | if (pxm_to_node_map[pxm] == NUMA_NO_NODE || node < pxm_to_node_map[pxm]) | 65 | if (pxm_to_node_map[pxm] == NUMA_NO_NODE || node < pxm_to_node_map[pxm]) |
66 | pxm_to_node_map[pxm] = node; | 66 | pxm_to_node_map[pxm] = node; |
@@ -193,7 +193,7 @@ static int __init acpi_parse_slit(struct acpi_table_header *table) | |||
193 | return 0; | 193 | return 0; |
194 | } | 194 | } |
195 | 195 | ||
196 | void __init __attribute__ ((weak)) | 196 | void __init __weak |
197 | acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa) | 197 | acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa) |
198 | { | 198 | { |
199 | printk(KERN_WARNING PREFIX | 199 | printk(KERN_WARNING PREFIX |
@@ -314,7 +314,7 @@ int __init acpi_numa_init(void) | |||
314 | return 0; | 314 | return 0; |
315 | } | 315 | } |
316 | 316 | ||
317 | int acpi_get_pxm(acpi_handle h) | 317 | static int acpi_get_pxm(acpi_handle h) |
318 | { | 318 | { |
319 | unsigned long long pxm; | 319 | unsigned long long pxm; |
320 | acpi_status status; | 320 | acpi_status status; |
@@ -331,14 +331,14 @@ int acpi_get_pxm(acpi_handle h) | |||
331 | return -1; | 331 | return -1; |
332 | } | 332 | } |
333 | 333 | ||
334 | int acpi_get_node(acpi_handle *handle) | 334 | int acpi_get_node(acpi_handle handle) |
335 | { | 335 | { |
336 | int pxm, node = NUMA_NO_NODE; | 336 | int pxm; |
337 | 337 | ||
338 | pxm = acpi_get_pxm(handle); | 338 | pxm = acpi_get_pxm(handle); |
339 | if (pxm >= 0 && pxm < MAX_PXM_DOMAINS) | 339 | if (pxm < 0 || pxm >= MAX_PXM_DOMAINS) |
340 | node = acpi_map_pxm_to_node(pxm); | 340 | return NUMA_NO_NODE; |
341 | 341 | ||
342 | return node; | 342 | return acpi_map_pxm_to_node(pxm); |
343 | } | 343 | } |
344 | EXPORT_SYMBOL(acpi_get_node); | 344 | EXPORT_SYMBOL(acpi_get_node); |
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index a52a5b662f35..5a0bf8ed649b 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
@@ -1166,13 +1166,13 @@ static inline void ahci_gtf_filter_workaround(struct ata_host *host) | |||
1166 | static int ahci_init_interrupts(struct pci_dev *pdev, unsigned int n_ports, | 1166 | static int ahci_init_interrupts(struct pci_dev *pdev, unsigned int n_ports, |
1167 | struct ahci_host_priv *hpriv) | 1167 | struct ahci_host_priv *hpriv) |
1168 | { | 1168 | { |
1169 | int rc, nvec; | 1169 | int nvec; |
1170 | 1170 | ||
1171 | if (hpriv->flags & AHCI_HFLAG_NO_MSI) | 1171 | if (hpriv->flags & AHCI_HFLAG_NO_MSI) |
1172 | goto intx; | 1172 | goto intx; |
1173 | 1173 | ||
1174 | rc = pci_msi_vec_count(pdev); | 1174 | nvec = pci_msi_vec_count(pdev); |
1175 | if (rc < 0) | 1175 | if (nvec < 0) |
1176 | goto intx; | 1176 | goto intx; |
1177 | 1177 | ||
1178 | /* | 1178 | /* |
@@ -1180,21 +1180,19 @@ static int ahci_init_interrupts(struct pci_dev *pdev, unsigned int n_ports, | |||
1180 | * Message mode could be enforced. In this case assume that advantage | 1180 | * Message mode could be enforced. In this case assume that advantage |
1181 | * of multipe MSIs is negated and use single MSI mode instead. | 1181 | * of multipe MSIs is negated and use single MSI mode instead. |
1182 | */ | 1182 | */ |
1183 | if (rc < n_ports) | 1183 | if (nvec < n_ports) |
1184 | goto single_msi; | 1184 | goto single_msi; |
1185 | 1185 | ||
1186 | nvec = rc; | 1186 | nvec = pci_enable_msi_range(pdev, nvec, nvec); |
1187 | rc = pci_enable_msi_block(pdev, nvec); | 1187 | if (nvec == -ENOSPC) |
1188 | if (rc < 0) | ||
1189 | goto intx; | ||
1190 | else if (rc > 0) | ||
1191 | goto single_msi; | 1188 | goto single_msi; |
1189 | else if (nvec < 0) | ||
1190 | goto intx; | ||
1192 | 1191 | ||
1193 | return nvec; | 1192 | return nvec; |
1194 | 1193 | ||
1195 | single_msi: | 1194 | single_msi: |
1196 | rc = pci_enable_msi(pdev); | 1195 | if (pci_enable_msi(pdev)) |
1197 | if (rc) | ||
1198 | goto intx; | 1196 | goto intx; |
1199 | return 1; | 1197 | return 1; |
1200 | 1198 | ||
diff --git a/drivers/bus/mvebu-mbus.c b/drivers/bus/mvebu-mbus.c index 725c46162bbd..2ac754e18bcf 100644 --- a/drivers/bus/mvebu-mbus.c +++ b/drivers/bus/mvebu-mbus.c | |||
@@ -870,14 +870,14 @@ static void __init mvebu_mbus_get_pcie_resources(struct device_node *np, | |||
870 | ret = of_property_read_u32_array(np, "pcie-mem-aperture", reg, ARRAY_SIZE(reg)); | 870 | ret = of_property_read_u32_array(np, "pcie-mem-aperture", reg, ARRAY_SIZE(reg)); |
871 | if (!ret) { | 871 | if (!ret) { |
872 | mem->start = reg[0]; | 872 | mem->start = reg[0]; |
873 | mem->end = mem->start + reg[1]; | 873 | mem->end = mem->start + reg[1] - 1; |
874 | mem->flags = IORESOURCE_MEM; | 874 | mem->flags = IORESOURCE_MEM; |
875 | } | 875 | } |
876 | 876 | ||
877 | ret = of_property_read_u32_array(np, "pcie-io-aperture", reg, ARRAY_SIZE(reg)); | 877 | ret = of_property_read_u32_array(np, "pcie-io-aperture", reg, ARRAY_SIZE(reg)); |
878 | if (!ret) { | 878 | if (!ret) { |
879 | io->start = reg[0]; | 879 | io->start = reg[0]; |
880 | io->end = io->start + reg[1]; | 880 | io->end = io->start + reg[1] - 1; |
881 | io->flags = IORESOURCE_IO; | 881 | io->flags = IORESOURCE_IO; |
882 | } | 882 | } |
883 | } | 883 | } |
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c index 7f2af9aca038..309023f12d7f 100644 --- a/drivers/gpu/drm/drm_fops.c +++ b/drivers/gpu/drm/drm_fops.c | |||
@@ -319,7 +319,8 @@ static int drm_open_helper(struct inode *inode, struct file *filp, | |||
319 | pci_dev_put(pci_dev); | 319 | pci_dev_put(pci_dev); |
320 | } | 320 | } |
321 | if (!dev->hose) { | 321 | if (!dev->hose) { |
322 | struct pci_bus *b = pci_bus_b(pci_root_buses.next); | 322 | struct pci_bus *b = list_entry(pci_root_buses.next, |
323 | struct pci_bus, node); | ||
323 | if (b) | 324 | if (b) |
324 | dev->hose = b->sysdata; | 325 | dev->hose = b->sysdata; |
325 | } | 326 | } |
diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h index e400fbe411de..cff039df056e 100644 --- a/drivers/iommu/amd_iommu_types.h +++ b/drivers/iommu/amd_iommu_types.h | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/list.h> | 25 | #include <linux/list.h> |
26 | #include <linux/spinlock.h> | 26 | #include <linux/spinlock.h> |
27 | #include <linux/pci.h> | 27 | #include <linux/pci.h> |
28 | #include <linux/irqreturn.h> | ||
28 | 29 | ||
29 | /* | 30 | /* |
30 | * Maximum number of IOMMUs supported | 31 | * Maximum number of IOMMUs supported |
diff --git a/drivers/message/i2o/iop.c b/drivers/message/i2o/iop.c index a8c08f332da0..92752fb5b2d3 100644 --- a/drivers/message/i2o/iop.c +++ b/drivers/message/i2o/iop.c | |||
@@ -652,6 +652,44 @@ static int i2o_iop_activate(struct i2o_controller *c) | |||
652 | return i2o_hrt_get(c); | 652 | return i2o_hrt_get(c); |
653 | }; | 653 | }; |
654 | 654 | ||
655 | static void i2o_res_alloc(struct i2o_controller *c, unsigned long flags) | ||
656 | { | ||
657 | i2o_status_block *sb = c->status_block.virt; | ||
658 | struct resource *res = &c->mem_resource; | ||
659 | resource_size_t size, align; | ||
660 | int err; | ||
661 | |||
662 | res->name = c->pdev->bus->name; | ||
663 | res->flags = flags; | ||
664 | res->start = 0; | ||
665 | res->end = 0; | ||
666 | osm_info("%s: requires private memory resources.\n", c->name); | ||
667 | |||
668 | if (flags & IORESOURCE_MEM) { | ||
669 | size = sb->desired_mem_size; | ||
670 | align = 1 << 20; /* unspecified, use 1Mb and play safe */ | ||
671 | } else { | ||
672 | size = sb->desired_io_size; | ||
673 | align = 1 << 12; /* unspecified, use 4Kb and play safe */ | ||
674 | } | ||
675 | |||
676 | err = pci_bus_alloc_resource(c->pdev->bus, res, size, align, 0, 0, | ||
677 | NULL, NULL); | ||
678 | if (err < 0) | ||
679 | return; | ||
680 | |||
681 | if (flags & IORESOURCE_MEM) { | ||
682 | c->mem_alloc = 1; | ||
683 | sb->current_mem_size = resource_size(res); | ||
684 | sb->current_mem_base = res->start; | ||
685 | } else if (flags & IORESOURCE_IO) { | ||
686 | c->io_alloc = 1; | ||
687 | sb->current_io_size = resource_size(res); | ||
688 | sb->current_io_base = res->start; | ||
689 | } | ||
690 | osm_info("%s: allocated PCI space %pR\n", c->name, res); | ||
691 | } | ||
692 | |||
655 | /** | 693 | /** |
656 | * i2o_iop_systab_set - Set the I2O System Table of the specified IOP | 694 | * i2o_iop_systab_set - Set the I2O System Table of the specified IOP |
657 | * @c: I2O controller to which the system table should be send | 695 | * @c: I2O controller to which the system table should be send |
@@ -665,52 +703,13 @@ static int i2o_iop_systab_set(struct i2o_controller *c) | |||
665 | struct i2o_message *msg; | 703 | struct i2o_message *msg; |
666 | i2o_status_block *sb = c->status_block.virt; | 704 | i2o_status_block *sb = c->status_block.virt; |
667 | struct device *dev = &c->pdev->dev; | 705 | struct device *dev = &c->pdev->dev; |
668 | struct resource *root; | ||
669 | int rc; | 706 | int rc; |
670 | 707 | ||
671 | if (sb->current_mem_size < sb->desired_mem_size) { | 708 | if (sb->current_mem_size < sb->desired_mem_size) |
672 | struct resource *res = &c->mem_resource; | 709 | i2o_res_alloc(c, IORESOURCE_MEM); |
673 | res->name = c->pdev->bus->name; | ||
674 | res->flags = IORESOURCE_MEM; | ||
675 | res->start = 0; | ||
676 | res->end = 0; | ||
677 | osm_info("%s: requires private memory resources.\n", c->name); | ||
678 | root = pci_find_parent_resource(c->pdev, res); | ||
679 | if (root == NULL) | ||
680 | osm_warn("%s: Can't find parent resource!\n", c->name); | ||
681 | if (root && allocate_resource(root, res, sb->desired_mem_size, sb->desired_mem_size, sb->desired_mem_size, 1 << 20, /* Unspecified, so use 1Mb and play safe */ | ||
682 | NULL, NULL) >= 0) { | ||
683 | c->mem_alloc = 1; | ||
684 | sb->current_mem_size = resource_size(res); | ||
685 | sb->current_mem_base = res->start; | ||
686 | osm_info("%s: allocated %llu bytes of PCI memory at " | ||
687 | "0x%016llX.\n", c->name, | ||
688 | (unsigned long long)resource_size(res), | ||
689 | (unsigned long long)res->start); | ||
690 | } | ||
691 | } | ||
692 | 710 | ||
693 | if (sb->current_io_size < sb->desired_io_size) { | 711 | if (sb->current_io_size < sb->desired_io_size) |
694 | struct resource *res = &c->io_resource; | 712 | i2o_res_alloc(c, IORESOURCE_IO); |
695 | res->name = c->pdev->bus->name; | ||
696 | res->flags = IORESOURCE_IO; | ||
697 | res->start = 0; | ||
698 | res->end = 0; | ||
699 | osm_info("%s: requires private memory resources.\n", c->name); | ||
700 | root = pci_find_parent_resource(c->pdev, res); | ||
701 | if (root == NULL) | ||
702 | osm_warn("%s: Can't find parent resource!\n", c->name); | ||
703 | if (root && allocate_resource(root, res, sb->desired_io_size, sb->desired_io_size, sb->desired_io_size, 1 << 20, /* Unspecified, so use 1Mb and play safe */ | ||
704 | NULL, NULL) >= 0) { | ||
705 | c->io_alloc = 1; | ||
706 | sb->current_io_size = resource_size(res); | ||
707 | sb->current_mem_base = res->start; | ||
708 | osm_info("%s: allocated %llu bytes of PCI I/O at " | ||
709 | "0x%016llX.\n", c->name, | ||
710 | (unsigned long long)resource_size(res), | ||
711 | (unsigned long long)res->start); | ||
712 | } | ||
713 | } | ||
714 | 713 | ||
715 | msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET); | 714 | msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET); |
716 | if (IS_ERR(msg)) | 715 | if (IS_ERR(msg)) |
diff --git a/drivers/misc/mei/hw-me.h b/drivers/misc/mei/hw-me.h index 80bd829fbd9a..893d5119fa9b 100644 --- a/drivers/misc/mei/hw-me.h +++ b/drivers/misc/mei/hw-me.h | |||
@@ -20,6 +20,7 @@ | |||
20 | #define _MEI_INTERFACE_H_ | 20 | #define _MEI_INTERFACE_H_ |
21 | 21 | ||
22 | #include <linux/mei.h> | 22 | #include <linux/mei.h> |
23 | #include <linux/irqreturn.h> | ||
23 | #include "mei_dev.h" | 24 | #include "mei_dev.h" |
24 | #include "client.h" | 25 | #include "client.h" |
25 | 26 | ||
diff --git a/drivers/misc/mic/card/mic_device.h b/drivers/misc/mic/card/mic_device.h index 347b9b3b7916..306f502be95e 100644 --- a/drivers/misc/mic/card/mic_device.h +++ b/drivers/misc/mic/card/mic_device.h | |||
@@ -29,6 +29,7 @@ | |||
29 | 29 | ||
30 | #include <linux/workqueue.h> | 30 | #include <linux/workqueue.h> |
31 | #include <linux/io.h> | 31 | #include <linux/io.h> |
32 | #include <linux/irqreturn.h> | ||
32 | 33 | ||
33 | /** | 34 | /** |
34 | * struct mic_intr_info - Contains h/w specific interrupt sources info | 35 | * struct mic_intr_info - Contains h/w specific interrupt sources info |
diff --git a/drivers/misc/mic/host/mic_device.h b/drivers/misc/mic/host/mic_device.h index 1a6edce2ecde..0398c696d257 100644 --- a/drivers/misc/mic/host/mic_device.h +++ b/drivers/misc/mic/host/mic_device.h | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/cdev.h> | 24 | #include <linux/cdev.h> |
25 | #include <linux/idr.h> | 25 | #include <linux/idr.h> |
26 | #include <linux/notifier.h> | 26 | #include <linux/notifier.h> |
27 | #include <linux/irqreturn.h> | ||
27 | 28 | ||
28 | #include "mic_intr.h" | 29 | #include "mic_intr.h" |
29 | 30 | ||
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index 17d2b07ee67c..e2501ac6fe84 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile | |||
@@ -33,21 +33,15 @@ obj-$(CONFIG_PCI_IOV) += iov.o | |||
33 | # | 33 | # |
34 | # Some architectures use the generic PCI setup functions | 34 | # Some architectures use the generic PCI setup functions |
35 | # | 35 | # |
36 | obj-$(CONFIG_X86) += setup-bus.o | 36 | obj-$(CONFIG_ALPHA) += setup-irq.o |
37 | obj-$(CONFIG_ALPHA) += setup-bus.o setup-irq.o | 37 | obj-$(CONFIG_ARM) += setup-irq.o |
38 | obj-$(CONFIG_ARM) += setup-bus.o setup-irq.o | 38 | obj-$(CONFIG_UNICORE32) += setup-irq.o |
39 | obj-$(CONFIG_UNICORE32) += setup-bus.o setup-irq.o | 39 | obj-$(CONFIG_SUPERH) += setup-irq.o |
40 | obj-$(CONFIG_PARISC) += setup-bus.o | 40 | obj-$(CONFIG_MIPS) += setup-irq.o |
41 | obj-$(CONFIG_SUPERH) += setup-bus.o setup-irq.o | ||
42 | obj-$(CONFIG_PPC) += setup-bus.o | ||
43 | obj-$(CONFIG_FRV) += setup-bus.o | ||
44 | obj-$(CONFIG_MIPS) += setup-bus.o setup-irq.o | ||
45 | obj-$(CONFIG_X86_VISWS) += setup-irq.o | 41 | obj-$(CONFIG_X86_VISWS) += setup-irq.o |
46 | obj-$(CONFIG_MN10300) += setup-bus.o | 42 | obj-$(CONFIG_TILE) += setup-irq.o |
47 | obj-$(CONFIG_MICROBLAZE) += setup-bus.o | 43 | obj-$(CONFIG_SPARC_LEON) += setup-irq.o |
48 | obj-$(CONFIG_TILE) += setup-bus.o setup-irq.o | 44 | obj-$(CONFIG_M68K) += setup-irq.o |
49 | obj-$(CONFIG_SPARC_LEON) += setup-bus.o setup-irq.o | ||
50 | obj-$(CONFIG_M68K) += setup-bus.o setup-irq.o | ||
51 | 45 | ||
52 | # | 46 | # |
53 | # ACPI Related PCI FW Functions | 47 | # ACPI Related PCI FW Functions |
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index 38901665c770..fb8aed307c28 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c | |||
@@ -132,7 +132,7 @@ static void pci_clip_resource_to_region(struct pci_bus *bus, | |||
132 | 132 | ||
133 | static int pci_bus_alloc_from_region(struct pci_bus *bus, struct resource *res, | 133 | static int pci_bus_alloc_from_region(struct pci_bus *bus, struct resource *res, |
134 | resource_size_t size, resource_size_t align, | 134 | resource_size_t size, resource_size_t align, |
135 | resource_size_t min, unsigned int type_mask, | 135 | resource_size_t min, unsigned long type_mask, |
136 | resource_size_t (*alignf)(void *, | 136 | resource_size_t (*alignf)(void *, |
137 | const struct resource *, | 137 | const struct resource *, |
138 | resource_size_t, | 138 | resource_size_t, |
@@ -144,7 +144,7 @@ static int pci_bus_alloc_from_region(struct pci_bus *bus, struct resource *res, | |||
144 | struct resource *r, avail; | 144 | struct resource *r, avail; |
145 | resource_size_t max; | 145 | resource_size_t max; |
146 | 146 | ||
147 | type_mask |= IORESOURCE_IO | IORESOURCE_MEM; | 147 | type_mask |= IORESOURCE_TYPE_BITS; |
148 | 148 | ||
149 | pci_bus_for_each_resource(bus, r, i) { | 149 | pci_bus_for_each_resource(bus, r, i) { |
150 | if (!r) | 150 | if (!r) |
@@ -200,7 +200,7 @@ static int pci_bus_alloc_from_region(struct pci_bus *bus, struct resource *res, | |||
200 | */ | 200 | */ |
201 | int pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, | 201 | int pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, |
202 | resource_size_t size, resource_size_t align, | 202 | resource_size_t size, resource_size_t align, |
203 | resource_size_t min, unsigned int type_mask, | 203 | resource_size_t min, unsigned long type_mask, |
204 | resource_size_t (*alignf)(void *, | 204 | resource_size_t (*alignf)(void *, |
205 | const struct resource *, | 205 | const struct resource *, |
206 | resource_size_t, | 206 | resource_size_t, |
diff --git a/drivers/pci/host-bridge.c b/drivers/pci/host-bridge.c index 06ace6248c61..47aaf22d814e 100644 --- a/drivers/pci/host-bridge.c +++ b/drivers/pci/host-bridge.c | |||
@@ -32,11 +32,6 @@ void pci_set_host_bridge_release(struct pci_host_bridge *bridge, | |||
32 | bridge->release_data = release_data; | 32 | bridge->release_data = release_data; |
33 | } | 33 | } |
34 | 34 | ||
35 | static bool resource_contains(struct resource *res1, struct resource *res2) | ||
36 | { | ||
37 | return res1->start <= res2->start && res1->end >= res2->end; | ||
38 | } | ||
39 | |||
40 | void pcibios_resource_to_bus(struct pci_bus *bus, struct pci_bus_region *region, | 35 | void pcibios_resource_to_bus(struct pci_bus *bus, struct pci_bus_region *region, |
41 | struct resource *res) | 36 | struct resource *res) |
42 | { | 37 | { |
@@ -45,9 +40,6 @@ void pcibios_resource_to_bus(struct pci_bus *bus, struct pci_bus_region *region, | |||
45 | resource_size_t offset = 0; | 40 | resource_size_t offset = 0; |
46 | 41 | ||
47 | list_for_each_entry(window, &bridge->windows, list) { | 42 | list_for_each_entry(window, &bridge->windows, list) { |
48 | if (resource_type(res) != resource_type(window->res)) | ||
49 | continue; | ||
50 | |||
51 | if (resource_contains(window->res, res)) { | 43 | if (resource_contains(window->res, res)) { |
52 | offset = window->offset; | 44 | offset = window->offset; |
53 | break; | 45 | break; |
diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig index 47d46c6d8468..a6f67ec8882f 100644 --- a/drivers/pci/host/Kconfig +++ b/drivers/pci/host/Kconfig | |||
@@ -27,7 +27,7 @@ config PCI_TEGRA | |||
27 | 27 | ||
28 | config PCI_RCAR_GEN2 | 28 | config PCI_RCAR_GEN2 |
29 | bool "Renesas R-Car Gen2 Internal PCI controller" | 29 | bool "Renesas R-Car Gen2 Internal PCI controller" |
30 | depends on ARM && (ARCH_R8A7790 || ARCH_R8A7791 || COMPILE_TEST) | 30 | depends on ARCH_SHMOBILE || (ARM && COMPILE_TEST) |
31 | help | 31 | help |
32 | Say Y here if you want internal PCI support on R-Car Gen2 SoC. | 32 | Say Y here if you want internal PCI support on R-Car Gen2 SoC. |
33 | There are 3 internal PCI controllers available with a single | 33 | There are 3 internal PCI controllers available with a single |
diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-imx6.c index e8663a8c3406..ee082509b0ba 100644 --- a/drivers/pci/host/pci-imx6.c +++ b/drivers/pci/host/pci-imx6.c | |||
@@ -424,20 +424,40 @@ static void imx6_pcie_reset_phy(struct pcie_port *pp) | |||
424 | 424 | ||
425 | static int imx6_pcie_link_up(struct pcie_port *pp) | 425 | static int imx6_pcie_link_up(struct pcie_port *pp) |
426 | { | 426 | { |
427 | u32 rc, ltssm, rx_valid; | 427 | u32 rc, debug_r0, rx_valid; |
428 | int count = 5; | ||
428 | 429 | ||
429 | /* | 430 | /* |
430 | * Test if the PHY reports that the link is up and also that | 431 | * Test if the PHY reports that the link is up and also that the LTSSM |
431 | * the link training finished. It might happen that the PHY | 432 | * training finished. There are three possible states of the link when |
432 | * reports the link is already up, but the link training bit | 433 | * this code is called: |
433 | * is still set, so make sure to check the training is done | 434 | * 1) The link is DOWN (unlikely) |
434 | * as well here. | 435 | * The link didn't come up yet for some reason. This usually means |
436 | * we have a real problem somewhere. Reset the PHY and exit. This | ||
437 | * state calls for inspection of the DEBUG registers. | ||
438 | * 2) The link is UP, but still in LTSSM training | ||
439 | * Wait for the training to finish, which should take a very short | ||
440 | * time. If the training does not finish, we have a problem and we | ||
441 | * need to inspect the DEBUG registers. If the training does finish, | ||
442 | * the link is up and operating correctly. | ||
443 | * 3) The link is UP and no longer in LTSSM training | ||
444 | * The link is up and operating correctly. | ||
435 | */ | 445 | */ |
436 | rc = readl(pp->dbi_base + PCIE_PHY_DEBUG_R1); | 446 | while (1) { |
437 | if ((rc & PCIE_PHY_DEBUG_R1_XMLH_LINK_UP) && | 447 | rc = readl(pp->dbi_base + PCIE_PHY_DEBUG_R1); |
438 | !(rc & PCIE_PHY_DEBUG_R1_XMLH_LINK_IN_TRAINING)) | 448 | if (!(rc & PCIE_PHY_DEBUG_R1_XMLH_LINK_UP)) |
439 | return 1; | 449 | break; |
440 | 450 | if (!(rc & PCIE_PHY_DEBUG_R1_XMLH_LINK_IN_TRAINING)) | |
451 | return 1; | ||
452 | if (!count--) | ||
453 | break; | ||
454 | dev_dbg(pp->dev, "Link is up, but still in training\n"); | ||
455 | /* | ||
456 | * Wait a little bit, then re-check if the link finished | ||
457 | * the training. | ||
458 | */ | ||
459 | usleep_range(1000, 2000); | ||
460 | } | ||
441 | /* | 461 | /* |
442 | * From L0, initiate MAC entry to gen2 if EP/RC supports gen2. | 462 | * From L0, initiate MAC entry to gen2 if EP/RC supports gen2. |
443 | * Wait 2ms (LTSSM timeout is 24ms, PHY lock is ~5us in gen2). | 463 | * Wait 2ms (LTSSM timeout is 24ms, PHY lock is ~5us in gen2). |
@@ -446,15 +466,16 @@ static int imx6_pcie_link_up(struct pcie_port *pp) | |||
446 | * to gen2 is stuck | 466 | * to gen2 is stuck |
447 | */ | 467 | */ |
448 | pcie_phy_read(pp->dbi_base, PCIE_PHY_RX_ASIC_OUT, &rx_valid); | 468 | pcie_phy_read(pp->dbi_base, PCIE_PHY_RX_ASIC_OUT, &rx_valid); |
449 | ltssm = readl(pp->dbi_base + PCIE_PHY_DEBUG_R0) & 0x3F; | 469 | debug_r0 = readl(pp->dbi_base + PCIE_PHY_DEBUG_R0); |
450 | 470 | ||
451 | if (rx_valid & 0x01) | 471 | if (rx_valid & 0x01) |
452 | return 0; | 472 | return 0; |
453 | 473 | ||
454 | if (ltssm != 0x0d) | 474 | if ((debug_r0 & 0x3f) != 0x0d) |
455 | return 0; | 475 | return 0; |
456 | 476 | ||
457 | dev_err(pp->dev, "transition to gen2 is stuck, reset PHY!\n"); | 477 | dev_err(pp->dev, "transition to gen2 is stuck, reset PHY!\n"); |
478 | dev_dbg(pp->dev, "debug_r0=%08x debug_r1=%08x\n", debug_r0, rc); | ||
458 | 479 | ||
459 | imx6_pcie_reset_phy(pp); | 480 | imx6_pcie_reset_phy(pp); |
460 | 481 | ||
diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c index 0e79665afd44..d3d1cfd51e09 100644 --- a/drivers/pci/host/pci-mvebu.c +++ b/drivers/pci/host/pci-mvebu.c | |||
@@ -101,7 +101,9 @@ struct mvebu_pcie { | |||
101 | struct mvebu_pcie_port *ports; | 101 | struct mvebu_pcie_port *ports; |
102 | struct msi_chip *msi; | 102 | struct msi_chip *msi; |
103 | struct resource io; | 103 | struct resource io; |
104 | char io_name[30]; | ||
104 | struct resource realio; | 105 | struct resource realio; |
106 | char mem_name[30]; | ||
105 | struct resource mem; | 107 | struct resource mem; |
106 | struct resource busn; | 108 | struct resource busn; |
107 | int nports; | 109 | int nports; |
@@ -672,10 +674,30 @@ static int mvebu_pcie_setup(int nr, struct pci_sys_data *sys) | |||
672 | { | 674 | { |
673 | struct mvebu_pcie *pcie = sys_to_pcie(sys); | 675 | struct mvebu_pcie *pcie = sys_to_pcie(sys); |
674 | int i; | 676 | int i; |
677 | int domain = 0; | ||
675 | 678 | ||
676 | if (resource_size(&pcie->realio) != 0) | 679 | #ifdef CONFIG_PCI_DOMAINS |
680 | domain = sys->domain; | ||
681 | #endif | ||
682 | |||
683 | snprintf(pcie->mem_name, sizeof(pcie->mem_name), "PCI MEM %04x", | ||
684 | domain); | ||
685 | pcie->mem.name = pcie->mem_name; | ||
686 | |||
687 | snprintf(pcie->io_name, sizeof(pcie->io_name), "PCI I/O %04x", domain); | ||
688 | pcie->realio.name = pcie->io_name; | ||
689 | |||
690 | if (request_resource(&iomem_resource, &pcie->mem)) | ||
691 | return 0; | ||
692 | |||
693 | if (resource_size(&pcie->realio) != 0) { | ||
694 | if (request_resource(&ioport_resource, &pcie->realio)) { | ||
695 | release_resource(&pcie->mem); | ||
696 | return 0; | ||
697 | } | ||
677 | pci_add_resource_offset(&sys->resources, &pcie->realio, | 698 | pci_add_resource_offset(&sys->resources, &pcie->realio, |
678 | sys->io_offset); | 699 | sys->io_offset); |
700 | } | ||
679 | pci_add_resource_offset(&sys->resources, &pcie->mem, sys->mem_offset); | 701 | pci_add_resource_offset(&sys->resources, &pcie->mem, sys->mem_offset); |
680 | pci_add_resource(&sys->resources, &pcie->busn); | 702 | pci_add_resource(&sys->resources, &pcie->busn); |
681 | 703 | ||
@@ -797,7 +819,7 @@ static int mvebu_get_tgt_attr(struct device_node *np, int devfn, | |||
797 | 819 | ||
798 | for (i = 0; i < nranges; i++) { | 820 | for (i = 0; i < nranges; i++) { |
799 | u32 flags = of_read_number(range, 1); | 821 | u32 flags = of_read_number(range, 1); |
800 | u32 slot = of_read_number(range, 2); | 822 | u32 slot = of_read_number(range + 1, 1); |
801 | u64 cpuaddr = of_read_number(range + na, pna); | 823 | u64 cpuaddr = of_read_number(range + na, pna); |
802 | unsigned long rtype; | 824 | unsigned long rtype; |
803 | 825 | ||
diff --git a/drivers/pci/host/pci-rcar-gen2.c b/drivers/pci/host/pci-rcar-gen2.c index ceec147baec3..fd3e3ab56509 100644 --- a/drivers/pci/host/pci-rcar-gen2.c +++ b/drivers/pci/host/pci-rcar-gen2.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/pci.h> | 18 | #include <linux/pci.h> |
19 | #include <linux/platform_device.h> | 19 | #include <linux/platform_device.h> |
20 | #include <linux/pm_runtime.h> | 20 | #include <linux/pm_runtime.h> |
21 | #include <linux/sizes.h> | ||
21 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
22 | 23 | ||
23 | /* AHB-PCI Bridge PCI communication registers */ | 24 | /* AHB-PCI Bridge PCI communication registers */ |
@@ -39,9 +40,26 @@ | |||
39 | 40 | ||
40 | #define RCAR_PCI_INT_ENABLE_REG (RCAR_AHBPCI_PCICOM_OFFSET + 0x20) | 41 | #define RCAR_PCI_INT_ENABLE_REG (RCAR_AHBPCI_PCICOM_OFFSET + 0x20) |
41 | #define RCAR_PCI_INT_STATUS_REG (RCAR_AHBPCI_PCICOM_OFFSET + 0x24) | 42 | #define RCAR_PCI_INT_STATUS_REG (RCAR_AHBPCI_PCICOM_OFFSET + 0x24) |
43 | #define RCAR_PCI_INT_SIGTABORT (1 << 0) | ||
44 | #define RCAR_PCI_INT_SIGRETABORT (1 << 1) | ||
45 | #define RCAR_PCI_INT_REMABORT (1 << 2) | ||
46 | #define RCAR_PCI_INT_PERR (1 << 3) | ||
47 | #define RCAR_PCI_INT_SIGSERR (1 << 4) | ||
48 | #define RCAR_PCI_INT_RESERR (1 << 5) | ||
49 | #define RCAR_PCI_INT_WIN1ERR (1 << 12) | ||
50 | #define RCAR_PCI_INT_WIN2ERR (1 << 13) | ||
42 | #define RCAR_PCI_INT_A (1 << 16) | 51 | #define RCAR_PCI_INT_A (1 << 16) |
43 | #define RCAR_PCI_INT_B (1 << 17) | 52 | #define RCAR_PCI_INT_B (1 << 17) |
44 | #define RCAR_PCI_INT_PME (1 << 19) | 53 | #define RCAR_PCI_INT_PME (1 << 19) |
54 | #define RCAR_PCI_INT_ALLERRORS (RCAR_PCI_INT_SIGTABORT | \ | ||
55 | RCAR_PCI_INT_SIGRETABORT | \ | ||
56 | RCAR_PCI_INT_SIGRETABORT | \ | ||
57 | RCAR_PCI_INT_REMABORT | \ | ||
58 | RCAR_PCI_INT_PERR | \ | ||
59 | RCAR_PCI_INT_SIGSERR | \ | ||
60 | RCAR_PCI_INT_RESERR | \ | ||
61 | RCAR_PCI_INT_WIN1ERR | \ | ||
62 | RCAR_PCI_INT_WIN2ERR) | ||
45 | 63 | ||
46 | #define RCAR_AHB_BUS_CTR_REG (RCAR_AHBPCI_PCICOM_OFFSET + 0x30) | 64 | #define RCAR_AHB_BUS_CTR_REG (RCAR_AHBPCI_PCICOM_OFFSET + 0x30) |
47 | #define RCAR_AHB_BUS_MMODE_HTRANS (1 << 0) | 65 | #define RCAR_AHB_BUS_MMODE_HTRANS (1 << 0) |
@@ -74,9 +92,6 @@ | |||
74 | 92 | ||
75 | #define RCAR_PCI_UNIT_REV_REG (RCAR_AHBPCI_PCICOM_OFFSET + 0x48) | 93 | #define RCAR_PCI_UNIT_REV_REG (RCAR_AHBPCI_PCICOM_OFFSET + 0x48) |
76 | 94 | ||
77 | /* Number of internal PCI controllers */ | ||
78 | #define RCAR_PCI_NR_CONTROLLERS 3 | ||
79 | |||
80 | struct rcar_pci_priv { | 95 | struct rcar_pci_priv { |
81 | struct device *dev; | 96 | struct device *dev; |
82 | void __iomem *reg; | 97 | void __iomem *reg; |
@@ -84,6 +99,7 @@ struct rcar_pci_priv { | |||
84 | struct resource mem_res; | 99 | struct resource mem_res; |
85 | struct resource *cfg_res; | 100 | struct resource *cfg_res; |
86 | int irq; | 101 | int irq; |
102 | unsigned long window_size; | ||
87 | }; | 103 | }; |
88 | 104 | ||
89 | /* PCI configuration space operations */ | 105 | /* PCI configuration space operations */ |
@@ -102,6 +118,10 @@ static void __iomem *rcar_pci_cfg_base(struct pci_bus *bus, unsigned int devfn, | |||
102 | if (slot > 2) | 118 | if (slot > 2) |
103 | return NULL; | 119 | return NULL; |
104 | 120 | ||
121 | /* bridge logic only has registers to 0x40 */ | ||
122 | if (slot == 0x0 && where >= 0x40) | ||
123 | return NULL; | ||
124 | |||
105 | val = slot ? RCAR_AHBPCI_WIN1_DEVICE | RCAR_AHBPCI_WIN_CTR_CFG : | 125 | val = slot ? RCAR_AHBPCI_WIN1_DEVICE | RCAR_AHBPCI_WIN_CTR_CFG : |
106 | RCAR_AHBPCI_WIN1_HOST | RCAR_AHBPCI_WIN_CTR_CFG; | 126 | RCAR_AHBPCI_WIN1_HOST | RCAR_AHBPCI_WIN_CTR_CFG; |
107 | 127 | ||
@@ -156,7 +176,7 @@ static int rcar_pci_write_config(struct pci_bus *bus, unsigned int devfn, | |||
156 | } | 176 | } |
157 | 177 | ||
158 | /* PCI interrupt mapping */ | 178 | /* PCI interrupt mapping */ |
159 | static int __init rcar_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | 179 | static int rcar_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) |
160 | { | 180 | { |
161 | struct pci_sys_data *sys = dev->bus->sysdata; | 181 | struct pci_sys_data *sys = dev->bus->sysdata; |
162 | struct rcar_pci_priv *priv = sys->private_data; | 182 | struct rcar_pci_priv *priv = sys->private_data; |
@@ -164,8 +184,48 @@ static int __init rcar_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |||
164 | return priv->irq; | 184 | return priv->irq; |
165 | } | 185 | } |
166 | 186 | ||
187 | #ifdef CONFIG_PCI_DEBUG | ||
188 | /* if debug enabled, then attach an error handler irq to the bridge */ | ||
189 | |||
190 | static irqreturn_t rcar_pci_err_irq(int irq, void *pw) | ||
191 | { | ||
192 | struct rcar_pci_priv *priv = pw; | ||
193 | u32 status = ioread32(priv->reg + RCAR_PCI_INT_STATUS_REG); | ||
194 | |||
195 | if (status & RCAR_PCI_INT_ALLERRORS) { | ||
196 | dev_err(priv->dev, "error irq: status %08x\n", status); | ||
197 | |||
198 | /* clear the error(s) */ | ||
199 | iowrite32(status & RCAR_PCI_INT_ALLERRORS, | ||
200 | priv->reg + RCAR_PCI_INT_STATUS_REG); | ||
201 | return IRQ_HANDLED; | ||
202 | } | ||
203 | |||
204 | return IRQ_NONE; | ||
205 | } | ||
206 | |||
207 | static void rcar_pci_setup_errirq(struct rcar_pci_priv *priv) | ||
208 | { | ||
209 | int ret; | ||
210 | u32 val; | ||
211 | |||
212 | ret = devm_request_irq(priv->dev, priv->irq, rcar_pci_err_irq, | ||
213 | IRQF_SHARED, "error irq", priv); | ||
214 | if (ret) { | ||
215 | dev_err(priv->dev, "cannot claim IRQ for error handling\n"); | ||
216 | return; | ||
217 | } | ||
218 | |||
219 | val = ioread32(priv->reg + RCAR_PCI_INT_ENABLE_REG); | ||
220 | val |= RCAR_PCI_INT_ALLERRORS; | ||
221 | iowrite32(val, priv->reg + RCAR_PCI_INT_ENABLE_REG); | ||
222 | } | ||
223 | #else | ||
224 | static inline void rcar_pci_setup_errirq(struct rcar_pci_priv *priv) { } | ||
225 | #endif | ||
226 | |||
167 | /* PCI host controller setup */ | 227 | /* PCI host controller setup */ |
168 | static int __init rcar_pci_setup(int nr, struct pci_sys_data *sys) | 228 | static int rcar_pci_setup(int nr, struct pci_sys_data *sys) |
169 | { | 229 | { |
170 | struct rcar_pci_priv *priv = sys->private_data; | 230 | struct rcar_pci_priv *priv = sys->private_data; |
171 | void __iomem *reg = priv->reg; | 231 | void __iomem *reg = priv->reg; |
@@ -183,10 +243,31 @@ static int __init rcar_pci_setup(int nr, struct pci_sys_data *sys) | |||
183 | iowrite32(val, reg + RCAR_USBCTR_REG); | 243 | iowrite32(val, reg + RCAR_USBCTR_REG); |
184 | udelay(4); | 244 | udelay(4); |
185 | 245 | ||
186 | /* De-assert reset and set PCIAHB window1 size to 1GB */ | 246 | /* De-assert reset and reset PCIAHB window1 size */ |
187 | val &= ~(RCAR_USBCTR_PCIAHB_WIN1_MASK | RCAR_USBCTR_PCICLK_MASK | | 247 | val &= ~(RCAR_USBCTR_PCIAHB_WIN1_MASK | RCAR_USBCTR_PCICLK_MASK | |
188 | RCAR_USBCTR_USBH_RST | RCAR_USBCTR_PLL_RST); | 248 | RCAR_USBCTR_USBH_RST | RCAR_USBCTR_PLL_RST); |
189 | iowrite32(val | RCAR_USBCTR_PCIAHB_WIN1_1G, reg + RCAR_USBCTR_REG); | 249 | |
250 | /* Setup PCIAHB window1 size */ | ||
251 | switch (priv->window_size) { | ||
252 | case SZ_2G: | ||
253 | val |= RCAR_USBCTR_PCIAHB_WIN1_2G; | ||
254 | break; | ||
255 | case SZ_1G: | ||
256 | val |= RCAR_USBCTR_PCIAHB_WIN1_1G; | ||
257 | break; | ||
258 | case SZ_512M: | ||
259 | val |= RCAR_USBCTR_PCIAHB_WIN1_512M; | ||
260 | break; | ||
261 | default: | ||
262 | pr_warn("unknown window size %ld - defaulting to 256M\n", | ||
263 | priv->window_size); | ||
264 | priv->window_size = SZ_256M; | ||
265 | /* fall-through */ | ||
266 | case SZ_256M: | ||
267 | val |= RCAR_USBCTR_PCIAHB_WIN1_256M; | ||
268 | break; | ||
269 | } | ||
270 | iowrite32(val, reg + RCAR_USBCTR_REG); | ||
190 | 271 | ||
191 | /* Configure AHB master and slave modes */ | 272 | /* Configure AHB master and slave modes */ |
192 | iowrite32(RCAR_AHB_BUS_MODE, reg + RCAR_AHB_BUS_CTR_REG); | 273 | iowrite32(RCAR_AHB_BUS_MODE, reg + RCAR_AHB_BUS_CTR_REG); |
@@ -197,7 +278,7 @@ static int __init rcar_pci_setup(int nr, struct pci_sys_data *sys) | |||
197 | RCAR_PCI_ARBITER_PCIBP_MODE; | 278 | RCAR_PCI_ARBITER_PCIBP_MODE; |
198 | iowrite32(val, reg + RCAR_PCI_ARBITER_CTR_REG); | 279 | iowrite32(val, reg + RCAR_PCI_ARBITER_CTR_REG); |
199 | 280 | ||
200 | /* PCI-AHB mapping: 0x40000000-0x80000000 */ | 281 | /* PCI-AHB mapping: 0x40000000 base */ |
201 | iowrite32(0x40000000 | RCAR_PCIAHB_PREFETCH16, | 282 | iowrite32(0x40000000 | RCAR_PCIAHB_PREFETCH16, |
202 | reg + RCAR_PCIAHB_WIN1_CTR_REG); | 283 | reg + RCAR_PCIAHB_WIN1_CTR_REG); |
203 | 284 | ||
@@ -224,10 +305,15 @@ static int __init rcar_pci_setup(int nr, struct pci_sys_data *sys) | |||
224 | iowrite32(RCAR_PCI_INT_A | RCAR_PCI_INT_B | RCAR_PCI_INT_PME, | 305 | iowrite32(RCAR_PCI_INT_A | RCAR_PCI_INT_B | RCAR_PCI_INT_PME, |
225 | reg + RCAR_PCI_INT_ENABLE_REG); | 306 | reg + RCAR_PCI_INT_ENABLE_REG); |
226 | 307 | ||
308 | if (priv->irq > 0) | ||
309 | rcar_pci_setup_errirq(priv); | ||
310 | |||
227 | /* Add PCI resources */ | 311 | /* Add PCI resources */ |
228 | pci_add_resource(&sys->resources, &priv->io_res); | 312 | pci_add_resource(&sys->resources, &priv->io_res); |
229 | pci_add_resource(&sys->resources, &priv->mem_res); | 313 | pci_add_resource(&sys->resources, &priv->mem_res); |
230 | 314 | ||
315 | /* Setup bus number based on platform device id */ | ||
316 | sys->busnr = to_platform_device(priv->dev)->id; | ||
231 | return 1; | 317 | return 1; |
232 | } | 318 | } |
233 | 319 | ||
@@ -236,48 +322,13 @@ static struct pci_ops rcar_pci_ops = { | |||
236 | .write = rcar_pci_write_config, | 322 | .write = rcar_pci_write_config, |
237 | }; | 323 | }; |
238 | 324 | ||
239 | static struct hw_pci rcar_hw_pci __initdata = { | 325 | static int rcar_pci_probe(struct platform_device *pdev) |
240 | .map_irq = rcar_pci_map_irq, | ||
241 | .ops = &rcar_pci_ops, | ||
242 | .setup = rcar_pci_setup, | ||
243 | }; | ||
244 | |||
245 | static int rcar_pci_count __initdata; | ||
246 | |||
247 | static int __init rcar_pci_add_controller(struct rcar_pci_priv *priv) | ||
248 | { | ||
249 | void **private_data; | ||
250 | int count; | ||
251 | |||
252 | if (rcar_hw_pci.nr_controllers < rcar_pci_count) | ||
253 | goto add_priv; | ||
254 | |||
255 | /* (Re)allocate private data pointer array if needed */ | ||
256 | count = rcar_pci_count + RCAR_PCI_NR_CONTROLLERS; | ||
257 | private_data = kzalloc(count * sizeof(void *), GFP_KERNEL); | ||
258 | if (!private_data) | ||
259 | return -ENOMEM; | ||
260 | |||
261 | rcar_pci_count = count; | ||
262 | if (rcar_hw_pci.private_data) { | ||
263 | memcpy(private_data, rcar_hw_pci.private_data, | ||
264 | rcar_hw_pci.nr_controllers * sizeof(void *)); | ||
265 | kfree(rcar_hw_pci.private_data); | ||
266 | } | ||
267 | |||
268 | rcar_hw_pci.private_data = private_data; | ||
269 | |||
270 | add_priv: | ||
271 | /* Add private data pointer to the array */ | ||
272 | rcar_hw_pci.private_data[rcar_hw_pci.nr_controllers++] = priv; | ||
273 | return 0; | ||
274 | } | ||
275 | |||
276 | static int __init rcar_pci_probe(struct platform_device *pdev) | ||
277 | { | 326 | { |
278 | struct resource *cfg_res, *mem_res; | 327 | struct resource *cfg_res, *mem_res; |
279 | struct rcar_pci_priv *priv; | 328 | struct rcar_pci_priv *priv; |
280 | void __iomem *reg; | 329 | void __iomem *reg; |
330 | struct hw_pci hw; | ||
331 | void *hw_private[1]; | ||
281 | 332 | ||
282 | cfg_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 333 | cfg_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
283 | reg = devm_ioremap_resource(&pdev->dev, cfg_res); | 334 | reg = devm_ioremap_resource(&pdev->dev, cfg_res); |
@@ -308,31 +359,34 @@ static int __init rcar_pci_probe(struct platform_device *pdev) | |||
308 | priv->reg = reg; | 359 | priv->reg = reg; |
309 | priv->dev = &pdev->dev; | 360 | priv->dev = &pdev->dev; |
310 | 361 | ||
311 | return rcar_pci_add_controller(priv); | 362 | if (priv->irq < 0) { |
363 | dev_err(&pdev->dev, "no valid irq found\n"); | ||
364 | return priv->irq; | ||
365 | } | ||
366 | |||
367 | priv->window_size = SZ_1G; | ||
368 | |||
369 | hw_private[0] = priv; | ||
370 | memset(&hw, 0, sizeof(hw)); | ||
371 | hw.nr_controllers = ARRAY_SIZE(hw_private); | ||
372 | hw.private_data = hw_private; | ||
373 | hw.map_irq = rcar_pci_map_irq; | ||
374 | hw.ops = &rcar_pci_ops; | ||
375 | hw.setup = rcar_pci_setup; | ||
376 | pci_common_init_dev(&pdev->dev, &hw); | ||
377 | return 0; | ||
312 | } | 378 | } |
313 | 379 | ||
314 | static struct platform_driver rcar_pci_driver = { | 380 | static struct platform_driver rcar_pci_driver = { |
315 | .driver = { | 381 | .driver = { |
316 | .name = "pci-rcar-gen2", | 382 | .name = "pci-rcar-gen2", |
383 | .owner = THIS_MODULE, | ||
384 | .suppress_bind_attrs = true, | ||
317 | }, | 385 | }, |
386 | .probe = rcar_pci_probe, | ||
318 | }; | 387 | }; |
319 | 388 | ||
320 | static int __init rcar_pci_init(void) | 389 | module_platform_driver(rcar_pci_driver); |
321 | { | ||
322 | int retval; | ||
323 | |||
324 | retval = platform_driver_probe(&rcar_pci_driver, rcar_pci_probe); | ||
325 | if (!retval) | ||
326 | pci_common_init(&rcar_hw_pci); | ||
327 | |||
328 | /* Private data pointer array is not needed any more */ | ||
329 | kfree(rcar_hw_pci.private_data); | ||
330 | rcar_hw_pci.private_data = NULL; | ||
331 | |||
332 | return retval; | ||
333 | } | ||
334 | |||
335 | subsys_initcall(rcar_pci_init); | ||
336 | 390 | ||
337 | MODULE_LICENSE("GPL v2"); | 391 | MODULE_LICENSE("GPL v2"); |
338 | MODULE_DESCRIPTION("Renesas R-Car Gen2 internal PCI"); | 392 | MODULE_DESCRIPTION("Renesas R-Car Gen2 internal PCI"); |
diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c index 2e48ecf09e2c..509a29d84509 100644 --- a/drivers/pci/host/pcie-designware.c +++ b/drivers/pci/host/pcie-designware.c | |||
@@ -798,7 +798,7 @@ void dw_pcie_setup_rc(struct pcie_port *pp) | |||
798 | 798 | ||
799 | /* setup RC BARs */ | 799 | /* setup RC BARs */ |
800 | dw_pcie_writel_rc(pp, 0x00000004, PCI_BASE_ADDRESS_0); | 800 | dw_pcie_writel_rc(pp, 0x00000004, PCI_BASE_ADDRESS_0); |
801 | dw_pcie_writel_rc(pp, 0x00000004, PCI_BASE_ADDRESS_1); | 801 | dw_pcie_writel_rc(pp, 0x00000000, PCI_BASE_ADDRESS_1); |
802 | 802 | ||
803 | /* setup interrupt pins */ | 803 | /* setup interrupt pins */ |
804 | dw_pcie_readl_rc(pp, PCI_INTERRUPT_LINE, &val); | 804 | dw_pcie_readl_rc(pp, PCI_INTERRUPT_LINE, &val); |
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index 828acf422c17..bccc27ee1030 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c | |||
@@ -424,7 +424,7 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge) | |||
424 | */ | 424 | */ |
425 | static unsigned char acpiphp_max_busnr(struct pci_bus *bus) | 425 | static unsigned char acpiphp_max_busnr(struct pci_bus *bus) |
426 | { | 426 | { |
427 | struct list_head *tmp; | 427 | struct pci_bus *tmp; |
428 | unsigned char max, n; | 428 | unsigned char max, n; |
429 | 429 | ||
430 | /* | 430 | /* |
@@ -437,8 +437,8 @@ static unsigned char acpiphp_max_busnr(struct pci_bus *bus) | |||
437 | */ | 437 | */ |
438 | max = bus->busn_res.start; | 438 | max = bus->busn_res.start; |
439 | 439 | ||
440 | list_for_each(tmp, &bus->children) { | 440 | list_for_each_entry(tmp, &bus->children, node) { |
441 | n = pci_bus_max_busnr(pci_bus_b(tmp)); | 441 | n = pci_bus_max_busnr(tmp); |
442 | if (n > max) | 442 | if (n > max) |
443 | max = n; | 443 | max = n; |
444 | } | 444 | } |
diff --git a/drivers/pci/hotplug/cpqphp_core.c b/drivers/pci/hotplug/cpqphp_core.c index 31273e155e6c..037e2612c5bd 100644 --- a/drivers/pci/hotplug/cpqphp_core.c +++ b/drivers/pci/hotplug/cpqphp_core.c | |||
@@ -920,12 +920,12 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
920 | bus->max_bus_speed = PCI_SPEED_100MHz_PCIX; | 920 | bus->max_bus_speed = PCI_SPEED_100MHz_PCIX; |
921 | break; | 921 | break; |
922 | } | 922 | } |
923 | if (bus_cap & 20) { | 923 | if (bus_cap & 0x20) { |
924 | dbg("bus max supports 66MHz PCI-X\n"); | 924 | dbg("bus max supports 66MHz PCI-X\n"); |
925 | bus->max_bus_speed = PCI_SPEED_66MHz_PCIX; | 925 | bus->max_bus_speed = PCI_SPEED_66MHz_PCIX; |
926 | break; | 926 | break; |
927 | } | 927 | } |
928 | if (bus_cap & 10) { | 928 | if (bus_cap & 0x10) { |
929 | dbg("bus max supports 66MHz PCI\n"); | 929 | dbg("bus max supports 66MHz PCI\n"); |
930 | bus->max_bus_speed = PCI_SPEED_66MHz; | 930 | bus->max_bus_speed = PCI_SPEED_66MHz; |
931 | break; | 931 | break; |
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h index 88b37cad4b35..8a66866b8cf1 100644 --- a/drivers/pci/hotplug/pciehp.h +++ b/drivers/pci/hotplug/pciehp.h | |||
@@ -76,6 +76,7 @@ struct slot { | |||
76 | struct hotplug_slot *hotplug_slot; | 76 | struct hotplug_slot *hotplug_slot; |
77 | struct delayed_work work; /* work for button event */ | 77 | struct delayed_work work; /* work for button event */ |
78 | struct mutex lock; | 78 | struct mutex lock; |
79 | struct mutex hotplug_lock; | ||
79 | struct workqueue_struct *wq; | 80 | struct workqueue_struct *wq; |
80 | }; | 81 | }; |
81 | 82 | ||
@@ -109,6 +110,8 @@ struct controller { | |||
109 | #define INT_BUTTON_PRESS 7 | 110 | #define INT_BUTTON_PRESS 7 |
110 | #define INT_BUTTON_RELEASE 8 | 111 | #define INT_BUTTON_RELEASE 8 |
111 | #define INT_BUTTON_CANCEL 9 | 112 | #define INT_BUTTON_CANCEL 9 |
113 | #define INT_LINK_UP 10 | ||
114 | #define INT_LINK_DOWN 11 | ||
112 | 115 | ||
113 | #define STATIC_STATE 0 | 116 | #define STATIC_STATE 0 |
114 | #define BLINKINGON_STATE 1 | 117 | #define BLINKINGON_STATE 1 |
@@ -132,6 +135,7 @@ u8 pciehp_handle_attention_button(struct slot *p_slot); | |||
132 | u8 pciehp_handle_switch_change(struct slot *p_slot); | 135 | u8 pciehp_handle_switch_change(struct slot *p_slot); |
133 | u8 pciehp_handle_presence_change(struct slot *p_slot); | 136 | u8 pciehp_handle_presence_change(struct slot *p_slot); |
134 | u8 pciehp_handle_power_fault(struct slot *p_slot); | 137 | u8 pciehp_handle_power_fault(struct slot *p_slot); |
138 | void pciehp_handle_linkstate_change(struct slot *p_slot); | ||
135 | int pciehp_configure_device(struct slot *p_slot); | 139 | int pciehp_configure_device(struct slot *p_slot); |
136 | int pciehp_unconfigure_device(struct slot *p_slot); | 140 | int pciehp_unconfigure_device(struct slot *p_slot); |
137 | void pciehp_queue_pushbutton_work(struct work_struct *work); | 141 | void pciehp_queue_pushbutton_work(struct work_struct *work); |
@@ -153,6 +157,7 @@ void pciehp_green_led_on(struct slot *slot); | |||
153 | void pciehp_green_led_off(struct slot *slot); | 157 | void pciehp_green_led_off(struct slot *slot); |
154 | void pciehp_green_led_blink(struct slot *slot); | 158 | void pciehp_green_led_blink(struct slot *slot); |
155 | int pciehp_check_link_status(struct controller *ctrl); | 159 | int pciehp_check_link_status(struct controller *ctrl); |
160 | bool pciehp_check_link_active(struct controller *ctrl); | ||
156 | void pciehp_release_ctrl(struct controller *ctrl); | 161 | void pciehp_release_ctrl(struct controller *ctrl); |
157 | int pciehp_reset_slot(struct slot *slot, int probe); | 162 | int pciehp_reset_slot(struct slot *slot, int probe); |
158 | 163 | ||
diff --git a/drivers/pci/hotplug/pciehp_acpi.c b/drivers/pci/hotplug/pciehp_acpi.c index eddddd447d0d..20fea57d2149 100644 --- a/drivers/pci/hotplug/pciehp_acpi.c +++ b/drivers/pci/hotplug/pciehp_acpi.c | |||
@@ -112,6 +112,7 @@ static struct pcie_port_service_driver __initdata dummy_driver = { | |||
112 | static int __init select_detection_mode(void) | 112 | static int __init select_detection_mode(void) |
113 | { | 113 | { |
114 | struct dummy_slot *slot, *tmp; | 114 | struct dummy_slot *slot, *tmp; |
115 | |||
115 | if (pcie_port_service_register(&dummy_driver)) | 116 | if (pcie_port_service_register(&dummy_driver)) |
116 | return PCIEHP_DETECT_ACPI; | 117 | return PCIEHP_DETECT_ACPI; |
117 | pcie_port_service_unregister(&dummy_driver); | 118 | pcie_port_service_unregister(&dummy_driver); |
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c index 53b58debc288..0e0a2fff20a3 100644 --- a/drivers/pci/hotplug/pciehp_core.c +++ b/drivers/pci/hotplug/pciehp_core.c | |||
@@ -108,6 +108,7 @@ static int init_slot(struct controller *ctrl) | |||
108 | ops = kzalloc(sizeof(*ops), GFP_KERNEL); | 108 | ops = kzalloc(sizeof(*ops), GFP_KERNEL); |
109 | if (!ops) | 109 | if (!ops) |
110 | goto out; | 110 | goto out; |
111 | |||
111 | ops->enable_slot = enable_slot; | 112 | ops->enable_slot = enable_slot; |
112 | ops->disable_slot = disable_slot; | 113 | ops->disable_slot = disable_slot; |
113 | ops->get_power_status = get_power_status; | 114 | ops->get_power_status = get_power_status; |
@@ -283,8 +284,11 @@ static int pciehp_probe(struct pcie_device *dev) | |||
283 | slot = ctrl->slot; | 284 | slot = ctrl->slot; |
284 | pciehp_get_adapter_status(slot, &occupied); | 285 | pciehp_get_adapter_status(slot, &occupied); |
285 | pciehp_get_power_status(slot, &poweron); | 286 | pciehp_get_power_status(slot, &poweron); |
286 | if (occupied && pciehp_force) | 287 | if (occupied && pciehp_force) { |
288 | mutex_lock(&slot->hotplug_lock); | ||
287 | pciehp_enable_slot(slot); | 289 | pciehp_enable_slot(slot); |
290 | mutex_unlock(&slot->hotplug_lock); | ||
291 | } | ||
288 | /* If empty slot's power status is on, turn power off */ | 292 | /* If empty slot's power status is on, turn power off */ |
289 | if (!occupied && poweron && POWER_CTRL(ctrl)) | 293 | if (!occupied && poweron && POWER_CTRL(ctrl)) |
290 | pciehp_power_off_slot(slot); | 294 | pciehp_power_off_slot(slot); |
@@ -328,10 +332,12 @@ static int pciehp_resume (struct pcie_device *dev) | |||
328 | 332 | ||
329 | /* Check if slot is occupied */ | 333 | /* Check if slot is occupied */ |
330 | pciehp_get_adapter_status(slot, &status); | 334 | pciehp_get_adapter_status(slot, &status); |
335 | mutex_lock(&slot->hotplug_lock); | ||
331 | if (status) | 336 | if (status) |
332 | pciehp_enable_slot(slot); | 337 | pciehp_enable_slot(slot); |
333 | else | 338 | else |
334 | pciehp_disable_slot(slot); | 339 | pciehp_disable_slot(slot); |
340 | mutex_unlock(&slot->hotplug_lock); | ||
335 | return 0; | 341 | return 0; |
336 | } | 342 | } |
337 | #endif /* PM */ | 343 | #endif /* PM */ |
diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c index 50628487597d..c75e6a678dcc 100644 --- a/drivers/pci/hotplug/pciehp_ctrl.c +++ b/drivers/pci/hotplug/pciehp_ctrl.c | |||
@@ -150,6 +150,27 @@ u8 pciehp_handle_power_fault(struct slot *p_slot) | |||
150 | return 1; | 150 | return 1; |
151 | } | 151 | } |
152 | 152 | ||
153 | void pciehp_handle_linkstate_change(struct slot *p_slot) | ||
154 | { | ||
155 | u32 event_type; | ||
156 | struct controller *ctrl = p_slot->ctrl; | ||
157 | |||
158 | /* Link Status Change */ | ||
159 | ctrl_dbg(ctrl, "Data Link Layer State change\n"); | ||
160 | |||
161 | if (pciehp_check_link_active(ctrl)) { | ||
162 | ctrl_info(ctrl, "slot(%s): Link Up event\n", | ||
163 | slot_name(p_slot)); | ||
164 | event_type = INT_LINK_UP; | ||
165 | } else { | ||
166 | ctrl_info(ctrl, "slot(%s): Link Down event\n", | ||
167 | slot_name(p_slot)); | ||
168 | event_type = INT_LINK_DOWN; | ||
169 | } | ||
170 | |||
171 | queue_interrupt_event(p_slot, event_type); | ||
172 | } | ||
173 | |||
153 | /* The following routines constitute the bulk of the | 174 | /* The following routines constitute the bulk of the |
154 | hotplug controller logic | 175 | hotplug controller logic |
155 | */ | 176 | */ |
@@ -212,7 +233,8 @@ static int board_added(struct slot *p_slot) | |||
212 | if (retval) { | 233 | if (retval) { |
213 | ctrl_err(ctrl, "Cannot add device at %04x:%02x:00\n", | 234 | ctrl_err(ctrl, "Cannot add device at %04x:%02x:00\n", |
214 | pci_domain_nr(parent), parent->number); | 235 | pci_domain_nr(parent), parent->number); |
215 | goto err_exit; | 236 | if (retval != -EEXIST) |
237 | goto err_exit; | ||
216 | } | 238 | } |
217 | 239 | ||
218 | pciehp_green_led_on(p_slot); | 240 | pciehp_green_led_on(p_slot); |
@@ -255,6 +277,9 @@ static int remove_board(struct slot *p_slot) | |||
255 | struct power_work_info { | 277 | struct power_work_info { |
256 | struct slot *p_slot; | 278 | struct slot *p_slot; |
257 | struct work_struct work; | 279 | struct work_struct work; |
280 | unsigned int req; | ||
281 | #define DISABLE_REQ 0 | ||
282 | #define ENABLE_REQ 1 | ||
258 | }; | 283 | }; |
259 | 284 | ||
260 | /** | 285 | /** |
@@ -269,30 +294,38 @@ static void pciehp_power_thread(struct work_struct *work) | |||
269 | struct power_work_info *info = | 294 | struct power_work_info *info = |
270 | container_of(work, struct power_work_info, work); | 295 | container_of(work, struct power_work_info, work); |
271 | struct slot *p_slot = info->p_slot; | 296 | struct slot *p_slot = info->p_slot; |
297 | int ret; | ||
272 | 298 | ||
273 | mutex_lock(&p_slot->lock); | 299 | switch (info->req) { |
274 | switch (p_slot->state) { | 300 | case DISABLE_REQ: |
275 | case POWEROFF_STATE: | ||
276 | mutex_unlock(&p_slot->lock); | ||
277 | ctrl_dbg(p_slot->ctrl, | 301 | ctrl_dbg(p_slot->ctrl, |
278 | "Disabling domain:bus:device=%04x:%02x:00\n", | 302 | "Disabling domain:bus:device=%04x:%02x:00\n", |
279 | pci_domain_nr(p_slot->ctrl->pcie->port->subordinate), | 303 | pci_domain_nr(p_slot->ctrl->pcie->port->subordinate), |
280 | p_slot->ctrl->pcie->port->subordinate->number); | 304 | p_slot->ctrl->pcie->port->subordinate->number); |
305 | mutex_lock(&p_slot->hotplug_lock); | ||
281 | pciehp_disable_slot(p_slot); | 306 | pciehp_disable_slot(p_slot); |
307 | mutex_unlock(&p_slot->hotplug_lock); | ||
282 | mutex_lock(&p_slot->lock); | 308 | mutex_lock(&p_slot->lock); |
283 | p_slot->state = STATIC_STATE; | 309 | p_slot->state = STATIC_STATE; |
284 | break; | ||
285 | case POWERON_STATE: | ||
286 | mutex_unlock(&p_slot->lock); | 310 | mutex_unlock(&p_slot->lock); |
287 | if (pciehp_enable_slot(p_slot)) | 311 | break; |
312 | case ENABLE_REQ: | ||
313 | ctrl_dbg(p_slot->ctrl, | ||
314 | "Enabling domain:bus:device=%04x:%02x:00\n", | ||
315 | pci_domain_nr(p_slot->ctrl->pcie->port->subordinate), | ||
316 | p_slot->ctrl->pcie->port->subordinate->number); | ||
317 | mutex_lock(&p_slot->hotplug_lock); | ||
318 | ret = pciehp_enable_slot(p_slot); | ||
319 | mutex_unlock(&p_slot->hotplug_lock); | ||
320 | if (ret) | ||
288 | pciehp_green_led_off(p_slot); | 321 | pciehp_green_led_off(p_slot); |
289 | mutex_lock(&p_slot->lock); | 322 | mutex_lock(&p_slot->lock); |
290 | p_slot->state = STATIC_STATE; | 323 | p_slot->state = STATIC_STATE; |
324 | mutex_unlock(&p_slot->lock); | ||
291 | break; | 325 | break; |
292 | default: | 326 | default: |
293 | break; | 327 | break; |
294 | } | 328 | } |
295 | mutex_unlock(&p_slot->lock); | ||
296 | 329 | ||
297 | kfree(info); | 330 | kfree(info); |
298 | } | 331 | } |
@@ -315,9 +348,11 @@ void pciehp_queue_pushbutton_work(struct work_struct *work) | |||
315 | switch (p_slot->state) { | 348 | switch (p_slot->state) { |
316 | case BLINKINGOFF_STATE: | 349 | case BLINKINGOFF_STATE: |
317 | p_slot->state = POWEROFF_STATE; | 350 | p_slot->state = POWEROFF_STATE; |
351 | info->req = DISABLE_REQ; | ||
318 | break; | 352 | break; |
319 | case BLINKINGON_STATE: | 353 | case BLINKINGON_STATE: |
320 | p_slot->state = POWERON_STATE; | 354 | p_slot->state = POWERON_STATE; |
355 | info->req = ENABLE_REQ; | ||
321 | break; | 356 | break; |
322 | default: | 357 | default: |
323 | kfree(info); | 358 | kfree(info); |
@@ -364,11 +399,10 @@ static void handle_button_press_event(struct slot *p_slot) | |||
364 | */ | 399 | */ |
365 | ctrl_info(ctrl, "Button cancel on Slot(%s)\n", slot_name(p_slot)); | 400 | ctrl_info(ctrl, "Button cancel on Slot(%s)\n", slot_name(p_slot)); |
366 | cancel_delayed_work(&p_slot->work); | 401 | cancel_delayed_work(&p_slot->work); |
367 | if (p_slot->state == BLINKINGOFF_STATE) { | 402 | if (p_slot->state == BLINKINGOFF_STATE) |
368 | pciehp_green_led_on(p_slot); | 403 | pciehp_green_led_on(p_slot); |
369 | } else { | 404 | else |
370 | pciehp_green_led_off(p_slot); | 405 | pciehp_green_led_off(p_slot); |
371 | } | ||
372 | pciehp_set_attention_status(p_slot, 0); | 406 | pciehp_set_attention_status(p_slot, 0); |
373 | ctrl_info(ctrl, "PCI slot #%s - action canceled " | 407 | ctrl_info(ctrl, "PCI slot #%s - action canceled " |
374 | "due to button press\n", slot_name(p_slot)); | 408 | "due to button press\n", slot_name(p_slot)); |
@@ -407,14 +441,81 @@ static void handle_surprise_event(struct slot *p_slot) | |||
407 | INIT_WORK(&info->work, pciehp_power_thread); | 441 | INIT_WORK(&info->work, pciehp_power_thread); |
408 | 442 | ||
409 | pciehp_get_adapter_status(p_slot, &getstatus); | 443 | pciehp_get_adapter_status(p_slot, &getstatus); |
410 | if (!getstatus) | 444 | if (!getstatus) { |
411 | p_slot->state = POWEROFF_STATE; | 445 | p_slot->state = POWEROFF_STATE; |
412 | else | 446 | info->req = DISABLE_REQ; |
447 | } else { | ||
413 | p_slot->state = POWERON_STATE; | 448 | p_slot->state = POWERON_STATE; |
449 | info->req = ENABLE_REQ; | ||
450 | } | ||
414 | 451 | ||
415 | queue_work(p_slot->wq, &info->work); | 452 | queue_work(p_slot->wq, &info->work); |
416 | } | 453 | } |
417 | 454 | ||
455 | /* | ||
456 | * Note: This function must be called with slot->lock held | ||
457 | */ | ||
458 | static void handle_link_event(struct slot *p_slot, u32 event) | ||
459 | { | ||
460 | struct controller *ctrl = p_slot->ctrl; | ||
461 | struct power_work_info *info; | ||
462 | |||
463 | info = kmalloc(sizeof(*info), GFP_KERNEL); | ||
464 | if (!info) { | ||
465 | ctrl_err(p_slot->ctrl, "%s: Cannot allocate memory\n", | ||
466 | __func__); | ||
467 | return; | ||
468 | } | ||
469 | info->p_slot = p_slot; | ||
470 | info->req = event == INT_LINK_UP ? ENABLE_REQ : DISABLE_REQ; | ||
471 | INIT_WORK(&info->work, pciehp_power_thread); | ||
472 | |||
473 | switch (p_slot->state) { | ||
474 | case BLINKINGON_STATE: | ||
475 | case BLINKINGOFF_STATE: | ||
476 | cancel_delayed_work(&p_slot->work); | ||
477 | /* Fall through */ | ||
478 | case STATIC_STATE: | ||
479 | p_slot->state = event == INT_LINK_UP ? | ||
480 | POWERON_STATE : POWEROFF_STATE; | ||
481 | queue_work(p_slot->wq, &info->work); | ||
482 | break; | ||
483 | case POWERON_STATE: | ||
484 | if (event == INT_LINK_UP) { | ||
485 | ctrl_info(ctrl, | ||
486 | "Link Up event ignored on slot(%s): already powering on\n", | ||
487 | slot_name(p_slot)); | ||
488 | kfree(info); | ||
489 | } else { | ||
490 | ctrl_info(ctrl, | ||
491 | "Link Down event queued on slot(%s): currently getting powered on\n", | ||
492 | slot_name(p_slot)); | ||
493 | p_slot->state = POWEROFF_STATE; | ||
494 | queue_work(p_slot->wq, &info->work); | ||
495 | } | ||
496 | break; | ||
497 | case POWEROFF_STATE: | ||
498 | if (event == INT_LINK_UP) { | ||
499 | ctrl_info(ctrl, | ||
500 | "Link Up event queued on slot(%s): currently getting powered off\n", | ||
501 | slot_name(p_slot)); | ||
502 | p_slot->state = POWERON_STATE; | ||
503 | queue_work(p_slot->wq, &info->work); | ||
504 | } else { | ||
505 | ctrl_info(ctrl, | ||
506 | "Link Down event ignored on slot(%s): already powering off\n", | ||
507 | slot_name(p_slot)); | ||
508 | kfree(info); | ||
509 | } | ||
510 | break; | ||
511 | default: | ||
512 | ctrl_err(ctrl, "Not a valid state on slot(%s)\n", | ||
513 | slot_name(p_slot)); | ||
514 | kfree(info); | ||
515 | break; | ||
516 | } | ||
517 | } | ||
518 | |||
418 | static void interrupt_event_handler(struct work_struct *work) | 519 | static void interrupt_event_handler(struct work_struct *work) |
419 | { | 520 | { |
420 | struct event_info *info = container_of(work, struct event_info, work); | 521 | struct event_info *info = container_of(work, struct event_info, work); |
@@ -433,12 +534,23 @@ static void interrupt_event_handler(struct work_struct *work) | |||
433 | pciehp_green_led_off(p_slot); | 534 | pciehp_green_led_off(p_slot); |
434 | break; | 535 | break; |
435 | case INT_PRESENCE_ON: | 536 | case INT_PRESENCE_ON: |
436 | case INT_PRESENCE_OFF: | ||
437 | if (!HP_SUPR_RM(ctrl)) | 537 | if (!HP_SUPR_RM(ctrl)) |
438 | break; | 538 | break; |
539 | ctrl_dbg(ctrl, "Surprise Insertion\n"); | ||
540 | handle_surprise_event(p_slot); | ||
541 | break; | ||
542 | case INT_PRESENCE_OFF: | ||
543 | /* | ||
544 | * Regardless of surprise capability, we need to | ||
545 | * definitely remove a card that has been pulled out! | ||
546 | */ | ||
439 | ctrl_dbg(ctrl, "Surprise Removal\n"); | 547 | ctrl_dbg(ctrl, "Surprise Removal\n"); |
440 | handle_surprise_event(p_slot); | 548 | handle_surprise_event(p_slot); |
441 | break; | 549 | break; |
550 | case INT_LINK_UP: | ||
551 | case INT_LINK_DOWN: | ||
552 | handle_link_event(p_slot, info->event_type); | ||
553 | break; | ||
442 | default: | 554 | default: |
443 | break; | 555 | break; |
444 | } | 556 | } |
@@ -447,6 +559,9 @@ static void interrupt_event_handler(struct work_struct *work) | |||
447 | kfree(info); | 559 | kfree(info); |
448 | } | 560 | } |
449 | 561 | ||
562 | /* | ||
563 | * Note: This function must be called with slot->hotplug_lock held | ||
564 | */ | ||
450 | int pciehp_enable_slot(struct slot *p_slot) | 565 | int pciehp_enable_slot(struct slot *p_slot) |
451 | { | 566 | { |
452 | u8 getstatus = 0; | 567 | u8 getstatus = 0; |
@@ -479,13 +594,15 @@ int pciehp_enable_slot(struct slot *p_slot) | |||
479 | pciehp_get_latch_status(p_slot, &getstatus); | 594 | pciehp_get_latch_status(p_slot, &getstatus); |
480 | 595 | ||
481 | rc = board_added(p_slot); | 596 | rc = board_added(p_slot); |
482 | if (rc) { | 597 | if (rc) |
483 | pciehp_get_latch_status(p_slot, &getstatus); | 598 | pciehp_get_latch_status(p_slot, &getstatus); |
484 | } | 599 | |
485 | return rc; | 600 | return rc; |
486 | } | 601 | } |
487 | 602 | ||
488 | 603 | /* | |
604 | * Note: This function must be called with slot->hotplug_lock held | ||
605 | */ | ||
489 | int pciehp_disable_slot(struct slot *p_slot) | 606 | int pciehp_disable_slot(struct slot *p_slot) |
490 | { | 607 | { |
491 | u8 getstatus = 0; | 608 | u8 getstatus = 0; |
@@ -494,24 +611,6 @@ int pciehp_disable_slot(struct slot *p_slot) | |||
494 | if (!p_slot->ctrl) | 611 | if (!p_slot->ctrl) |
495 | return 1; | 612 | return 1; |
496 | 613 | ||
497 | if (!HP_SUPR_RM(p_slot->ctrl)) { | ||
498 | pciehp_get_adapter_status(p_slot, &getstatus); | ||
499 | if (!getstatus) { | ||
500 | ctrl_info(ctrl, "No adapter on slot(%s)\n", | ||
501 | slot_name(p_slot)); | ||
502 | return -ENODEV; | ||
503 | } | ||
504 | } | ||
505 | |||
506 | if (MRL_SENS(p_slot->ctrl)) { | ||
507 | pciehp_get_latch_status(p_slot, &getstatus); | ||
508 | if (getstatus) { | ||
509 | ctrl_info(ctrl, "Latch open on slot(%s)\n", | ||
510 | slot_name(p_slot)); | ||
511 | return -ENODEV; | ||
512 | } | ||
513 | } | ||
514 | |||
515 | if (POWER_CTRL(p_slot->ctrl)) { | 614 | if (POWER_CTRL(p_slot->ctrl)) { |
516 | pciehp_get_power_status(p_slot, &getstatus); | 615 | pciehp_get_power_status(p_slot, &getstatus); |
517 | if (!getstatus) { | 616 | if (!getstatus) { |
@@ -536,7 +635,9 @@ int pciehp_sysfs_enable_slot(struct slot *p_slot) | |||
536 | case STATIC_STATE: | 635 | case STATIC_STATE: |
537 | p_slot->state = POWERON_STATE; | 636 | p_slot->state = POWERON_STATE; |
538 | mutex_unlock(&p_slot->lock); | 637 | mutex_unlock(&p_slot->lock); |
638 | mutex_lock(&p_slot->hotplug_lock); | ||
539 | retval = pciehp_enable_slot(p_slot); | 639 | retval = pciehp_enable_slot(p_slot); |
640 | mutex_unlock(&p_slot->hotplug_lock); | ||
540 | mutex_lock(&p_slot->lock); | 641 | mutex_lock(&p_slot->lock); |
541 | p_slot->state = STATIC_STATE; | 642 | p_slot->state = STATIC_STATE; |
542 | break; | 643 | break; |
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index 14acfccb7670..d7d058fa19a4 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c | |||
@@ -206,7 +206,7 @@ static void pcie_write_cmd(struct controller *ctrl, u16 cmd, u16 mask) | |||
206 | mutex_unlock(&ctrl->ctrl_lock); | 206 | mutex_unlock(&ctrl->ctrl_lock); |
207 | } | 207 | } |
208 | 208 | ||
209 | static bool check_link_active(struct controller *ctrl) | 209 | bool pciehp_check_link_active(struct controller *ctrl) |
210 | { | 210 | { |
211 | struct pci_dev *pdev = ctrl_dev(ctrl); | 211 | struct pci_dev *pdev = ctrl_dev(ctrl); |
212 | u16 lnk_status; | 212 | u16 lnk_status; |
@@ -225,12 +225,12 @@ static void __pcie_wait_link_active(struct controller *ctrl, bool active) | |||
225 | { | 225 | { |
226 | int timeout = 1000; | 226 | int timeout = 1000; |
227 | 227 | ||
228 | if (check_link_active(ctrl) == active) | 228 | if (pciehp_check_link_active(ctrl) == active) |
229 | return; | 229 | return; |
230 | while (timeout > 0) { | 230 | while (timeout > 0) { |
231 | msleep(10); | 231 | msleep(10); |
232 | timeout -= 10; | 232 | timeout -= 10; |
233 | if (check_link_active(ctrl) == active) | 233 | if (pciehp_check_link_active(ctrl) == active) |
234 | return; | 234 | return; |
235 | } | 235 | } |
236 | ctrl_dbg(ctrl, "Data Link Layer Link Active not %s in 1000 msec\n", | 236 | ctrl_dbg(ctrl, "Data Link Layer Link Active not %s in 1000 msec\n", |
@@ -242,11 +242,6 @@ static void pcie_wait_link_active(struct controller *ctrl) | |||
242 | __pcie_wait_link_active(ctrl, true); | 242 | __pcie_wait_link_active(ctrl, true); |
243 | } | 243 | } |
244 | 244 | ||
245 | static void pcie_wait_link_not_active(struct controller *ctrl) | ||
246 | { | ||
247 | __pcie_wait_link_active(ctrl, false); | ||
248 | } | ||
249 | |||
250 | static bool pci_bus_check_dev(struct pci_bus *bus, int devfn) | 245 | static bool pci_bus_check_dev(struct pci_bus *bus, int devfn) |
251 | { | 246 | { |
252 | u32 l; | 247 | u32 l; |
@@ -332,11 +327,6 @@ static int pciehp_link_enable(struct controller *ctrl) | |||
332 | return __pciehp_link_set(ctrl, true); | 327 | return __pciehp_link_set(ctrl, true); |
333 | } | 328 | } |
334 | 329 | ||
335 | static int pciehp_link_disable(struct controller *ctrl) | ||
336 | { | ||
337 | return __pciehp_link_set(ctrl, false); | ||
338 | } | ||
339 | |||
340 | void pciehp_get_attention_status(struct slot *slot, u8 *status) | 330 | void pciehp_get_attention_status(struct slot *slot, u8 *status) |
341 | { | 331 | { |
342 | struct controller *ctrl = slot->ctrl; | 332 | struct controller *ctrl = slot->ctrl; |
@@ -508,14 +498,6 @@ void pciehp_power_off_slot(struct slot * slot) | |||
508 | { | 498 | { |
509 | struct controller *ctrl = slot->ctrl; | 499 | struct controller *ctrl = slot->ctrl; |
510 | 500 | ||
511 | /* Disable the link at first */ | ||
512 | pciehp_link_disable(ctrl); | ||
513 | /* wait the link is down */ | ||
514 | if (ctrl->link_active_reporting) | ||
515 | pcie_wait_link_not_active(ctrl); | ||
516 | else | ||
517 | msleep(1000); | ||
518 | |||
519 | pcie_write_cmd(ctrl, PCI_EXP_SLTCTL_PWR_OFF, PCI_EXP_SLTCTL_PCC); | 501 | pcie_write_cmd(ctrl, PCI_EXP_SLTCTL_PWR_OFF, PCI_EXP_SLTCTL_PCC); |
520 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, | 502 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, |
521 | pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, | 503 | pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, |
@@ -540,7 +522,7 @@ static irqreturn_t pcie_isr(int irq, void *dev_id) | |||
540 | 522 | ||
541 | detected &= (PCI_EXP_SLTSTA_ABP | PCI_EXP_SLTSTA_PFD | | 523 | detected &= (PCI_EXP_SLTSTA_ABP | PCI_EXP_SLTSTA_PFD | |
542 | PCI_EXP_SLTSTA_MRLSC | PCI_EXP_SLTSTA_PDC | | 524 | PCI_EXP_SLTSTA_MRLSC | PCI_EXP_SLTSTA_PDC | |
543 | PCI_EXP_SLTSTA_CC); | 525 | PCI_EXP_SLTSTA_CC | PCI_EXP_SLTSTA_DLLSC); |
544 | detected &= ~intr_loc; | 526 | detected &= ~intr_loc; |
545 | intr_loc |= detected; | 527 | intr_loc |= detected; |
546 | if (!intr_loc) | 528 | if (!intr_loc) |
@@ -579,6 +561,10 @@ static irqreturn_t pcie_isr(int irq, void *dev_id) | |||
579 | ctrl->power_fault_detected = 1; | 561 | ctrl->power_fault_detected = 1; |
580 | pciehp_handle_power_fault(slot); | 562 | pciehp_handle_power_fault(slot); |
581 | } | 563 | } |
564 | |||
565 | if (intr_loc & PCI_EXP_SLTSTA_DLLSC) | ||
566 | pciehp_handle_linkstate_change(slot); | ||
567 | |||
582 | return IRQ_HANDLED; | 568 | return IRQ_HANDLED; |
583 | } | 569 | } |
584 | 570 | ||
@@ -596,9 +582,17 @@ void pcie_enable_notification(struct controller *ctrl) | |||
596 | * when it is cleared in the interrupt service routine, and | 582 | * when it is cleared in the interrupt service routine, and |
597 | * next power fault detected interrupt was notified again. | 583 | * next power fault detected interrupt was notified again. |
598 | */ | 584 | */ |
599 | cmd = PCI_EXP_SLTCTL_PDCE; | 585 | |
586 | /* | ||
587 | * Always enable link events: thus link-up and link-down shall | ||
588 | * always be treated as hotplug and unplug respectively. Enable | ||
589 | * presence detect only if Attention Button is not present. | ||
590 | */ | ||
591 | cmd = PCI_EXP_SLTCTL_DLLSCE; | ||
600 | if (ATTN_BUTTN(ctrl)) | 592 | if (ATTN_BUTTN(ctrl)) |
601 | cmd |= PCI_EXP_SLTCTL_ABPE; | 593 | cmd |= PCI_EXP_SLTCTL_ABPE; |
594 | else | ||
595 | cmd |= PCI_EXP_SLTCTL_PDCE; | ||
602 | if (MRL_SENS(ctrl)) | 596 | if (MRL_SENS(ctrl)) |
603 | cmd |= PCI_EXP_SLTCTL_MRLSCE; | 597 | cmd |= PCI_EXP_SLTCTL_MRLSCE; |
604 | if (!pciehp_poll_mode) | 598 | if (!pciehp_poll_mode) |
@@ -606,7 +600,8 @@ void pcie_enable_notification(struct controller *ctrl) | |||
606 | 600 | ||
607 | mask = (PCI_EXP_SLTCTL_PDCE | PCI_EXP_SLTCTL_ABPE | | 601 | mask = (PCI_EXP_SLTCTL_PDCE | PCI_EXP_SLTCTL_ABPE | |
608 | PCI_EXP_SLTCTL_MRLSCE | PCI_EXP_SLTCTL_PFDE | | 602 | PCI_EXP_SLTCTL_MRLSCE | PCI_EXP_SLTCTL_PFDE | |
609 | PCI_EXP_SLTCTL_HPIE | PCI_EXP_SLTCTL_CCIE); | 603 | PCI_EXP_SLTCTL_HPIE | PCI_EXP_SLTCTL_CCIE | |
604 | PCI_EXP_SLTCTL_DLLSCE); | ||
610 | 605 | ||
611 | pcie_write_cmd(ctrl, cmd, mask); | 606 | pcie_write_cmd(ctrl, cmd, mask); |
612 | } | 607 | } |
@@ -624,33 +619,38 @@ static void pcie_disable_notification(struct controller *ctrl) | |||
624 | 619 | ||
625 | /* | 620 | /* |
626 | * pciehp has a 1:1 bus:slot relationship so we ultimately want a secondary | 621 | * pciehp has a 1:1 bus:slot relationship so we ultimately want a secondary |
627 | * bus reset of the bridge, but if the slot supports surprise removal we need | 622 | * bus reset of the bridge, but at the same time we want to ensure that it is |
628 | * to disable presence detection around the bus reset and clear any spurious | 623 | * not seen as a hot-unplug, followed by the hot-plug of the device. Thus, |
624 | * disable link state notification and presence detection change notification | ||
625 | * momentarily, if we see that they could interfere. Also, clear any spurious | ||
629 | * events after. | 626 | * events after. |
630 | */ | 627 | */ |
631 | int pciehp_reset_slot(struct slot *slot, int probe) | 628 | int pciehp_reset_slot(struct slot *slot, int probe) |
632 | { | 629 | { |
633 | struct controller *ctrl = slot->ctrl; | 630 | struct controller *ctrl = slot->ctrl; |
634 | struct pci_dev *pdev = ctrl_dev(ctrl); | 631 | struct pci_dev *pdev = ctrl_dev(ctrl); |
632 | u16 stat_mask = 0, ctrl_mask = 0; | ||
635 | 633 | ||
636 | if (probe) | 634 | if (probe) |
637 | return 0; | 635 | return 0; |
638 | 636 | ||
639 | if (HP_SUPR_RM(ctrl)) { | 637 | if (!ATTN_BUTTN(ctrl)) { |
640 | pcie_write_cmd(ctrl, 0, PCI_EXP_SLTCTL_PDCE); | 638 | ctrl_mask |= PCI_EXP_SLTCTL_PDCE; |
641 | if (pciehp_poll_mode) | 639 | stat_mask |= PCI_EXP_SLTSTA_PDC; |
642 | del_timer_sync(&ctrl->poll_timer); | ||
643 | } | 640 | } |
641 | ctrl_mask |= PCI_EXP_SLTCTL_DLLSCE; | ||
642 | stat_mask |= PCI_EXP_SLTSTA_DLLSC; | ||
643 | |||
644 | pcie_write_cmd(ctrl, 0, ctrl_mask); | ||
645 | if (pciehp_poll_mode) | ||
646 | del_timer_sync(&ctrl->poll_timer); | ||
644 | 647 | ||
645 | pci_reset_bridge_secondary_bus(ctrl->pcie->port); | 648 | pci_reset_bridge_secondary_bus(ctrl->pcie->port); |
646 | 649 | ||
647 | if (HP_SUPR_RM(ctrl)) { | 650 | pcie_capability_write_word(pdev, PCI_EXP_SLTSTA, stat_mask); |
648 | pcie_capability_write_word(pdev, PCI_EXP_SLTSTA, | 651 | pcie_write_cmd(ctrl, ctrl_mask, ctrl_mask); |
649 | PCI_EXP_SLTSTA_PDC); | 652 | if (pciehp_poll_mode) |
650 | pcie_write_cmd(ctrl, PCI_EXP_SLTCTL_PDCE, PCI_EXP_SLTCTL_PDCE); | 653 | int_poll_timeout(ctrl->poll_timer.data); |
651 | if (pciehp_poll_mode) | ||
652 | int_poll_timeout(ctrl->poll_timer.data); | ||
653 | } | ||
654 | 654 | ||
655 | return 0; | 655 | return 0; |
656 | } | 656 | } |
@@ -687,6 +687,7 @@ static int pcie_init_slot(struct controller *ctrl) | |||
687 | 687 | ||
688 | slot->ctrl = ctrl; | 688 | slot->ctrl = ctrl; |
689 | mutex_init(&slot->lock); | 689 | mutex_init(&slot->lock); |
690 | mutex_init(&slot->hotplug_lock); | ||
690 | INIT_DELAYED_WORK(&slot->work, pciehp_queue_pushbutton_work); | 691 | INIT_DELAYED_WORK(&slot->work, pciehp_queue_pushbutton_work); |
691 | ctrl->slot = slot; | 692 | ctrl->slot = slot; |
692 | return 0; | 693 | return 0; |
diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c index b07d7cc2d697..1b533060ce65 100644 --- a/drivers/pci/hotplug/pciehp_pci.c +++ b/drivers/pci/hotplug/pciehp_pci.c | |||
@@ -50,7 +50,7 @@ int pciehp_configure_device(struct slot *p_slot) | |||
50 | "at %04x:%02x:00, cannot hot-add\n", pci_name(dev), | 50 | "at %04x:%02x:00, cannot hot-add\n", pci_name(dev), |
51 | pci_domain_nr(parent), parent->number); | 51 | pci_domain_nr(parent), parent->number); |
52 | pci_dev_put(dev); | 52 | pci_dev_put(dev); |
53 | ret = -EINVAL; | 53 | ret = -EEXIST; |
54 | goto out; | 54 | goto out; |
55 | } | 55 | } |
56 | 56 | ||
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c index 9dce7c5e2a77..de7a74782f92 100644 --- a/drivers/pci/iov.c +++ b/drivers/pci/iov.c | |||
@@ -170,97 +170,6 @@ static void virtfn_remove(struct pci_dev *dev, int id, int reset) | |||
170 | pci_dev_put(dev); | 170 | pci_dev_put(dev); |
171 | } | 171 | } |
172 | 172 | ||
173 | static int sriov_migration(struct pci_dev *dev) | ||
174 | { | ||
175 | u16 status; | ||
176 | struct pci_sriov *iov = dev->sriov; | ||
177 | |||
178 | if (!iov->num_VFs) | ||
179 | return 0; | ||
180 | |||
181 | if (!(iov->cap & PCI_SRIOV_CAP_VFM)) | ||
182 | return 0; | ||
183 | |||
184 | pci_read_config_word(dev, iov->pos + PCI_SRIOV_STATUS, &status); | ||
185 | if (!(status & PCI_SRIOV_STATUS_VFM)) | ||
186 | return 0; | ||
187 | |||
188 | schedule_work(&iov->mtask); | ||
189 | |||
190 | return 1; | ||
191 | } | ||
192 | |||
193 | static void sriov_migration_task(struct work_struct *work) | ||
194 | { | ||
195 | int i; | ||
196 | u8 state; | ||
197 | u16 status; | ||
198 | struct pci_sriov *iov = container_of(work, struct pci_sriov, mtask); | ||
199 | |||
200 | for (i = iov->initial_VFs; i < iov->num_VFs; i++) { | ||
201 | state = readb(iov->mstate + i); | ||
202 | if (state == PCI_SRIOV_VFM_MI) { | ||
203 | writeb(PCI_SRIOV_VFM_AV, iov->mstate + i); | ||
204 | state = readb(iov->mstate + i); | ||
205 | if (state == PCI_SRIOV_VFM_AV) | ||
206 | virtfn_add(iov->self, i, 1); | ||
207 | } else if (state == PCI_SRIOV_VFM_MO) { | ||
208 | virtfn_remove(iov->self, i, 1); | ||
209 | writeb(PCI_SRIOV_VFM_UA, iov->mstate + i); | ||
210 | state = readb(iov->mstate + i); | ||
211 | if (state == PCI_SRIOV_VFM_AV) | ||
212 | virtfn_add(iov->self, i, 0); | ||
213 | } | ||
214 | } | ||
215 | |||
216 | pci_read_config_word(iov->self, iov->pos + PCI_SRIOV_STATUS, &status); | ||
217 | status &= ~PCI_SRIOV_STATUS_VFM; | ||
218 | pci_write_config_word(iov->self, iov->pos + PCI_SRIOV_STATUS, status); | ||
219 | } | ||
220 | |||
221 | static int sriov_enable_migration(struct pci_dev *dev, int nr_virtfn) | ||
222 | { | ||
223 | int bir; | ||
224 | u32 table; | ||
225 | resource_size_t pa; | ||
226 | struct pci_sriov *iov = dev->sriov; | ||
227 | |||
228 | if (nr_virtfn <= iov->initial_VFs) | ||
229 | return 0; | ||
230 | |||
231 | pci_read_config_dword(dev, iov->pos + PCI_SRIOV_VFM, &table); | ||
232 | bir = PCI_SRIOV_VFM_BIR(table); | ||
233 | if (bir > PCI_STD_RESOURCE_END) | ||
234 | return -EIO; | ||
235 | |||
236 | table = PCI_SRIOV_VFM_OFFSET(table); | ||
237 | if (table + nr_virtfn > pci_resource_len(dev, bir)) | ||
238 | return -EIO; | ||
239 | |||
240 | pa = pci_resource_start(dev, bir) + table; | ||
241 | iov->mstate = ioremap(pa, nr_virtfn); | ||
242 | if (!iov->mstate) | ||
243 | return -ENOMEM; | ||
244 | |||
245 | INIT_WORK(&iov->mtask, sriov_migration_task); | ||
246 | |||
247 | iov->ctrl |= PCI_SRIOV_CTRL_VFM | PCI_SRIOV_CTRL_INTR; | ||
248 | pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl); | ||
249 | |||
250 | return 0; | ||
251 | } | ||
252 | |||
253 | static void sriov_disable_migration(struct pci_dev *dev) | ||
254 | { | ||
255 | struct pci_sriov *iov = dev->sriov; | ||
256 | |||
257 | iov->ctrl &= ~(PCI_SRIOV_CTRL_VFM | PCI_SRIOV_CTRL_INTR); | ||
258 | pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl); | ||
259 | |||
260 | cancel_work_sync(&iov->mtask); | ||
261 | iounmap(iov->mstate); | ||
262 | } | ||
263 | |||
264 | static int sriov_enable(struct pci_dev *dev, int nr_virtfn) | 173 | static int sriov_enable(struct pci_dev *dev, int nr_virtfn) |
265 | { | 174 | { |
266 | int rc; | 175 | int rc; |
@@ -351,12 +260,6 @@ static int sriov_enable(struct pci_dev *dev, int nr_virtfn) | |||
351 | goto failed; | 260 | goto failed; |
352 | } | 261 | } |
353 | 262 | ||
354 | if (iov->cap & PCI_SRIOV_CAP_VFM) { | ||
355 | rc = sriov_enable_migration(dev, nr_virtfn); | ||
356 | if (rc) | ||
357 | goto failed; | ||
358 | } | ||
359 | |||
360 | kobject_uevent(&dev->dev.kobj, KOBJ_CHANGE); | 263 | kobject_uevent(&dev->dev.kobj, KOBJ_CHANGE); |
361 | iov->num_VFs = nr_virtfn; | 264 | iov->num_VFs = nr_virtfn; |
362 | 265 | ||
@@ -387,9 +290,6 @@ static void sriov_disable(struct pci_dev *dev) | |||
387 | if (!iov->num_VFs) | 290 | if (!iov->num_VFs) |
388 | return; | 291 | return; |
389 | 292 | ||
390 | if (iov->cap & PCI_SRIOV_CAP_VFM) | ||
391 | sriov_disable_migration(dev); | ||
392 | |||
393 | for (i = 0; i < iov->num_VFs; i++) | 293 | for (i = 0; i < iov->num_VFs; i++) |
394 | virtfn_remove(dev, i, 0); | 294 | virtfn_remove(dev, i, 0); |
395 | 295 | ||
@@ -688,25 +588,6 @@ void pci_disable_sriov(struct pci_dev *dev) | |||
688 | EXPORT_SYMBOL_GPL(pci_disable_sriov); | 588 | EXPORT_SYMBOL_GPL(pci_disable_sriov); |
689 | 589 | ||
690 | /** | 590 | /** |
691 | * pci_sriov_migration - notify SR-IOV core of Virtual Function Migration | ||
692 | * @dev: the PCI device | ||
693 | * | ||
694 | * Returns IRQ_HANDLED if the IRQ is handled, or IRQ_NONE if not. | ||
695 | * | ||
696 | * Physical Function driver is responsible to register IRQ handler using | ||
697 | * VF Migration Interrupt Message Number, and call this function when the | ||
698 | * interrupt is generated by the hardware. | ||
699 | */ | ||
700 | irqreturn_t pci_sriov_migration(struct pci_dev *dev) | ||
701 | { | ||
702 | if (!dev->is_physfn) | ||
703 | return IRQ_NONE; | ||
704 | |||
705 | return sriov_migration(dev) ? IRQ_HANDLED : IRQ_NONE; | ||
706 | } | ||
707 | EXPORT_SYMBOL_GPL(pci_sriov_migration); | ||
708 | |||
709 | /** | ||
710 | * pci_num_vf - return number of VFs associated with a PF device_release_driver | 591 | * pci_num_vf - return number of VFs associated with a PF device_release_driver |
711 | * @dev: the PCI device | 592 | * @dev: the PCI device |
712 | * | 593 | * |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index fdbc294821e6..7325d43bf030 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -108,12 +108,12 @@ static bool pcie_ari_disabled; | |||
108 | */ | 108 | */ |
109 | unsigned char pci_bus_max_busnr(struct pci_bus* bus) | 109 | unsigned char pci_bus_max_busnr(struct pci_bus* bus) |
110 | { | 110 | { |
111 | struct list_head *tmp; | 111 | struct pci_bus *tmp; |
112 | unsigned char max, n; | 112 | unsigned char max, n; |
113 | 113 | ||
114 | max = bus->busn_res.end; | 114 | max = bus->busn_res.end; |
115 | list_for_each(tmp, &bus->children) { | 115 | list_for_each_entry(tmp, &bus->children, node) { |
116 | n = pci_bus_max_busnr(pci_bus_b(tmp)); | 116 | n = pci_bus_max_busnr(tmp); |
117 | if(n > max) | 117 | if(n > max) |
118 | max = n; | 118 | max = n; |
119 | } | 119 | } |
@@ -401,33 +401,40 @@ EXPORT_SYMBOL_GPL(pci_find_ht_capability); | |||
401 | * @res: child resource record for which parent is sought | 401 | * @res: child resource record for which parent is sought |
402 | * | 402 | * |
403 | * For given resource region of given device, return the resource | 403 | * For given resource region of given device, return the resource |
404 | * region of parent bus the given region is contained in or where | 404 | * region of parent bus the given region is contained in. |
405 | * it should be allocated from. | ||
406 | */ | 405 | */ |
407 | struct resource * | 406 | struct resource * |
408 | pci_find_parent_resource(const struct pci_dev *dev, struct resource *res) | 407 | pci_find_parent_resource(const struct pci_dev *dev, struct resource *res) |
409 | { | 408 | { |
410 | const struct pci_bus *bus = dev->bus; | 409 | const struct pci_bus *bus = dev->bus; |
410 | struct resource *r; | ||
411 | int i; | 411 | int i; |
412 | struct resource *best = NULL, *r; | ||
413 | 412 | ||
414 | pci_bus_for_each_resource(bus, r, i) { | 413 | pci_bus_for_each_resource(bus, r, i) { |
415 | if (!r) | 414 | if (!r) |
416 | continue; | 415 | continue; |
417 | if (res->start && !(res->start >= r->start && res->end <= r->end)) | 416 | if (res->start && resource_contains(r, res)) { |
418 | continue; /* Not contained */ | 417 | |
419 | if ((res->flags ^ r->flags) & (IORESOURCE_IO | IORESOURCE_MEM)) | 418 | /* |
420 | continue; /* Wrong type */ | 419 | * If the window is prefetchable but the BAR is |
421 | if (!((res->flags ^ r->flags) & IORESOURCE_PREFETCH)) | 420 | * not, the allocator made a mistake. |
422 | return r; /* Exact match */ | 421 | */ |
423 | /* We can't insert a non-prefetch resource inside a prefetchable parent .. */ | 422 | if (r->flags & IORESOURCE_PREFETCH && |
424 | if (r->flags & IORESOURCE_PREFETCH) | 423 | !(res->flags & IORESOURCE_PREFETCH)) |
425 | continue; | 424 | return NULL; |
426 | /* .. but we can put a prefetchable resource inside a non-prefetchable one */ | 425 | |
427 | if (!best) | 426 | /* |
428 | best = r; | 427 | * If we're below a transparent bridge, there may |
428 | * be both a positively-decoded aperture and a | ||
429 | * subtractively-decoded region that contain the BAR. | ||
430 | * We want the positively-decoded one, so this depends | ||
431 | * on pci_bus_for_each_resource() giving us those | ||
432 | * first. | ||
433 | */ | ||
434 | return r; | ||
435 | } | ||
429 | } | 436 | } |
430 | return best; | 437 | return NULL; |
431 | } | 438 | } |
432 | 439 | ||
433 | /** | 440 | /** |
@@ -1178,6 +1185,11 @@ int pci_load_and_free_saved_state(struct pci_dev *dev, | |||
1178 | } | 1185 | } |
1179 | EXPORT_SYMBOL_GPL(pci_load_and_free_saved_state); | 1186 | EXPORT_SYMBOL_GPL(pci_load_and_free_saved_state); |
1180 | 1187 | ||
1188 | int __weak pcibios_enable_device(struct pci_dev *dev, int bars) | ||
1189 | { | ||
1190 | return pci_enable_resources(dev, bars); | ||
1191 | } | ||
1192 | |||
1181 | static int do_pci_enable_device(struct pci_dev *dev, int bars) | 1193 | static int do_pci_enable_device(struct pci_dev *dev, int bars) |
1182 | { | 1194 | { |
1183 | int err; | 1195 | int err; |
@@ -1624,29 +1636,27 @@ static void pci_pme_list_scan(struct work_struct *work) | |||
1624 | struct pci_pme_device *pme_dev, *n; | 1636 | struct pci_pme_device *pme_dev, *n; |
1625 | 1637 | ||
1626 | mutex_lock(&pci_pme_list_mutex); | 1638 | mutex_lock(&pci_pme_list_mutex); |
1627 | if (!list_empty(&pci_pme_list)) { | 1639 | list_for_each_entry_safe(pme_dev, n, &pci_pme_list, list) { |
1628 | list_for_each_entry_safe(pme_dev, n, &pci_pme_list, list) { | 1640 | if (pme_dev->dev->pme_poll) { |
1629 | if (pme_dev->dev->pme_poll) { | 1641 | struct pci_dev *bridge; |
1630 | struct pci_dev *bridge; | 1642 | |
1631 | 1643 | bridge = pme_dev->dev->bus->self; | |
1632 | bridge = pme_dev->dev->bus->self; | 1644 | /* |
1633 | /* | 1645 | * If bridge is in low power state, the |
1634 | * If bridge is in low power state, the | 1646 | * configuration space of subordinate devices |
1635 | * configuration space of subordinate devices | 1647 | * may be not accessible |
1636 | * may be not accessible | 1648 | */ |
1637 | */ | 1649 | if (bridge && bridge->current_state != PCI_D0) |
1638 | if (bridge && bridge->current_state != PCI_D0) | 1650 | continue; |
1639 | continue; | 1651 | pci_pme_wakeup(pme_dev->dev, NULL); |
1640 | pci_pme_wakeup(pme_dev->dev, NULL); | 1652 | } else { |
1641 | } else { | 1653 | list_del(&pme_dev->list); |
1642 | list_del(&pme_dev->list); | 1654 | kfree(pme_dev); |
1643 | kfree(pme_dev); | ||
1644 | } | ||
1645 | } | 1655 | } |
1646 | if (!list_empty(&pci_pme_list)) | ||
1647 | schedule_delayed_work(&pci_pme_work, | ||
1648 | msecs_to_jiffies(PME_TIMEOUT)); | ||
1649 | } | 1656 | } |
1657 | if (!list_empty(&pci_pme_list)) | ||
1658 | schedule_delayed_work(&pci_pme_work, | ||
1659 | msecs_to_jiffies(PME_TIMEOUT)); | ||
1650 | mutex_unlock(&pci_pme_list_mutex); | 1660 | mutex_unlock(&pci_pme_list_mutex); |
1651 | } | 1661 | } |
1652 | 1662 | ||
@@ -2193,21 +2203,18 @@ void pci_request_acs(void) | |||
2193 | } | 2203 | } |
2194 | 2204 | ||
2195 | /** | 2205 | /** |
2196 | * pci_enable_acs - enable ACS if hardware support it | 2206 | * pci_std_enable_acs - enable ACS on devices using standard ACS capabilites |
2197 | * @dev: the PCI device | 2207 | * @dev: the PCI device |
2198 | */ | 2208 | */ |
2199 | void pci_enable_acs(struct pci_dev *dev) | 2209 | static int pci_std_enable_acs(struct pci_dev *dev) |
2200 | { | 2210 | { |
2201 | int pos; | 2211 | int pos; |
2202 | u16 cap; | 2212 | u16 cap; |
2203 | u16 ctrl; | 2213 | u16 ctrl; |
2204 | 2214 | ||
2205 | if (!pci_acs_enable) | ||
2206 | return; | ||
2207 | |||
2208 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ACS); | 2215 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ACS); |
2209 | if (!pos) | 2216 | if (!pos) |
2210 | return; | 2217 | return -ENODEV; |
2211 | 2218 | ||
2212 | pci_read_config_word(dev, pos + PCI_ACS_CAP, &cap); | 2219 | pci_read_config_word(dev, pos + PCI_ACS_CAP, &cap); |
2213 | pci_read_config_word(dev, pos + PCI_ACS_CTRL, &ctrl); | 2220 | pci_read_config_word(dev, pos + PCI_ACS_CTRL, &ctrl); |
@@ -2225,6 +2232,23 @@ void pci_enable_acs(struct pci_dev *dev) | |||
2225 | ctrl |= (cap & PCI_ACS_UF); | 2232 | ctrl |= (cap & PCI_ACS_UF); |
2226 | 2233 | ||
2227 | pci_write_config_word(dev, pos + PCI_ACS_CTRL, ctrl); | 2234 | pci_write_config_word(dev, pos + PCI_ACS_CTRL, ctrl); |
2235 | |||
2236 | return 0; | ||
2237 | } | ||
2238 | |||
2239 | /** | ||
2240 | * pci_enable_acs - enable ACS if hardware support it | ||
2241 | * @dev: the PCI device | ||
2242 | */ | ||
2243 | void pci_enable_acs(struct pci_dev *dev) | ||
2244 | { | ||
2245 | if (!pci_acs_enable) | ||
2246 | return; | ||
2247 | |||
2248 | if (!pci_std_enable_acs(dev)) | ||
2249 | return; | ||
2250 | |||
2251 | pci_dev_specific_enable_acs(dev); | ||
2228 | } | 2252 | } |
2229 | 2253 | ||
2230 | static bool pci_acs_flags_enabled(struct pci_dev *pdev, u16 acs_flags) | 2254 | static bool pci_acs_flags_enabled(struct pci_dev *pdev, u16 acs_flags) |
@@ -4250,6 +4274,7 @@ void pci_reassigndev_resource_alignment(struct pci_dev *dev) | |||
4250 | "Rounding up size of resource #%d to %#llx.\n", | 4274 | "Rounding up size of resource #%d to %#llx.\n", |
4251 | i, (unsigned long long)size); | 4275 | i, (unsigned long long)size); |
4252 | } | 4276 | } |
4277 | r->flags |= IORESOURCE_UNSET; | ||
4253 | r->end = size - 1; | 4278 | r->end = size - 1; |
4254 | r->start = 0; | 4279 | r->start = 0; |
4255 | } | 4280 | } |
@@ -4263,6 +4288,7 @@ void pci_reassigndev_resource_alignment(struct pci_dev *dev) | |||
4263 | r = &dev->resource[i]; | 4288 | r = &dev->resource[i]; |
4264 | if (!(r->flags & IORESOURCE_MEM)) | 4289 | if (!(r->flags & IORESOURCE_MEM)) |
4265 | continue; | 4290 | continue; |
4291 | r->flags |= IORESOURCE_UNSET; | ||
4266 | r->end = resource_size(r) - 1; | 4292 | r->end = resource_size(r) - 1; |
4267 | r->start = 0; | 4293 | r->start = 0; |
4268 | } | 4294 | } |
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 4df38df224f4..6bd082299e31 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
@@ -1,8 +1,6 @@ | |||
1 | #ifndef DRIVERS_PCI_H | 1 | #ifndef DRIVERS_PCI_H |
2 | #define DRIVERS_PCI_H | 2 | #define DRIVERS_PCI_H |
3 | 3 | ||
4 | #include <linux/workqueue.h> | ||
5 | |||
6 | #define PCI_CFG_SPACE_SIZE 256 | 4 | #define PCI_CFG_SPACE_SIZE 256 |
7 | #define PCI_CFG_SPACE_EXP_SIZE 4096 | 5 | #define PCI_CFG_SPACE_EXP_SIZE 4096 |
8 | 6 | ||
@@ -240,8 +238,6 @@ struct pci_sriov { | |||
240 | struct pci_dev *dev; /* lowest numbered PF */ | 238 | struct pci_dev *dev; /* lowest numbered PF */ |
241 | struct pci_dev *self; /* this PF */ | 239 | struct pci_dev *self; /* this PF */ |
242 | struct mutex lock; /* lock for VF bus */ | 240 | struct mutex lock; /* lock for VF bus */ |
243 | struct work_struct mtask; /* VF Migration task */ | ||
244 | u8 __iomem *mstate; /* VF Migration State Array */ | ||
245 | }; | 241 | }; |
246 | 242 | ||
247 | #ifdef CONFIG_PCI_ATS | 243 | #ifdef CONFIG_PCI_ATS |
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 6e34498ec9f0..ef09f5f2fe6c 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -252,6 +252,7 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
252 | /* Address above 32-bit boundary; disable the BAR */ | 252 | /* Address above 32-bit boundary; disable the BAR */ |
253 | pci_write_config_dword(dev, pos, 0); | 253 | pci_write_config_dword(dev, pos, 0); |
254 | pci_write_config_dword(dev, pos + 4, 0); | 254 | pci_write_config_dword(dev, pos + 4, 0); |
255 | res->flags |= IORESOURCE_UNSET; | ||
255 | region.start = 0; | 256 | region.start = 0; |
256 | region.end = sz64; | 257 | region.end = sz64; |
257 | bar_disabled = true; | 258 | bar_disabled = true; |
@@ -731,22 +732,6 @@ struct pci_bus *__ref pci_add_new_bus(struct pci_bus *parent, struct pci_dev *de | |||
731 | return child; | 732 | return child; |
732 | } | 733 | } |
733 | 734 | ||
734 | static void pci_fixup_parent_subordinate_busnr(struct pci_bus *child, int max) | ||
735 | { | ||
736 | struct pci_bus *parent = child->parent; | ||
737 | |||
738 | /* Attempts to fix that up are really dangerous unless | ||
739 | we're going to re-assign all bus numbers. */ | ||
740 | if (!pcibios_assign_all_busses()) | ||
741 | return; | ||
742 | |||
743 | while (parent->parent && parent->busn_res.end < max) { | ||
744 | parent->busn_res.end = max; | ||
745 | pci_write_config_byte(parent->self, PCI_SUBORDINATE_BUS, max); | ||
746 | parent = parent->parent; | ||
747 | } | ||
748 | } | ||
749 | |||
750 | /* | 735 | /* |
751 | * If it's a bridge, configure it and scan the bus behind it. | 736 | * If it's a bridge, configure it and scan the bus behind it. |
752 | * For CardBus bridges, we don't scan behind as the devices will | 737 | * For CardBus bridges, we don't scan behind as the devices will |
@@ -782,7 +767,7 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass) | |||
782 | /* Check if setup is sensible at all */ | 767 | /* Check if setup is sensible at all */ |
783 | if (!pass && | 768 | if (!pass && |
784 | (primary != bus->number || secondary <= bus->number || | 769 | (primary != bus->number || secondary <= bus->number || |
785 | secondary > subordinate)) { | 770 | secondary > subordinate || subordinate > bus->busn_res.end)) { |
786 | dev_info(&dev->dev, "bridge configuration invalid ([bus %02x-%02x]), reconfiguring\n", | 771 | dev_info(&dev->dev, "bridge configuration invalid ([bus %02x-%02x]), reconfiguring\n", |
787 | secondary, subordinate); | 772 | secondary, subordinate); |
788 | broken = 1; | 773 | broken = 1; |
@@ -805,11 +790,10 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass) | |||
805 | goto out; | 790 | goto out; |
806 | 791 | ||
807 | /* | 792 | /* |
808 | * If we already got to this bus through a different bridge, | 793 | * The bus might already exist for two reasons: Either we are |
809 | * don't re-add it. This can happen with the i450NX chipset. | 794 | * rescanning the bus or the bus is reachable through more than |
810 | * | 795 | * one bridge. The second case can happen with the i450NX |
811 | * However, we continue to descend down the hierarchy and | 796 | * chipset. |
812 | * scan remaining child buses. | ||
813 | */ | 797 | */ |
814 | child = pci_find_bus(pci_domain_nr(bus), secondary); | 798 | child = pci_find_bus(pci_domain_nr(bus), secondary); |
815 | if (!child) { | 799 | if (!child) { |
@@ -822,17 +806,19 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass) | |||
822 | } | 806 | } |
823 | 807 | ||
824 | cmax = pci_scan_child_bus(child); | 808 | cmax = pci_scan_child_bus(child); |
825 | if (cmax > max) | 809 | if (cmax > subordinate) |
826 | max = cmax; | 810 | dev_warn(&dev->dev, "bridge has subordinate %02x but max busn %02x\n", |
827 | if (child->busn_res.end > max) | 811 | subordinate, cmax); |
828 | max = child->busn_res.end; | 812 | /* subordinate should equal child->busn_res.end */ |
813 | if (subordinate > max) | ||
814 | max = subordinate; | ||
829 | } else { | 815 | } else { |
830 | /* | 816 | /* |
831 | * We need to assign a number to this bus which we always | 817 | * We need to assign a number to this bus which we always |
832 | * do in the second pass. | 818 | * do in the second pass. |
833 | */ | 819 | */ |
834 | if (!pass) { | 820 | if (!pass) { |
835 | if (pcibios_assign_all_busses() || broken) | 821 | if (pcibios_assign_all_busses() || broken || is_cardbus) |
836 | /* Temporarily disable forwarding of the | 822 | /* Temporarily disable forwarding of the |
837 | configuration cycles on all bridges in | 823 | configuration cycles on all bridges in |
838 | this bus segment to avoid possible | 824 | this bus segment to avoid possible |
@@ -844,19 +830,25 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass) | |||
844 | goto out; | 830 | goto out; |
845 | } | 831 | } |
846 | 832 | ||
833 | if (max >= bus->busn_res.end) { | ||
834 | dev_warn(&dev->dev, "can't allocate child bus %02x from %pR\n", | ||
835 | max, &bus->busn_res); | ||
836 | goto out; | ||
837 | } | ||
838 | |||
847 | /* Clear errors */ | 839 | /* Clear errors */ |
848 | pci_write_config_word(dev, PCI_STATUS, 0xffff); | 840 | pci_write_config_word(dev, PCI_STATUS, 0xffff); |
849 | 841 | ||
850 | /* Prevent assigning a bus number that already exists. | 842 | /* The bus will already exist if we are rescanning */ |
851 | * This can happen when a bridge is hot-plugged, so in | ||
852 | * this case we only re-scan this bus. */ | ||
853 | child = pci_find_bus(pci_domain_nr(bus), max+1); | 843 | child = pci_find_bus(pci_domain_nr(bus), max+1); |
854 | if (!child) { | 844 | if (!child) { |
855 | child = pci_add_new_bus(bus, dev, ++max); | 845 | child = pci_add_new_bus(bus, dev, max+1); |
856 | if (!child) | 846 | if (!child) |
857 | goto out; | 847 | goto out; |
858 | pci_bus_insert_busn_res(child, max, 0xff); | 848 | pci_bus_insert_busn_res(child, max+1, |
849 | bus->busn_res.end); | ||
859 | } | 850 | } |
851 | max++; | ||
860 | buses = (buses & 0xff000000) | 852 | buses = (buses & 0xff000000) |
861 | | ((unsigned int)(child->primary) << 0) | 853 | | ((unsigned int)(child->primary) << 0) |
862 | | ((unsigned int)(child->busn_res.start) << 8) | 854 | | ((unsigned int)(child->busn_res.start) << 8) |
@@ -878,20 +870,7 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass) | |||
878 | 870 | ||
879 | if (!is_cardbus) { | 871 | if (!is_cardbus) { |
880 | child->bridge_ctl = bctl; | 872 | child->bridge_ctl = bctl; |
881 | /* | ||
882 | * Adjust subordinate busnr in parent buses. | ||
883 | * We do this before scanning for children because | ||
884 | * some devices may not be detected if the bios | ||
885 | * was lazy. | ||
886 | */ | ||
887 | pci_fixup_parent_subordinate_busnr(child, max); | ||
888 | /* Now we can scan all subordinate buses... */ | ||
889 | max = pci_scan_child_bus(child); | 873 | max = pci_scan_child_bus(child); |
890 | /* | ||
891 | * now fix it up again since we have found | ||
892 | * the real value of max. | ||
893 | */ | ||
894 | pci_fixup_parent_subordinate_busnr(child, max); | ||
895 | } else { | 874 | } else { |
896 | /* | 875 | /* |
897 | * For CardBus bridges, we leave 4 bus numbers | 876 | * For CardBus bridges, we leave 4 bus numbers |
@@ -922,11 +901,15 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass) | |||
922 | } | 901 | } |
923 | } | 902 | } |
924 | max += i; | 903 | max += i; |
925 | pci_fixup_parent_subordinate_busnr(child, max); | ||
926 | } | 904 | } |
927 | /* | 905 | /* |
928 | * Set the subordinate bus number to its real value. | 906 | * Set the subordinate bus number to its real value. |
929 | */ | 907 | */ |
908 | if (max > bus->busn_res.end) { | ||
909 | dev_warn(&dev->dev, "max busn %02x is outside %pR\n", | ||
910 | max, &bus->busn_res); | ||
911 | max = bus->busn_res.end; | ||
912 | } | ||
930 | pci_bus_update_busn_res_end(child, max); | 913 | pci_bus_update_busn_res_end(child, max); |
931 | pci_write_config_byte(dev, PCI_SUBORDINATE_BUS, max); | 914 | pci_write_config_byte(dev, PCI_SUBORDINATE_BUS, max); |
932 | } | 915 | } |
@@ -1125,10 +1108,10 @@ int pci_setup_device(struct pci_dev *dev) | |||
1125 | pci_read_config_word(dev, PCI_SUBSYSTEM_ID, &dev->subsystem_device); | 1108 | pci_read_config_word(dev, PCI_SUBSYSTEM_ID, &dev->subsystem_device); |
1126 | 1109 | ||
1127 | /* | 1110 | /* |
1128 | * Do the ugly legacy mode stuff here rather than broken chip | 1111 | * Do the ugly legacy mode stuff here rather than broken chip |
1129 | * quirk code. Legacy mode ATA controllers have fixed | 1112 | * quirk code. Legacy mode ATA controllers have fixed |
1130 | * addresses. These are not always echoed in BAR0-3, and | 1113 | * addresses. These are not always echoed in BAR0-3, and |
1131 | * BAR0-3 in a few cases contain junk! | 1114 | * BAR0-3 in a few cases contain junk! |
1132 | */ | 1115 | */ |
1133 | if (class == PCI_CLASS_STORAGE_IDE) { | 1116 | if (class == PCI_CLASS_STORAGE_IDE) { |
1134 | u8 progif; | 1117 | u8 progif; |
@@ -1139,11 +1122,15 @@ int pci_setup_device(struct pci_dev *dev) | |||
1139 | res = &dev->resource[0]; | 1122 | res = &dev->resource[0]; |
1140 | res->flags = LEGACY_IO_RESOURCE; | 1123 | res->flags = LEGACY_IO_RESOURCE; |
1141 | pcibios_bus_to_resource(dev->bus, res, ®ion); | 1124 | pcibios_bus_to_resource(dev->bus, res, ®ion); |
1125 | dev_info(&dev->dev, "legacy IDE quirk: reg 0x10: %pR\n", | ||
1126 | res); | ||
1142 | region.start = 0x3F6; | 1127 | region.start = 0x3F6; |
1143 | region.end = 0x3F6; | 1128 | region.end = 0x3F6; |
1144 | res = &dev->resource[1]; | 1129 | res = &dev->resource[1]; |
1145 | res->flags = LEGACY_IO_RESOURCE; | 1130 | res->flags = LEGACY_IO_RESOURCE; |
1146 | pcibios_bus_to_resource(dev->bus, res, ®ion); | 1131 | pcibios_bus_to_resource(dev->bus, res, ®ion); |
1132 | dev_info(&dev->dev, "legacy IDE quirk: reg 0x14: %pR\n", | ||
1133 | res); | ||
1147 | } | 1134 | } |
1148 | if ((progif & 4) == 0) { | 1135 | if ((progif & 4) == 0) { |
1149 | region.start = 0x170; | 1136 | region.start = 0x170; |
@@ -1151,11 +1138,15 @@ int pci_setup_device(struct pci_dev *dev) | |||
1151 | res = &dev->resource[2]; | 1138 | res = &dev->resource[2]; |
1152 | res->flags = LEGACY_IO_RESOURCE; | 1139 | res->flags = LEGACY_IO_RESOURCE; |
1153 | pcibios_bus_to_resource(dev->bus, res, ®ion); | 1140 | pcibios_bus_to_resource(dev->bus, res, ®ion); |
1141 | dev_info(&dev->dev, "legacy IDE quirk: reg 0x18: %pR\n", | ||
1142 | res); | ||
1154 | region.start = 0x376; | 1143 | region.start = 0x376; |
1155 | region.end = 0x376; | 1144 | region.end = 0x376; |
1156 | res = &dev->resource[3]; | 1145 | res = &dev->resource[3]; |
1157 | res->flags = LEGACY_IO_RESOURCE; | 1146 | res->flags = LEGACY_IO_RESOURCE; |
1158 | pcibios_bus_to_resource(dev->bus, res, ®ion); | 1147 | pcibios_bus_to_resource(dev->bus, res, ®ion); |
1148 | dev_info(&dev->dev, "legacy IDE quirk: reg 0x1c: %pR\n", | ||
1149 | res); | ||
1159 | } | 1150 | } |
1160 | } | 1151 | } |
1161 | break; | 1152 | break; |
@@ -1835,7 +1826,7 @@ int pci_bus_insert_busn_res(struct pci_bus *b, int bus, int bus_max) | |||
1835 | res->flags |= IORESOURCE_PCI_FIXED; | 1826 | res->flags |= IORESOURCE_PCI_FIXED; |
1836 | } | 1827 | } |
1837 | 1828 | ||
1838 | conflict = insert_resource_conflict(parent_res, res); | 1829 | conflict = request_resource_conflict(parent_res, res); |
1839 | 1830 | ||
1840 | if (conflict) | 1831 | if (conflict) |
1841 | dev_printk(KERN_DEBUG, &b->dev, | 1832 | dev_printk(KERN_DEBUG, &b->dev, |
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 5cb726c193de..e7292065a1b1 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -296,6 +296,7 @@ static void quirk_s3_64M(struct pci_dev *dev) | |||
296 | struct resource *r = &dev->resource[0]; | 296 | struct resource *r = &dev->resource[0]; |
297 | 297 | ||
298 | if ((r->start & 0x3ffffff) || r->end != r->start + 0x3ffffff) { | 298 | if ((r->start & 0x3ffffff) || r->end != r->start + 0x3ffffff) { |
299 | r->flags |= IORESOURCE_UNSET; | ||
299 | r->start = 0; | 300 | r->start = 0; |
300 | r->end = 0x3ffffff; | 301 | r->end = 0x3ffffff; |
301 | } | 302 | } |
@@ -937,6 +938,8 @@ DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_700C | |||
937 | static void quirk_dunord(struct pci_dev *dev) | 938 | static void quirk_dunord(struct pci_dev *dev) |
938 | { | 939 | { |
939 | struct resource *r = &dev->resource [1]; | 940 | struct resource *r = &dev->resource [1]; |
941 | |||
942 | r->flags |= IORESOURCE_UNSET; | ||
940 | r->start = 0; | 943 | r->start = 0; |
941 | r->end = 0xffffff; | 944 | r->end = 0xffffff; |
942 | } | 945 | } |
@@ -1740,6 +1743,7 @@ static void quirk_tc86c001_ide(struct pci_dev *dev) | |||
1740 | struct resource *r = &dev->resource[0]; | 1743 | struct resource *r = &dev->resource[0]; |
1741 | 1744 | ||
1742 | if (r->start & 0x8) { | 1745 | if (r->start & 0x8) { |
1746 | r->flags |= IORESOURCE_UNSET; | ||
1743 | r->start = 0; | 1747 | r->start = 0; |
1744 | r->end = 0xf; | 1748 | r->end = 0xf; |
1745 | } | 1749 | } |
@@ -1769,6 +1773,7 @@ static void quirk_plx_pci9050(struct pci_dev *dev) | |||
1769 | dev_info(&dev->dev, | 1773 | dev_info(&dev->dev, |
1770 | "Re-allocating PLX PCI 9050 BAR %u to length 256 to avoid bit 7 bug\n", | 1774 | "Re-allocating PLX PCI 9050 BAR %u to length 256 to avoid bit 7 bug\n", |
1771 | bar); | 1775 | bar); |
1776 | r->flags |= IORESOURCE_UNSET; | ||
1772 | r->start = 0; | 1777 | r->start = 0; |
1773 | r->end = 0xff; | 1778 | r->end = 0xff; |
1774 | } | 1779 | } |
@@ -3423,6 +3428,61 @@ static int pci_quirk_amd_sb_acs(struct pci_dev *dev, u16 acs_flags) | |||
3423 | #endif | 3428 | #endif |
3424 | } | 3429 | } |
3425 | 3430 | ||
3431 | /* | ||
3432 | * Many Intel PCH root ports do provide ACS-like features to disable peer | ||
3433 | * transactions and validate bus numbers in requests, but do not provide an | ||
3434 | * actual PCIe ACS capability. This is the list of device IDs known to fall | ||
3435 | * into that category as provided by Intel in Red Hat bugzilla 1037684. | ||
3436 | */ | ||
3437 | static const u16 pci_quirk_intel_pch_acs_ids[] = { | ||
3438 | /* Ibexpeak PCH */ | ||
3439 | 0x3b42, 0x3b43, 0x3b44, 0x3b45, 0x3b46, 0x3b47, 0x3b48, 0x3b49, | ||
3440 | 0x3b4a, 0x3b4b, 0x3b4c, 0x3b4d, 0x3b4e, 0x3b4f, 0x3b50, 0x3b51, | ||
3441 | /* Cougarpoint PCH */ | ||
3442 | 0x1c10, 0x1c11, 0x1c12, 0x1c13, 0x1c14, 0x1c15, 0x1c16, 0x1c17, | ||
3443 | 0x1c18, 0x1c19, 0x1c1a, 0x1c1b, 0x1c1c, 0x1c1d, 0x1c1e, 0x1c1f, | ||
3444 | /* Pantherpoint PCH */ | ||
3445 | 0x1e10, 0x1e11, 0x1e12, 0x1e13, 0x1e14, 0x1e15, 0x1e16, 0x1e17, | ||
3446 | 0x1e18, 0x1e19, 0x1e1a, 0x1e1b, 0x1e1c, 0x1e1d, 0x1e1e, 0x1e1f, | ||
3447 | /* Lynxpoint-H PCH */ | ||
3448 | 0x8c10, 0x8c11, 0x8c12, 0x8c13, 0x8c14, 0x8c15, 0x8c16, 0x8c17, | ||
3449 | 0x8c18, 0x8c19, 0x8c1a, 0x8c1b, 0x8c1c, 0x8c1d, 0x8c1e, 0x8c1f, | ||
3450 | /* Lynxpoint-LP PCH */ | ||
3451 | 0x9c10, 0x9c11, 0x9c12, 0x9c13, 0x9c14, 0x9c15, 0x9c16, 0x9c17, | ||
3452 | 0x9c18, 0x9c19, 0x9c1a, 0x9c1b, | ||
3453 | /* Wildcat PCH */ | ||
3454 | 0x9c90, 0x9c91, 0x9c92, 0x9c93, 0x9c94, 0x9c95, 0x9c96, 0x9c97, | ||
3455 | 0x9c98, 0x9c99, 0x9c9a, 0x9c9b, | ||
3456 | }; | ||
3457 | |||
3458 | static bool pci_quirk_intel_pch_acs_match(struct pci_dev *dev) | ||
3459 | { | ||
3460 | int i; | ||
3461 | |||
3462 | /* Filter out a few obvious non-matches first */ | ||
3463 | if (!pci_is_pcie(dev) || pci_pcie_type(dev) != PCI_EXP_TYPE_ROOT_PORT) | ||
3464 | return false; | ||
3465 | |||
3466 | for (i = 0; i < ARRAY_SIZE(pci_quirk_intel_pch_acs_ids); i++) | ||
3467 | if (pci_quirk_intel_pch_acs_ids[i] == dev->device) | ||
3468 | return true; | ||
3469 | |||
3470 | return false; | ||
3471 | } | ||
3472 | |||
3473 | #define INTEL_PCH_ACS_FLAGS (PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF | PCI_ACS_SV) | ||
3474 | |||
3475 | static int pci_quirk_intel_pch_acs(struct pci_dev *dev, u16 acs_flags) | ||
3476 | { | ||
3477 | u16 flags = dev->dev_flags & PCI_DEV_FLAGS_ACS_ENABLED_QUIRK ? | ||
3478 | INTEL_PCH_ACS_FLAGS : 0; | ||
3479 | |||
3480 | if (!pci_quirk_intel_pch_acs_match(dev)) | ||
3481 | return -ENOTTY; | ||
3482 | |||
3483 | return acs_flags & ~flags ? 0 : 1; | ||
3484 | } | ||
3485 | |||
3426 | static const struct pci_dev_acs_enabled { | 3486 | static const struct pci_dev_acs_enabled { |
3427 | u16 vendor; | 3487 | u16 vendor; |
3428 | u16 device; | 3488 | u16 device; |
@@ -3434,6 +3494,7 @@ static const struct pci_dev_acs_enabled { | |||
3434 | { PCI_VENDOR_ID_ATI, 0x439d, pci_quirk_amd_sb_acs }, | 3494 | { PCI_VENDOR_ID_ATI, 0x439d, pci_quirk_amd_sb_acs }, |
3435 | { PCI_VENDOR_ID_ATI, 0x4384, pci_quirk_amd_sb_acs }, | 3495 | { PCI_VENDOR_ID_ATI, 0x4384, pci_quirk_amd_sb_acs }, |
3436 | { PCI_VENDOR_ID_ATI, 0x4399, pci_quirk_amd_sb_acs }, | 3496 | { PCI_VENDOR_ID_ATI, 0x4399, pci_quirk_amd_sb_acs }, |
3497 | { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_quirk_intel_pch_acs }, | ||
3437 | { 0 } | 3498 | { 0 } |
3438 | }; | 3499 | }; |
3439 | 3500 | ||
@@ -3461,3 +3522,132 @@ int pci_dev_specific_acs_enabled(struct pci_dev *dev, u16 acs_flags) | |||
3461 | 3522 | ||
3462 | return -ENOTTY; | 3523 | return -ENOTTY; |
3463 | } | 3524 | } |
3525 | |||
3526 | /* Config space offset of Root Complex Base Address register */ | ||
3527 | #define INTEL_LPC_RCBA_REG 0xf0 | ||
3528 | /* 31:14 RCBA address */ | ||
3529 | #define INTEL_LPC_RCBA_MASK 0xffffc000 | ||
3530 | /* RCBA Enable */ | ||
3531 | #define INTEL_LPC_RCBA_ENABLE (1 << 0) | ||
3532 | |||
3533 | /* Backbone Scratch Pad Register */ | ||
3534 | #define INTEL_BSPR_REG 0x1104 | ||
3535 | /* Backbone Peer Non-Posted Disable */ | ||
3536 | #define INTEL_BSPR_REG_BPNPD (1 << 8) | ||
3537 | /* Backbone Peer Posted Disable */ | ||
3538 | #define INTEL_BSPR_REG_BPPD (1 << 9) | ||
3539 | |||
3540 | /* Upstream Peer Decode Configuration Register */ | ||
3541 | #define INTEL_UPDCR_REG 0x1114 | ||
3542 | /* 5:0 Peer Decode Enable bits */ | ||
3543 | #define INTEL_UPDCR_REG_MASK 0x3f | ||
3544 | |||
3545 | static int pci_quirk_enable_intel_lpc_acs(struct pci_dev *dev) | ||
3546 | { | ||
3547 | u32 rcba, bspr, updcr; | ||
3548 | void __iomem *rcba_mem; | ||
3549 | |||
3550 | /* | ||
3551 | * Read the RCBA register from the LPC (D31:F0). PCH root ports | ||
3552 | * are D28:F* and therefore get probed before LPC, thus we can't | ||
3553 | * use pci_get_slot/pci_read_config_dword here. | ||
3554 | */ | ||
3555 | pci_bus_read_config_dword(dev->bus, PCI_DEVFN(31, 0), | ||
3556 | INTEL_LPC_RCBA_REG, &rcba); | ||
3557 | if (!(rcba & INTEL_LPC_RCBA_ENABLE)) | ||
3558 | return -EINVAL; | ||
3559 | |||
3560 | rcba_mem = ioremap_nocache(rcba & INTEL_LPC_RCBA_MASK, | ||
3561 | PAGE_ALIGN(INTEL_UPDCR_REG)); | ||
3562 | if (!rcba_mem) | ||
3563 | return -ENOMEM; | ||
3564 | |||
3565 | /* | ||
3566 | * The BSPR can disallow peer cycles, but it's set by soft strap and | ||
3567 | * therefore read-only. If both posted and non-posted peer cycles are | ||
3568 | * disallowed, we're ok. If either are allowed, then we need to use | ||
3569 | * the UPDCR to disable peer decodes for each port. This provides the | ||
3570 | * PCIe ACS equivalent of PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF | ||
3571 | */ | ||
3572 | bspr = readl(rcba_mem + INTEL_BSPR_REG); | ||
3573 | bspr &= INTEL_BSPR_REG_BPNPD | INTEL_BSPR_REG_BPPD; | ||
3574 | if (bspr != (INTEL_BSPR_REG_BPNPD | INTEL_BSPR_REG_BPPD)) { | ||
3575 | updcr = readl(rcba_mem + INTEL_UPDCR_REG); | ||
3576 | if (updcr & INTEL_UPDCR_REG_MASK) { | ||
3577 | dev_info(&dev->dev, "Disabling UPDCR peer decodes\n"); | ||
3578 | updcr &= ~INTEL_UPDCR_REG_MASK; | ||
3579 | writel(updcr, rcba_mem + INTEL_UPDCR_REG); | ||
3580 | } | ||
3581 | } | ||
3582 | |||
3583 | iounmap(rcba_mem); | ||
3584 | return 0; | ||
3585 | } | ||
3586 | |||
3587 | /* Miscellaneous Port Configuration register */ | ||
3588 | #define INTEL_MPC_REG 0xd8 | ||
3589 | /* MPC: Invalid Receive Bus Number Check Enable */ | ||
3590 | #define INTEL_MPC_REG_IRBNCE (1 << 26) | ||
3591 | |||
3592 | static void pci_quirk_enable_intel_rp_mpc_acs(struct pci_dev *dev) | ||
3593 | { | ||
3594 | u32 mpc; | ||
3595 | |||
3596 | /* | ||
3597 | * When enabled, the IRBNCE bit of the MPC register enables the | ||
3598 | * equivalent of PCI ACS Source Validation (PCI_ACS_SV), which | ||
3599 | * ensures that requester IDs fall within the bus number range | ||
3600 | * of the bridge. Enable if not already. | ||
3601 | */ | ||
3602 | pci_read_config_dword(dev, INTEL_MPC_REG, &mpc); | ||
3603 | if (!(mpc & INTEL_MPC_REG_IRBNCE)) { | ||
3604 | dev_info(&dev->dev, "Enabling MPC IRBNCE\n"); | ||
3605 | mpc |= INTEL_MPC_REG_IRBNCE; | ||
3606 | pci_write_config_word(dev, INTEL_MPC_REG, mpc); | ||
3607 | } | ||
3608 | } | ||
3609 | |||
3610 | static int pci_quirk_enable_intel_pch_acs(struct pci_dev *dev) | ||
3611 | { | ||
3612 | if (!pci_quirk_intel_pch_acs_match(dev)) | ||
3613 | return -ENOTTY; | ||
3614 | |||
3615 | if (pci_quirk_enable_intel_lpc_acs(dev)) { | ||
3616 | dev_warn(&dev->dev, "Failed to enable Intel PCH ACS quirk\n"); | ||
3617 | return 0; | ||
3618 | } | ||
3619 | |||
3620 | pci_quirk_enable_intel_rp_mpc_acs(dev); | ||
3621 | |||
3622 | dev->dev_flags |= PCI_DEV_FLAGS_ACS_ENABLED_QUIRK; | ||
3623 | |||
3624 | dev_info(&dev->dev, "Intel PCH root port ACS workaround enabled\n"); | ||
3625 | |||
3626 | return 0; | ||
3627 | } | ||
3628 | |||
3629 | static const struct pci_dev_enable_acs { | ||
3630 | u16 vendor; | ||
3631 | u16 device; | ||
3632 | int (*enable_acs)(struct pci_dev *dev); | ||
3633 | } pci_dev_enable_acs[] = { | ||
3634 | { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_quirk_enable_intel_pch_acs }, | ||
3635 | { 0 } | ||
3636 | }; | ||
3637 | |||
3638 | void pci_dev_specific_enable_acs(struct pci_dev *dev) | ||
3639 | { | ||
3640 | const struct pci_dev_enable_acs *i; | ||
3641 | int ret; | ||
3642 | |||
3643 | for (i = pci_dev_enable_acs; i->enable_acs; i++) { | ||
3644 | if ((i->vendor == dev->vendor || | ||
3645 | i->vendor == (u16)PCI_ANY_ID) && | ||
3646 | (i->device == dev->device || | ||
3647 | i->device == (u16)PCI_ANY_ID)) { | ||
3648 | ret = i->enable_acs(dev); | ||
3649 | if (ret >= 0) | ||
3650 | return; | ||
3651 | } | ||
3652 | } | ||
3653 | } | ||
diff --git a/drivers/pci/rom.c b/drivers/pci/rom.c index 5d595724e5f4..c1839450d4d6 100644 --- a/drivers/pci/rom.c +++ b/drivers/pci/rom.c | |||
@@ -197,8 +197,10 @@ void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom) | |||
197 | void pci_cleanup_rom(struct pci_dev *pdev) | 197 | void pci_cleanup_rom(struct pci_dev *pdev) |
198 | { | 198 | { |
199 | struct resource *res = &pdev->resource[PCI_ROM_RESOURCE]; | 199 | struct resource *res = &pdev->resource[PCI_ROM_RESOURCE]; |
200 | |||
200 | if (res->flags & IORESOURCE_ROM_COPY) { | 201 | if (res->flags & IORESOURCE_ROM_COPY) { |
201 | kfree((void*)(unsigned long)res->start); | 202 | kfree((void*)(unsigned long)res->start); |
203 | res->flags |= IORESOURCE_UNSET; | ||
202 | res->flags &= ~IORESOURCE_ROM_COPY; | 204 | res->flags &= ~IORESOURCE_ROM_COPY; |
203 | res->start = 0; | 205 | res->start = 0; |
204 | res->end = 0; | 206 | res->end = 0; |
diff --git a/drivers/pci/search.c b/drivers/pci/search.c index 3ff2ac7c14e2..4a1b972efe7f 100644 --- a/drivers/pci/search.c +++ b/drivers/pci/search.c | |||
@@ -54,14 +54,14 @@ pci_find_upstream_pcie_bridge(struct pci_dev *pdev) | |||
54 | 54 | ||
55 | static struct pci_bus *pci_do_find_bus(struct pci_bus *bus, unsigned char busnr) | 55 | static struct pci_bus *pci_do_find_bus(struct pci_bus *bus, unsigned char busnr) |
56 | { | 56 | { |
57 | struct pci_bus* child; | 57 | struct pci_bus *child; |
58 | struct list_head *tmp; | 58 | struct pci_bus *tmp; |
59 | 59 | ||
60 | if(bus->number == busnr) | 60 | if(bus->number == busnr) |
61 | return bus; | 61 | return bus; |
62 | 62 | ||
63 | list_for_each(tmp, &bus->children) { | 63 | list_for_each_entry(tmp, &bus->children, node) { |
64 | child = pci_do_find_bus(pci_bus_b(tmp), busnr); | 64 | child = pci_do_find_bus(tmp, busnr); |
65 | if(child) | 65 | if(child) |
66 | return child; | 66 | return child; |
67 | } | 67 | } |
@@ -111,7 +111,7 @@ pci_find_next_bus(const struct pci_bus *from) | |||
111 | down_read(&pci_bus_sem); | 111 | down_read(&pci_bus_sem); |
112 | n = from ? from->node.next : pci_root_buses.next; | 112 | n = from ? from->node.next : pci_root_buses.next; |
113 | if (n != &pci_root_buses) | 113 | if (n != &pci_root_buses) |
114 | b = pci_bus_b(n); | 114 | b = list_entry(n, struct pci_bus, node); |
115 | up_read(&pci_bus_sem); | 115 | up_read(&pci_bus_sem); |
116 | return b; | 116 | return b; |
117 | } | 117 | } |
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index 5c060b152ce6..7eed671d5586 100644 --- a/drivers/pci/setup-res.c +++ b/drivers/pci/setup-res.c | |||
@@ -44,6 +44,9 @@ void pci_update_resource(struct pci_dev *dev, int resno) | |||
44 | if (!res->flags) | 44 | if (!res->flags) |
45 | return; | 45 | return; |
46 | 46 | ||
47 | if (res->flags & IORESOURCE_UNSET) | ||
48 | return; | ||
49 | |||
47 | /* | 50 | /* |
48 | * Ignore non-moveable resources. This might be legacy resources for | 51 | * Ignore non-moveable resources. This might be legacy resources for |
49 | * which no functional BAR register exists or another important | 52 | * which no functional BAR register exists or another important |
@@ -101,11 +104,6 @@ void pci_update_resource(struct pci_dev *dev, int resno) | |||
101 | 104 | ||
102 | if (disable) | 105 | if (disable) |
103 | pci_write_config_word(dev, PCI_COMMAND, cmd); | 106 | pci_write_config_word(dev, PCI_COMMAND, cmd); |
104 | |||
105 | res->flags &= ~IORESOURCE_UNSET; | ||
106 | dev_dbg(&dev->dev, "BAR %d: set to %pR (PCI address [%#llx-%#llx])\n", | ||
107 | resno, res, (unsigned long long)region.start, | ||
108 | (unsigned long long)region.end); | ||
109 | } | 107 | } |
110 | 108 | ||
111 | int pci_claim_resource(struct pci_dev *dev, int resource) | 109 | int pci_claim_resource(struct pci_dev *dev, int resource) |
@@ -113,18 +111,23 @@ int pci_claim_resource(struct pci_dev *dev, int resource) | |||
113 | struct resource *res = &dev->resource[resource]; | 111 | struct resource *res = &dev->resource[resource]; |
114 | struct resource *root, *conflict; | 112 | struct resource *root, *conflict; |
115 | 113 | ||
114 | if (res->flags & IORESOURCE_UNSET) { | ||
115 | dev_info(&dev->dev, "can't claim BAR %d %pR: no address assigned\n", | ||
116 | resource, res); | ||
117 | return -EINVAL; | ||
118 | } | ||
119 | |||
116 | root = pci_find_parent_resource(dev, res); | 120 | root = pci_find_parent_resource(dev, res); |
117 | if (!root) { | 121 | if (!root) { |
118 | dev_info(&dev->dev, "no compatible bridge window for %pR\n", | 122 | dev_info(&dev->dev, "can't claim BAR %d %pR: no compatible bridge window\n", |
119 | res); | 123 | resource, res); |
120 | return -EINVAL; | 124 | return -EINVAL; |
121 | } | 125 | } |
122 | 126 | ||
123 | conflict = request_resource_conflict(root, res); | 127 | conflict = request_resource_conflict(root, res); |
124 | if (conflict) { | 128 | if (conflict) { |
125 | dev_info(&dev->dev, | 129 | dev_info(&dev->dev, "can't claim BAR %d %pR: address conflict with %s %pR\n", |
126 | "address space collision: %pR conflicts with %s %pR\n", | 130 | resource, res, conflict->name, conflict); |
127 | res, conflict->name, conflict); | ||
128 | return -EBUSY; | 131 | return -EBUSY; |
129 | } | 132 | } |
130 | 133 | ||
@@ -263,6 +266,7 @@ int pci_assign_resource(struct pci_dev *dev, int resno) | |||
263 | resource_size_t align, size; | 266 | resource_size_t align, size; |
264 | int ret; | 267 | int ret; |
265 | 268 | ||
269 | res->flags |= IORESOURCE_UNSET; | ||
266 | align = pci_resource_alignment(dev, res); | 270 | align = pci_resource_alignment(dev, res); |
267 | if (!align) { | 271 | if (!align) { |
268 | dev_info(&dev->dev, "BAR %d: can't assign %pR " | 272 | dev_info(&dev->dev, "BAR %d: can't assign %pR " |
@@ -282,6 +286,7 @@ int pci_assign_resource(struct pci_dev *dev, int resno) | |||
282 | ret = pci_revert_fw_address(res, dev, resno, size); | 286 | ret = pci_revert_fw_address(res, dev, resno, size); |
283 | 287 | ||
284 | if (!ret) { | 288 | if (!ret) { |
289 | res->flags &= ~IORESOURCE_UNSET; | ||
285 | res->flags &= ~IORESOURCE_STARTALIGN; | 290 | res->flags &= ~IORESOURCE_STARTALIGN; |
286 | dev_info(&dev->dev, "BAR %d: assigned %pR\n", resno, res); | 291 | dev_info(&dev->dev, "BAR %d: assigned %pR\n", resno, res); |
287 | if (resno < PCI_BRIDGE_RESOURCES) | 292 | if (resno < PCI_BRIDGE_RESOURCES) |
@@ -297,6 +302,7 @@ int pci_reassign_resource(struct pci_dev *dev, int resno, resource_size_t addsiz | |||
297 | resource_size_t new_size; | 302 | resource_size_t new_size; |
298 | int ret; | 303 | int ret; |
299 | 304 | ||
305 | res->flags |= IORESOURCE_UNSET; | ||
300 | if (!res->parent) { | 306 | if (!res->parent) { |
301 | dev_info(&dev->dev, "BAR %d: can't reassign an unassigned resource %pR " | 307 | dev_info(&dev->dev, "BAR %d: can't reassign an unassigned resource %pR " |
302 | "\n", resno, res); | 308 | "\n", resno, res); |
@@ -307,6 +313,7 @@ int pci_reassign_resource(struct pci_dev *dev, int resno, resource_size_t addsiz | |||
307 | new_size = resource_size(res) + addsize; | 313 | new_size = resource_size(res) + addsize; |
308 | ret = _pci_assign_resource(dev, resno, new_size, min_align); | 314 | ret = _pci_assign_resource(dev, resno, new_size, min_align); |
309 | if (!ret) { | 315 | if (!ret) { |
316 | res->flags &= ~IORESOURCE_UNSET; | ||
310 | res->flags &= ~IORESOURCE_STARTALIGN; | 317 | res->flags &= ~IORESOURCE_STARTALIGN; |
311 | dev_info(&dev->dev, "BAR %d: reassigned %pR\n", resno, res); | 318 | dev_info(&dev->dev, "BAR %d: reassigned %pR\n", resno, res); |
312 | if (resno < PCI_BRIDGE_RESOURCES) | 319 | if (resno < PCI_BRIDGE_RESOURCES) |
@@ -336,9 +343,15 @@ int pci_enable_resources(struct pci_dev *dev, int mask) | |||
336 | (!(r->flags & IORESOURCE_ROM_ENABLE))) | 343 | (!(r->flags & IORESOURCE_ROM_ENABLE))) |
337 | continue; | 344 | continue; |
338 | 345 | ||
346 | if (r->flags & IORESOURCE_UNSET) { | ||
347 | dev_err(&dev->dev, "can't enable device: BAR %d %pR not assigned\n", | ||
348 | i, r); | ||
349 | return -EINVAL; | ||
350 | } | ||
351 | |||
339 | if (!r->parent) { | 352 | if (!r->parent) { |
340 | dev_err(&dev->dev, "device not available " | 353 | dev_err(&dev->dev, "can't enable device: BAR %d %pR not claimed\n", |
341 | "(can't reserve %pR)\n", r); | 354 | i, r); |
342 | return -EINVAL; | 355 | return -EINVAL; |
343 | } | 356 | } |
344 | 357 | ||
diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c index 8485761e76af..946f90ef6020 100644 --- a/drivers/pcmcia/yenta_socket.c +++ b/drivers/pcmcia/yenta_socket.c | |||
@@ -1076,7 +1076,7 @@ static void yenta_config_init(struct yenta_socket *socket) | |||
1076 | */ | 1076 | */ |
1077 | static void yenta_fixup_parent_bridge(struct pci_bus *cardbus_bridge) | 1077 | static void yenta_fixup_parent_bridge(struct pci_bus *cardbus_bridge) |
1078 | { | 1078 | { |
1079 | struct list_head *tmp; | 1079 | struct pci_bus *sibling; |
1080 | unsigned char upper_limit; | 1080 | unsigned char upper_limit; |
1081 | /* | 1081 | /* |
1082 | * We only check and fix the parent bridge: All systems which need | 1082 | * We only check and fix the parent bridge: All systems which need |
@@ -1095,18 +1095,18 @@ static void yenta_fixup_parent_bridge(struct pci_bus *cardbus_bridge) | |||
1095 | /* stay within the limits of the bus range of the parent: */ | 1095 | /* stay within the limits of the bus range of the parent: */ |
1096 | upper_limit = bridge_to_fix->parent->busn_res.end; | 1096 | upper_limit = bridge_to_fix->parent->busn_res.end; |
1097 | 1097 | ||
1098 | /* check the bus ranges of all silbling bridges to prevent overlap */ | 1098 | /* check the bus ranges of all sibling bridges to prevent overlap */ |
1099 | list_for_each(tmp, &bridge_to_fix->parent->children) { | 1099 | list_for_each_entry(sibling, &bridge_to_fix->parent->children, |
1100 | struct pci_bus *silbling = pci_bus_b(tmp); | 1100 | node) { |
1101 | /* | 1101 | /* |
1102 | * If the silbling has a higher secondary bus number | 1102 | * If the sibling has a higher secondary bus number |
1103 | * and it's secondary is equal or smaller than our | 1103 | * and it's secondary is equal or smaller than our |
1104 | * current upper limit, set the new upper limit to | 1104 | * current upper limit, set the new upper limit to |
1105 | * the bus number below the silbling's range: | 1105 | * the bus number below the sibling's range: |
1106 | */ | 1106 | */ |
1107 | if (silbling->busn_res.start > bridge_to_fix->busn_res.end | 1107 | if (sibling->busn_res.start > bridge_to_fix->busn_res.end |
1108 | && silbling->busn_res.start <= upper_limit) | 1108 | && sibling->busn_res.start <= upper_limit) |
1109 | upper_limit = silbling->busn_res.start - 1; | 1109 | upper_limit = sibling->busn_res.start - 1; |
1110 | } | 1110 | } |
1111 | 1111 | ||
1112 | /* Show that the wanted subordinate number is not possible: */ | 1112 | /* Show that the wanted subordinate number is not possible: */ |
diff --git a/drivers/vfio/pci/vfio_pci_intrs.c b/drivers/vfio/pci/vfio_pci_intrs.c index 210357691dc0..9dd49c9839ac 100644 --- a/drivers/vfio/pci/vfio_pci_intrs.c +++ b/drivers/vfio/pci/vfio_pci_intrs.c | |||
@@ -482,15 +482,19 @@ static int vfio_msi_enable(struct vfio_pci_device *vdev, int nvec, bool msix) | |||
482 | for (i = 0; i < nvec; i++) | 482 | for (i = 0; i < nvec; i++) |
483 | vdev->msix[i].entry = i; | 483 | vdev->msix[i].entry = i; |
484 | 484 | ||
485 | ret = pci_enable_msix(pdev, vdev->msix, nvec); | 485 | ret = pci_enable_msix_range(pdev, vdev->msix, 1, nvec); |
486 | if (ret) { | 486 | if (ret < nvec) { |
487 | if (ret > 0) | ||
488 | pci_disable_msix(pdev); | ||
487 | kfree(vdev->msix); | 489 | kfree(vdev->msix); |
488 | kfree(vdev->ctx); | 490 | kfree(vdev->ctx); |
489 | return ret; | 491 | return ret; |
490 | } | 492 | } |
491 | } else { | 493 | } else { |
492 | ret = pci_enable_msi_block(pdev, nvec); | 494 | ret = pci_enable_msi_range(pdev, 1, nvec); |
493 | if (ret) { | 495 | if (ret < nvec) { |
496 | if (ret > 0) | ||
497 | pci_disable_msi(pdev); | ||
494 | kfree(vdev->ctx); | 498 | kfree(vdev->ctx); |
495 | return ret; | 499 | return ret; |
496 | } | 500 | } |
diff --git a/include/acpi/acpi_numa.h b/include/acpi/acpi_numa.h index 451823cb8837..94a37cd7fbda 100644 --- a/include/acpi/acpi_numa.h +++ b/include/acpi/acpi_numa.h | |||
@@ -13,7 +13,6 @@ | |||
13 | 13 | ||
14 | extern int pxm_to_node(int); | 14 | extern int pxm_to_node(int); |
15 | extern int node_to_pxm(int); | 15 | extern int node_to_pxm(int); |
16 | extern void __acpi_map_pxm_to_node(int, int); | ||
17 | extern int acpi_map_pxm_to_node(int); | 16 | extern int acpi_map_pxm_to_node(int); |
18 | extern unsigned char acpi_srat_revision; | 17 | extern unsigned char acpi_srat_revision; |
19 | 18 | ||
diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 6a15dddbaa09..7a8f2cd66c8b 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h | |||
@@ -263,14 +263,9 @@ extern void acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d); | |||
263 | extern void acpi_osi_setup(char *str); | 263 | extern void acpi_osi_setup(char *str); |
264 | 264 | ||
265 | #ifdef CONFIG_ACPI_NUMA | 265 | #ifdef CONFIG_ACPI_NUMA |
266 | int acpi_get_pxm(acpi_handle handle); | 266 | int acpi_get_node(acpi_handle handle); |
267 | int acpi_get_node(acpi_handle *handle); | ||
268 | #else | 267 | #else |
269 | static inline int acpi_get_pxm(acpi_handle handle) | 268 | static inline int acpi_get_node(acpi_handle handle) |
270 | { | ||
271 | return 0; | ||
272 | } | ||
273 | static inline int acpi_get_node(acpi_handle *handle) | ||
274 | { | 269 | { |
275 | return 0; | 270 | return 0; |
276 | } | 271 | } |
diff --git a/include/linux/ioport.h b/include/linux/ioport.h index 89b7c24a36e9..5e3a906cc089 100644 --- a/include/linux/ioport.h +++ b/include/linux/ioport.h | |||
@@ -51,7 +51,7 @@ struct resource { | |||
51 | 51 | ||
52 | #define IORESOURCE_EXCLUSIVE 0x08000000 /* Userland may not map this resource */ | 52 | #define IORESOURCE_EXCLUSIVE 0x08000000 /* Userland may not map this resource */ |
53 | #define IORESOURCE_DISABLED 0x10000000 | 53 | #define IORESOURCE_DISABLED 0x10000000 |
54 | #define IORESOURCE_UNSET 0x20000000 | 54 | #define IORESOURCE_UNSET 0x20000000 /* No address assigned yet */ |
55 | #define IORESOURCE_AUTO 0x40000000 | 55 | #define IORESOURCE_AUTO 0x40000000 |
56 | #define IORESOURCE_BUSY 0x80000000 /* Driver has marked this resource busy */ | 56 | #define IORESOURCE_BUSY 0x80000000 /* Driver has marked this resource busy */ |
57 | 57 | ||
@@ -169,6 +169,16 @@ static inline unsigned long resource_type(const struct resource *res) | |||
169 | { | 169 | { |
170 | return res->flags & IORESOURCE_TYPE_BITS; | 170 | return res->flags & IORESOURCE_TYPE_BITS; |
171 | } | 171 | } |
172 | /* True iff r1 completely contains r2 */ | ||
173 | static inline bool resource_contains(struct resource *r1, struct resource *r2) | ||
174 | { | ||
175 | if (resource_type(r1) != resource_type(r2)) | ||
176 | return false; | ||
177 | if (r1->flags & IORESOURCE_UNSET || r2->flags & IORESOURCE_UNSET) | ||
178 | return false; | ||
179 | return r1->start <= r2->start && r1->end >= r2->end; | ||
180 | } | ||
181 | |||
172 | 182 | ||
173 | /* Convenience shorthand with allocation */ | 183 | /* Convenience shorthand with allocation */ |
174 | #define request_region(start,n,name) __request_region(&ioport_resource, (start), (n), (name), 0) | 184 | #define request_region(start,n,name) __request_region(&ioport_resource, (start), (n), (name), 0) |
diff --git a/include/linux/pci.h b/include/linux/pci.h index 33aa2caf0f0c..aab57b4abe7f 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
@@ -29,7 +29,6 @@ | |||
29 | #include <linux/atomic.h> | 29 | #include <linux/atomic.h> |
30 | #include <linux/device.h> | 30 | #include <linux/device.h> |
31 | #include <linux/io.h> | 31 | #include <linux/io.h> |
32 | #include <linux/irqreturn.h> | ||
33 | #include <uapi/linux/pci.h> | 32 | #include <uapi/linux/pci.h> |
34 | 33 | ||
35 | #include <linux/pci_ids.h> | 34 | #include <linux/pci_ids.h> |
@@ -170,6 +169,8 @@ enum pci_dev_flags { | |||
170 | PCI_DEV_FLAGS_NO_D3 = (__force pci_dev_flags_t) 2, | 169 | PCI_DEV_FLAGS_NO_D3 = (__force pci_dev_flags_t) 2, |
171 | /* Provide indication device is assigned by a Virtual Machine Manager */ | 170 | /* Provide indication device is assigned by a Virtual Machine Manager */ |
172 | PCI_DEV_FLAGS_ASSIGNED = (__force pci_dev_flags_t) 4, | 171 | PCI_DEV_FLAGS_ASSIGNED = (__force pci_dev_flags_t) 4, |
172 | /* Flag for quirk use to store if quirk-specific ACS is enabled */ | ||
173 | PCI_DEV_FLAGS_ACS_ENABLED_QUIRK = (__force pci_dev_flags_t) 8, | ||
173 | }; | 174 | }; |
174 | 175 | ||
175 | enum pci_irq_reroute_variant { | 176 | enum pci_irq_reroute_variant { |
@@ -461,7 +462,6 @@ struct pci_bus { | |||
461 | unsigned int is_added:1; | 462 | unsigned int is_added:1; |
462 | }; | 463 | }; |
463 | 464 | ||
464 | #define pci_bus_b(n) list_entry(n, struct pci_bus, node) | ||
465 | #define to_pci_bus(n) container_of(n, struct pci_bus, dev) | 465 | #define to_pci_bus(n) container_of(n, struct pci_bus, dev) |
466 | 466 | ||
467 | /* | 467 | /* |
@@ -1066,7 +1066,7 @@ void pci_bus_remove_resources(struct pci_bus *bus); | |||
1066 | int __must_check pci_bus_alloc_resource(struct pci_bus *bus, | 1066 | int __must_check pci_bus_alloc_resource(struct pci_bus *bus, |
1067 | struct resource *res, resource_size_t size, | 1067 | struct resource *res, resource_size_t size, |
1068 | resource_size_t align, resource_size_t min, | 1068 | resource_size_t align, resource_size_t min, |
1069 | unsigned int type_mask, | 1069 | unsigned long type_mask, |
1070 | resource_size_t (*alignf)(void *, | 1070 | resource_size_t (*alignf)(void *, |
1071 | const struct resource *, | 1071 | const struct resource *, |
1072 | resource_size_t, | 1072 | resource_size_t, |
@@ -1530,6 +1530,7 @@ enum pci_fixup_pass { | |||
1530 | void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev); | 1530 | void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev); |
1531 | struct pci_dev *pci_get_dma_source(struct pci_dev *dev); | 1531 | struct pci_dev *pci_get_dma_source(struct pci_dev *dev); |
1532 | int pci_dev_specific_acs_enabled(struct pci_dev *dev, u16 acs_flags); | 1532 | int pci_dev_specific_acs_enabled(struct pci_dev *dev, u16 acs_flags); |
1533 | void pci_dev_specific_enable_acs(struct pci_dev *dev); | ||
1533 | #else | 1534 | #else |
1534 | static inline void pci_fixup_device(enum pci_fixup_pass pass, | 1535 | static inline void pci_fixup_device(enum pci_fixup_pass pass, |
1535 | struct pci_dev *dev) { } | 1536 | struct pci_dev *dev) { } |
@@ -1542,6 +1543,7 @@ static inline int pci_dev_specific_acs_enabled(struct pci_dev *dev, | |||
1542 | { | 1543 | { |
1543 | return -ENOTTY; | 1544 | return -ENOTTY; |
1544 | } | 1545 | } |
1546 | static inline void pci_dev_specific_enable_acs(struct pci_dev *dev) { } | ||
1545 | #endif | 1547 | #endif |
1546 | 1548 | ||
1547 | void __iomem *pcim_iomap(struct pci_dev *pdev, int bar, unsigned long maxlen); | 1549 | void __iomem *pcim_iomap(struct pci_dev *pdev, int bar, unsigned long maxlen); |
@@ -1597,7 +1599,6 @@ void __iomem *pci_ioremap_bar(struct pci_dev *pdev, int bar); | |||
1597 | #ifdef CONFIG_PCI_IOV | 1599 | #ifdef CONFIG_PCI_IOV |
1598 | int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn); | 1600 | int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn); |
1599 | void pci_disable_sriov(struct pci_dev *dev); | 1601 | void pci_disable_sriov(struct pci_dev *dev); |
1600 | irqreturn_t pci_sriov_migration(struct pci_dev *dev); | ||
1601 | int pci_num_vf(struct pci_dev *dev); | 1602 | int pci_num_vf(struct pci_dev *dev); |
1602 | int pci_vfs_assigned(struct pci_dev *dev); | 1603 | int pci_vfs_assigned(struct pci_dev *dev); |
1603 | int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs); | 1604 | int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs); |
@@ -1606,8 +1607,6 @@ int pci_sriov_get_totalvfs(struct pci_dev *dev); | |||
1606 | static inline int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn) | 1607 | static inline int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn) |
1607 | { return -ENODEV; } | 1608 | { return -ENODEV; } |
1608 | static inline void pci_disable_sriov(struct pci_dev *dev) { } | 1609 | static inline void pci_disable_sriov(struct pci_dev *dev) { } |
1609 | static inline irqreturn_t pci_sriov_migration(struct pci_dev *dev) | ||
1610 | { return IRQ_NONE; } | ||
1611 | static inline int pci_num_vf(struct pci_dev *dev) { return 0; } | 1610 | static inline int pci_num_vf(struct pci_dev *dev) { return 0; } |
1612 | static inline int pci_vfs_assigned(struct pci_dev *dev) | 1611 | static inline int pci_vfs_assigned(struct pci_dev *dev) |
1613 | { return 0; } | 1612 | { return 0; } |
diff --git a/kernel/resource.c b/kernel/resource.c index 3f285dce9347..673061c06da1 100644 --- a/kernel/resource.c +++ b/kernel/resource.c | |||
@@ -432,11 +432,6 @@ static void resource_clip(struct resource *res, resource_size_t min, | |||
432 | res->end = max; | 432 | res->end = max; |
433 | } | 433 | } |
434 | 434 | ||
435 | static bool resource_contains(struct resource *res1, struct resource *res2) | ||
436 | { | ||
437 | return res1->start <= res2->start && res1->end >= res2->end; | ||
438 | } | ||
439 | |||
440 | /* | 435 | /* |
441 | * Find empty slot in the resource tree with the given range and | 436 | * Find empty slot in the resource tree with the given range and |
442 | * alignment constraints | 437 | * alignment constraints |
@@ -471,10 +466,11 @@ static int __find_resource(struct resource *root, struct resource *old, | |||
471 | arch_remove_reservations(&tmp); | 466 | arch_remove_reservations(&tmp); |
472 | 467 | ||
473 | /* Check for overflow after ALIGN() */ | 468 | /* Check for overflow after ALIGN() */ |
474 | avail = *new; | ||
475 | avail.start = ALIGN(tmp.start, constraint->align); | 469 | avail.start = ALIGN(tmp.start, constraint->align); |
476 | avail.end = tmp.end; | 470 | avail.end = tmp.end; |
471 | avail.flags = new->flags & ~IORESOURCE_UNSET; | ||
477 | if (avail.start >= tmp.start) { | 472 | if (avail.start >= tmp.start) { |
473 | alloc.flags = avail.flags; | ||
478 | alloc.start = constraint->alignf(constraint->alignf_data, &avail, | 474 | alloc.start = constraint->alignf(constraint->alignf_data, &avail, |
479 | size, constraint->align); | 475 | size, constraint->align); |
480 | alloc.end = alloc.start + size - 1; | 476 | alloc.end = alloc.start + size - 1; |
@@ -949,8 +945,8 @@ struct resource * __request_region(struct resource *parent, | |||
949 | res->name = name; | 945 | res->name = name; |
950 | res->start = start; | 946 | res->start = start; |
951 | res->end = start + n - 1; | 947 | res->end = start + n - 1; |
952 | res->flags = IORESOURCE_BUSY; | 948 | res->flags = resource_type(parent); |
953 | res->flags |= flags; | 949 | res->flags |= IORESOURCE_BUSY | flags; |
954 | 950 | ||
955 | write_lock(&resource_lock); | 951 | write_lock(&resource_lock); |
956 | 952 | ||
diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 185b6d300ebc..5e2cf6f342f8 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c | |||
@@ -719,10 +719,15 @@ char *resource_string(char *buf, char *end, struct resource *res, | |||
719 | specp = &mem_spec; | 719 | specp = &mem_spec; |
720 | decode = 0; | 720 | decode = 0; |
721 | } | 721 | } |
722 | p = number(p, pend, res->start, *specp); | 722 | if (decode && res->flags & IORESOURCE_UNSET) { |
723 | if (res->start != res->end) { | 723 | p = string(p, pend, "size ", str_spec); |
724 | *p++ = '-'; | 724 | p = number(p, pend, resource_size(res), *specp); |
725 | p = number(p, pend, res->end, *specp); | 725 | } else { |
726 | p = number(p, pend, res->start, *specp); | ||
727 | if (res->start != res->end) { | ||
728 | *p++ = '-'; | ||
729 | p = number(p, pend, res->end, *specp); | ||
730 | } | ||
726 | } | 731 | } |
727 | if (decode) { | 732 | if (decode) { |
728 | if (res->flags & IORESOURCE_MEM_64) | 733 | if (res->flags & IORESOURCE_MEM_64) |