From: Yinghai Lu <ying...@kernel.org>

Rui Wang reported ioapic hot-add does not work on his machine
that _CRS have MEMORY_FIXED.
He also proposed to expose resource_to_addr() and use it for ioapic.

We should move it to acpi generic, as ioapi.c current is in
drivers/pci/.

Or should move it to acpica?

Signed-off-by: Yinghai Lu <ying...@kernel.org>
Signed-off-by: Jiang Liu <jiang....@linux.intel.com>
---
 arch/x86/pci/acpi.c     |   50 ++---------------------------------------------
 drivers/acpi/resource.c |   46 +++++++++++++++++++++++++++++++++++++++++++
 include/linux/acpi.h    |    3 +++
 3 files changed, 51 insertions(+), 48 deletions(-)

diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c
index 91bef49df228..e766cc7d3abe 100644
--- a/arch/x86/pci/acpi.c
+++ b/arch/x86/pci/acpi.c
@@ -218,59 +218,13 @@ static void teardown_mcfg_map(struct pci_root_info *info)
 }
 #endif
 
-static acpi_status resource_to_addr(struct acpi_resource *resource,
-                                   struct acpi_resource_address64 *addr)
-{
-       acpi_status status;
-       struct acpi_resource_memory24 *memory24;
-       struct acpi_resource_memory32 *memory32;
-       struct acpi_resource_fixed_memory32 *fixed_memory32;
-
-       memset(addr, 0, sizeof(*addr));
-       switch (resource->type) {
-       case ACPI_RESOURCE_TYPE_MEMORY24:
-               memory24 = &resource->data.memory24;
-               addr->resource_type = ACPI_MEMORY_RANGE;
-               addr->minimum = memory24->minimum;
-               addr->address_length = memory24->address_length;
-               addr->maximum = addr->minimum + addr->address_length - 1;
-               return AE_OK;
-       case ACPI_RESOURCE_TYPE_MEMORY32:
-               memory32 = &resource->data.memory32;
-               addr->resource_type = ACPI_MEMORY_RANGE;
-               addr->minimum = memory32->minimum;
-               addr->address_length = memory32->address_length;
-               addr->maximum = addr->minimum + addr->address_length - 1;
-               return AE_OK;
-       case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
-               fixed_memory32 = &resource->data.fixed_memory32;
-               addr->resource_type = ACPI_MEMORY_RANGE;
-               addr->minimum = fixed_memory32->address;
-               addr->address_length = fixed_memory32->address_length;
-               addr->maximum = addr->minimum + addr->address_length - 1;
-               return AE_OK;
-       case ACPI_RESOURCE_TYPE_ADDRESS16:
-       case ACPI_RESOURCE_TYPE_ADDRESS32:
-       case ACPI_RESOURCE_TYPE_ADDRESS64:
-               status = acpi_resource_to_address64(resource, addr);
-               if (ACPI_SUCCESS(status) &&
-                   (addr->resource_type == ACPI_MEMORY_RANGE ||
-                   addr->resource_type == ACPI_IO_RANGE) &&
-                   addr->address_length > 0) {
-                       return AE_OK;
-               }
-               break;
-       }
-       return AE_ERROR;
-}
-
 static acpi_status count_resource(struct acpi_resource *acpi_res, void *data)
 {
        struct pci_root_info *info = data;
        struct acpi_resource_address64 addr;
        acpi_status status;
 
-       status = resource_to_addr(acpi_res, &addr);
+       status = acpi_mem_addr_resource_to_address64(acpi_res, &addr);
        if (ACPI_SUCCESS(status))
                info->res_num++;
        return AE_OK;
@@ -285,7 +239,7 @@ static acpi_status setup_resource(struct acpi_resource 
*acpi_res, void *data)
        unsigned long flags;
        u64 start, orig_end, end;
 
-       status = resource_to_addr(acpi_res, &addr);
+       status = acpi_mem_addr_resource_to_address64(acpi_res, &addr);
        if (!ACPI_SUCCESS(status))
                return AE_OK;
 
diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c
index 0bdacc5e26a3..e91deebf0930 100644
--- a/drivers/acpi/resource.c
+++ b/drivers/acpi/resource.c
@@ -424,6 +424,52 @@ void acpi_dev_free_resource_list(struct list_head *list)
 }
 EXPORT_SYMBOL_GPL(acpi_dev_free_resource_list);
 
+acpi_status acpi_mem_addr_resource_to_address64(struct acpi_resource *resource,
+                       struct acpi_resource_address64 *addr)
+{
+       acpi_status status;
+       struct acpi_resource_memory24 *memory24;
+       struct acpi_resource_memory32 *memory32;
+       struct acpi_resource_fixed_memory32 *fixed_memory32;
+
+       memset(addr, 0, sizeof(*addr));
+       switch (resource->type) {
+       case ACPI_RESOURCE_TYPE_MEMORY24:
+               memory24 = &resource->data.memory24;
+               addr->resource_type = ACPI_MEMORY_RANGE;
+               addr->minimum = memory24->minimum;
+               addr->address_length = memory24->address_length;
+               addr->maximum = addr->minimum + addr->address_length - 1;
+               return AE_OK;
+       case ACPI_RESOURCE_TYPE_MEMORY32:
+               memory32 = &resource->data.memory32;
+               addr->resource_type = ACPI_MEMORY_RANGE;
+               addr->minimum = memory32->minimum;
+               addr->address_length = memory32->address_length;
+               addr->maximum = addr->minimum + addr->address_length - 1;
+               return AE_OK;
+       case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
+               fixed_memory32 = &resource->data.fixed_memory32;
+               addr->resource_type = ACPI_MEMORY_RANGE;
+               addr->minimum = fixed_memory32->address;
+               addr->address_length = fixed_memory32->address_length;
+               addr->maximum = addr->minimum + addr->address_length - 1;
+               return AE_OK;
+       case ACPI_RESOURCE_TYPE_ADDRESS16:
+       case ACPI_RESOURCE_TYPE_ADDRESS32:
+       case ACPI_RESOURCE_TYPE_ADDRESS64:
+               status = acpi_resource_to_address64(resource, addr);
+               if (ACPI_SUCCESS(status) &&
+                   (addr->resource_type == ACPI_MEMORY_RANGE ||
+                   addr->resource_type == ACPI_IO_RANGE) &&
+                   addr->address_length > 0) {
+                       return AE_OK;
+               }
+               break;
+       }
+       return AE_ERROR;
+}
+
 struct res_proc_context {
        struct list_head *list;
        int (*preproc)(struct acpi_resource *, void *);
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 7a8f2cd66c8b..b479e10f6621 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -286,6 +286,9 @@ unsigned long acpi_dev_irq_flags(u8 triggering, u8 
polarity, u8 shareable);
 bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index,
                                 struct resource *res);
 
+acpi_status acpi_mem_addr_resource_to_address64(struct acpi_resource *resource,
+                       struct acpi_resource_address64 *addr);
+
 struct resource_list_entry {
        struct list_head node;
        struct resource res;
-- 
1.7.10.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to