aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-06-12 19:17:03 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-06-16 16:33:20 -0400
commit12e27b115472ad0f3b142ddf59d3998305984408 (patch)
tree6fc02fd0af6f50ec0450c62016b0b270684c76a6 /arch
parent7171511eaec5bf23fb06078f59784a3a0626b38f (diff)
ACPI / ia64 / sba_iommu: Restore the working initialization ordering
Commit 66345d5f79fc (ACPI / ia64 / sba_iommu: Use ACPI scan handler for device discovery) changed the ordering of SBA (System Bus Adapter) IOMMU initialization with respect to the PCI host bridge initialization which broke things inadvertently, because the SBA IOMMU initialization code has to run after the PCI host bridge has been initialized. Fix that by reworking the SBA IOMMU ACPI scan handler so that it claims the discovered matching ACPI device objects without attempting to initialize anything and move the entire SBA IOMMU initialization to sba_init() that runs after the PCI bus has been enumerated. Link: https://bugzilla.kernel.org/show_bug.cgi?id=76691 Fixes: 66345d5f79fc (ACPI / ia64 / sba_iommu: Use ACPI scan handler for device discovery) Reported-and-tested-by: Émeric Maschino <emeric.maschino@gmail.com> Cc: Tony Luck <tony.luck@intel.com> Cc: 3.11+ <stable@vger.kernel.org> # 3.11+ Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/ia64/hp/common/sba_iommu.c64
1 files changed, 37 insertions, 27 deletions
diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c
index 1a871b78e570..344387a55406 100644
--- a/arch/ia64/hp/common/sba_iommu.c
+++ b/arch/ia64/hp/common/sba_iommu.c
@@ -242,7 +242,7 @@ struct ioc {
242 struct pci_dev *sac_only_dev; 242 struct pci_dev *sac_only_dev;
243}; 243};
244 244
245static struct ioc *ioc_list; 245static struct ioc *ioc_list, *ioc_found;
246static int reserve_sba_gart = 1; 246static int reserve_sba_gart = 1;
247 247
248static SBA_INLINE void sba_mark_invalid(struct ioc *, dma_addr_t, size_t); 248static SBA_INLINE void sba_mark_invalid(struct ioc *, dma_addr_t, size_t);
@@ -1809,20 +1809,13 @@ static struct ioc_iommu ioc_iommu_info[] __initdata = {
1809 { SX2000_IOC_ID, "sx2000", NULL }, 1809 { SX2000_IOC_ID, "sx2000", NULL },
1810}; 1810};
1811 1811
1812static struct ioc * 1812static void ioc_init(unsigned long hpa, struct ioc *ioc)
1813ioc_init(unsigned long hpa, void *handle)
1814{ 1813{
1815 struct ioc *ioc;
1816 struct ioc_iommu *info; 1814 struct ioc_iommu *info;
1817 1815
1818 ioc = kzalloc(sizeof(*ioc), GFP_KERNEL);
1819 if (!ioc)
1820 return NULL;
1821
1822 ioc->next = ioc_list; 1816 ioc->next = ioc_list;
1823 ioc_list = ioc; 1817 ioc_list = ioc;
1824 1818
1825 ioc->handle = handle;
1826 ioc->ioc_hpa = ioremap(hpa, 0x1000); 1819 ioc->ioc_hpa = ioremap(hpa, 0x1000);
1827 1820
1828 ioc->func_id = READ_REG(ioc->ioc_hpa + IOC_FUNC_ID); 1821 ioc->func_id = READ_REG(ioc->ioc_hpa + IOC_FUNC_ID);
@@ -1863,8 +1856,6 @@ ioc_init(unsigned long hpa, void *handle)
1863 "%s %d.%d HPA 0x%lx IOVA space %dMb at 0x%lx\n", 1856 "%s %d.%d HPA 0x%lx IOVA space %dMb at 0x%lx\n",
1864 ioc->name, (ioc->rev >> 4) & 0xF, ioc->rev & 0xF, 1857 ioc->name, (ioc->rev >> 4) & 0xF, ioc->rev & 0xF,
1865 hpa, ioc->iov_size >> 20, ioc->ibase); 1858 hpa, ioc->iov_size >> 20, ioc->ibase);
1866
1867 return ioc;
1868} 1859}
1869 1860
1870 1861
@@ -2031,22 +2022,21 @@ sba_map_ioc_to_node(struct ioc *ioc, acpi_handle handle)
2031#endif 2022#endif
2032} 2023}
2033 2024
2034static int 2025static void acpi_sba_ioc_add(struct ioc *ioc)
2035acpi_sba_ioc_add(struct acpi_device *device,
2036 const struct acpi_device_id *not_used)
2037{ 2026{
2038 struct ioc *ioc; 2027 acpi_handle handle = ioc->handle;
2039 acpi_status status; 2028 acpi_status status;
2040 u64 hpa, length; 2029 u64 hpa, length;
2041 struct acpi_device_info *adi; 2030 struct acpi_device_info *adi;
2042 2031
2043 status = hp_acpi_csr_space(device->handle, &hpa, &length); 2032 ioc_found = ioc->next;
2033 status = hp_acpi_csr_space(handle, &hpa, &length);
2044 if (ACPI_FAILURE(status)) 2034 if (ACPI_FAILURE(status))
2045 return 1; 2035 goto err;
2046 2036
2047 status = acpi_get_object_info(device->handle, &adi); 2037 status = acpi_get_object_info(handle, &adi);
2048 if (ACPI_FAILURE(status)) 2038 if (ACPI_FAILURE(status))
2049 return 1; 2039 goto err;
2050 2040
2051 /* 2041 /*
2052 * For HWP0001, only SBA appears in ACPI namespace. It encloses the PCI 2042 * For HWP0001, only SBA appears in ACPI namespace. It encloses the PCI
@@ -2067,13 +2057,13 @@ acpi_sba_ioc_add(struct acpi_device *device,
2067 if (!iovp_shift) 2057 if (!iovp_shift)
2068 iovp_shift = 12; 2058 iovp_shift = 12;
2069 2059
2070 ioc = ioc_init(hpa, device->handle); 2060 ioc_init(hpa, ioc);
2071 if (!ioc)
2072 return 1;
2073
2074 /* setup NUMA node association */ 2061 /* setup NUMA node association */
2075 sba_map_ioc_to_node(ioc, device->handle); 2062 sba_map_ioc_to_node(ioc, handle);
2076 return 0; 2063 return;
2064
2065 err:
2066 kfree(ioc);
2077} 2067}
2078 2068
2079static const struct acpi_device_id hp_ioc_iommu_device_ids[] = { 2069static const struct acpi_device_id hp_ioc_iommu_device_ids[] = {
@@ -2081,9 +2071,26 @@ static const struct acpi_device_id hp_ioc_iommu_device_ids[] = {
2081 {"HWP0004", 0}, 2071 {"HWP0004", 0},
2082 {"", 0}, 2072 {"", 0},
2083}; 2073};
2074
2075static int acpi_sba_ioc_attach(struct acpi_device *device,
2076 const struct acpi_device_id *not_used)
2077{
2078 struct ioc *ioc;
2079
2080 ioc = kzalloc(sizeof(*ioc), GFP_KERNEL);
2081 if (!ioc)
2082 return -ENOMEM;
2083
2084 ioc->next = ioc_found;
2085 ioc_found = ioc;
2086 ioc->handle = device->handle;
2087 return 1;
2088}
2089
2090
2084static struct acpi_scan_handler acpi_sba_ioc_handler = { 2091static struct acpi_scan_handler acpi_sba_ioc_handler = {
2085 .ids = hp_ioc_iommu_device_ids, 2092 .ids = hp_ioc_iommu_device_ids,
2086 .attach = acpi_sba_ioc_add, 2093 .attach = acpi_sba_ioc_attach,
2087}; 2094};
2088 2095
2089static int __init acpi_sba_ioc_init_acpi(void) 2096static int __init acpi_sba_ioc_init_acpi(void)
@@ -2118,9 +2125,12 @@ sba_init(void)
2118#endif 2125#endif
2119 2126
2120 /* 2127 /*
2121 * ioc_list should be populated by the acpi_sba_ioc_handler's .attach() 2128 * ioc_found should be populated by the acpi_sba_ioc_handler's .attach()
2122 * routine, but that only happens if acpi_scan_init() has already run. 2129 * routine, but that only happens if acpi_scan_init() has already run.
2123 */ 2130 */
2131 while (ioc_found)
2132 acpi_sba_ioc_add(ioc_found);
2133
2124 if (!ioc_list) { 2134 if (!ioc_list) {
2125#ifdef CONFIG_IA64_GENERIC 2135#ifdef CONFIG_IA64_GENERIC
2126 /* 2136 /*