|
@@ -242,7 +242,7 @@ struct ioc {
|
|
|
struct pci_dev *sac_only_dev;
|
|
|
};
|
|
|
|
|
|
-static struct ioc *ioc_list;
|
|
|
+static struct ioc *ioc_list, *ioc_found;
|
|
|
static int reserve_sba_gart = 1;
|
|
|
|
|
|
static 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 = {
|
|
|
{ SX2000_IOC_ID, "sx2000", NULL },
|
|
|
};
|
|
|
|
|
|
-static struct ioc *
|
|
|
-ioc_init(unsigned long hpa, void *handle)
|
|
|
+static void ioc_init(unsigned long hpa, struct ioc *ioc)
|
|
|
{
|
|
|
- struct ioc *ioc;
|
|
|
struct ioc_iommu *info;
|
|
|
|
|
|
- ioc = kzalloc(sizeof(*ioc), GFP_KERNEL);
|
|
|
- if (!ioc)
|
|
|
- return NULL;
|
|
|
-
|
|
|
ioc->next = ioc_list;
|
|
|
ioc_list = ioc;
|
|
|
|
|
|
- ioc->handle = handle;
|
|
|
ioc->ioc_hpa = ioremap(hpa, 0x1000);
|
|
|
|
|
|
ioc->func_id = READ_REG(ioc->ioc_hpa + IOC_FUNC_ID);
|
|
@@ -1863,8 +1856,6 @@ ioc_init(unsigned long hpa, void *handle)
|
|
|
"%s %d.%d HPA 0x%lx IOVA space %dMb at 0x%lx\n",
|
|
|
ioc->name, (ioc->rev >> 4) & 0xF, ioc->rev & 0xF,
|
|
|
hpa, ioc->iov_size >> 20, ioc->ibase);
|
|
|
-
|
|
|
- return ioc;
|
|
|
}
|
|
|
|
|
|
|
|
@@ -2031,22 +2022,21 @@ sba_map_ioc_to_node(struct ioc *ioc, acpi_handle handle)
|
|
|
#endif
|
|
|
}
|
|
|
|
|
|
-static int
|
|
|
-acpi_sba_ioc_add(struct acpi_device *device,
|
|
|
- const struct acpi_device_id *not_used)
|
|
|
+static void acpi_sba_ioc_add(struct ioc *ioc)
|
|
|
{
|
|
|
- struct ioc *ioc;
|
|
|
+ acpi_handle handle = ioc->handle;
|
|
|
acpi_status status;
|
|
|
u64 hpa, length;
|
|
|
struct acpi_device_info *adi;
|
|
|
|
|
|
- status = hp_acpi_csr_space(device->handle, &hpa, &length);
|
|
|
+ ioc_found = ioc->next;
|
|
|
+ status = hp_acpi_csr_space(handle, &hpa, &length);
|
|
|
if (ACPI_FAILURE(status))
|
|
|
- return 1;
|
|
|
+ goto err;
|
|
|
|
|
|
- status = acpi_get_object_info(device->handle, &adi);
|
|
|
+ status = acpi_get_object_info(handle, &adi);
|
|
|
if (ACPI_FAILURE(status))
|
|
|
- return 1;
|
|
|
+ goto err;
|
|
|
|
|
|
/*
|
|
|
* For HWP0001, only SBA appears in ACPI namespace. It encloses the PCI
|
|
@@ -2067,13 +2057,13 @@ acpi_sba_ioc_add(struct acpi_device *device,
|
|
|
if (!iovp_shift)
|
|
|
iovp_shift = 12;
|
|
|
|
|
|
- ioc = ioc_init(hpa, device->handle);
|
|
|
- if (!ioc)
|
|
|
- return 1;
|
|
|
-
|
|
|
+ ioc_init(hpa, ioc);
|
|
|
/* setup NUMA node association */
|
|
|
- sba_map_ioc_to_node(ioc, device->handle);
|
|
|
- return 0;
|
|
|
+ sba_map_ioc_to_node(ioc, handle);
|
|
|
+ return;
|
|
|
+
|
|
|
+ err:
|
|
|
+ kfree(ioc);
|
|
|
}
|
|
|
|
|
|
static 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[] = {
|
|
|
{"HWP0004", 0},
|
|
|
{"", 0},
|
|
|
};
|
|
|
+
|
|
|
+static int acpi_sba_ioc_attach(struct acpi_device *device,
|
|
|
+ const struct acpi_device_id *not_used)
|
|
|
+{
|
|
|
+ struct ioc *ioc;
|
|
|
+
|
|
|
+ ioc = kzalloc(sizeof(*ioc), GFP_KERNEL);
|
|
|
+ if (!ioc)
|
|
|
+ return -ENOMEM;
|
|
|
+
|
|
|
+ ioc->next = ioc_found;
|
|
|
+ ioc_found = ioc;
|
|
|
+ ioc->handle = device->handle;
|
|
|
+ return 1;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
static struct acpi_scan_handler acpi_sba_ioc_handler = {
|
|
|
.ids = hp_ioc_iommu_device_ids,
|
|
|
- .attach = acpi_sba_ioc_add,
|
|
|
+ .attach = acpi_sba_ioc_attach,
|
|
|
};
|
|
|
|
|
|
static int __init acpi_sba_ioc_init_acpi(void)
|
|
@@ -2118,9 +2125,12 @@ sba_init(void)
|
|
|
#endif
|
|
|
|
|
|
/*
|
|
|
- * ioc_list should be populated by the acpi_sba_ioc_handler's .attach()
|
|
|
+ * ioc_found should be populated by the acpi_sba_ioc_handler's .attach()
|
|
|
* routine, but that only happens if acpi_scan_init() has already run.
|
|
|
*/
|
|
|
+ while (ioc_found)
|
|
|
+ acpi_sba_ioc_add(ioc_found);
|
|
|
+
|
|
|
if (!ioc_list) {
|
|
|
#ifdef CONFIG_IA64_GENERIC
|
|
|
/*
|