Single item array is only supported to verify that original
logic is not changed.
Update for many item array support is to be added in next patch.

Signed-off-by: Lukasz Anaczkowski <lukasz.anaczkow...@intel.com>
---
 arch/x86/kernel/acpi/boot.c | 36 ++++++++++++++++++++++++++++--------
 drivers/acpi/numa.c         | 13 ++++++++++---
 drivers/acpi/tables.c       | 40 +++++++++++++++++++++++++---------------
 drivers/irqchip/irq-gic.c   | 15 +++++++++++----
 include/linux/acpi.h        | 13 +++++++++----
 5 files changed, 83 insertions(+), 34 deletions(-)

diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index e49ee24..21cb7a0 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -981,6 +981,7 @@ static int __init acpi_parse_madt_lapic_entries(void)
 {
        int count;
        int x2count = 0;
+       struct acpi_subtable_proc madt_proc[1];
 
        if (!cpu_has_apic)
                return -ENODEV;
@@ -1004,10 +1005,19 @@ static int __init acpi_parse_madt_lapic_entries(void)
                                      acpi_parse_sapic, MAX_LOCAL_APIC);
 
        if (!count) {
-               x2count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_X2APIC,
-                                       acpi_parse_x2apic, MAX_LOCAL_APIC);
-               count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC,
-                                       acpi_parse_lapic, MAX_LOCAL_APIC);
+               memset(madt_proc, 0, sizeof(madt_proc));
+               madt_proc[0].id = ACPI_MADT_TYPE_LOCAL_X2APIC;
+               madt_proc[0].handler = acpi_parse_x2apic;
+               x2count = acpi_table_parse_entries_array(ACPI_SIG_MADT,
+                                               sizeof(struct acpi_table_madt),
+                                               madt_proc, 
ARRAY_SIZE(madt_proc), MAX_LOCAL_APIC);
+
+               memset(madt_proc, 0, sizeof(madt_proc));
+               madt_proc[0].id = ACPI_MADT_TYPE_LOCAL_APIC;
+               madt_proc[0].handler = acpi_parse_lapic;
+               count = acpi_table_parse_entries_array(ACPI_SIG_MADT,
+                               sizeof(struct acpi_table_madt),
+                               madt_proc, ARRAY_SIZE(madt_proc), 
MAX_LOCAL_APIC);
        }
        if (!count && !x2count) {
                printk(KERN_ERR PREFIX "No LAPIC entries present\n");
@@ -1019,10 +1029,20 @@ static int __init acpi_parse_madt_lapic_entries(void)
                return count;
        }
 
-       x2count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_X2APIC_NMI,
-                                       acpi_parse_x2apic_nmi, 0);
-       count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC_NMI,
-                                     acpi_parse_lapic_nmi, 0);
+       memset(madt_proc, 0, sizeof(madt_proc));
+       madt_proc[0].id = ACPI_MADT_TYPE_LOCAL_X2APIC_NMI;
+       madt_proc[0].handler = acpi_parse_x2apic_nmi;
+       count = acpi_table_parse_entries_array(ACPI_SIG_MADT,
+                       sizeof(struct acpi_table_madt),
+                       madt_proc, ARRAY_SIZE(madt_proc), 0);
+
+       memset(madt_proc, 0, sizeof(madt_proc));
+       madt_proc[0].id = ACPI_MADT_TYPE_LOCAL_APIC_NMI;
+       madt_proc[0].handler = acpi_parse_lapic_nmi;
+       x2count = acpi_table_parse_entries_array(ACPI_SIG_MADT,
+                       sizeof(struct acpi_table_madt),
+                       madt_proc, ARRAY_SIZE(madt_proc), 0);
+
        if (count < 0 || x2count < 0) {
                printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n");
                /* TBD: Cleanup to allow fallback to MPS */
diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c
index acaa3b4..f3ccc68 100644
--- a/drivers/acpi/numa.c
+++ b/drivers/acpi/numa.c
@@ -314,9 +314,15 @@ static int __init
 acpi_table_parse_srat(enum acpi_srat_type id,
                      acpi_tbl_entry_handler handler, unsigned int max_entries)
 {
-       return acpi_table_parse_entries(ACPI_SIG_SRAT,
-                                           sizeof(struct acpi_table_srat), id,
-                                           handler, max_entries);
+       struct acpi_subtable_proc srat_proc;
+
+       memset(&srat_proc, 0, sizeof(srat_proc));
+       srat_proc.id = id;
+       srat_proc.handler = handler;
+
+       return acpi_table_parse_entries_array(ACPI_SIG_SRAT,
+                               sizeof(struct acpi_table_srat),
+                               &srat_proc, 1, max_entries);
 }
 
 int __init acpi_numa_init(void)
@@ -335,6 +341,7 @@ int __init acpi_numa_init(void)
                                     acpi_parse_x2apic_affinity, 0);
                acpi_table_parse_srat(ACPI_SRAT_TYPE_CPU_AFFINITY,
                                     acpi_parse_processor_affinity, 0);
+
                cnt = acpi_table_parse_srat(ACPI_SRAT_TYPE_MEMORY_AFFINITY,
                                            acpi_parse_memory_affinity,
                                            NR_NODE_MEMBLKS);
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
index aa8bcc6..33539ee 100644
--- a/drivers/acpi/tables.c
+++ b/drivers/acpi/tables.c
@@ -216,9 +216,9 @@ void acpi_table_print_madt_entry(struct 
acpi_subtable_header *header)
 
 int __init
 acpi_parse_entries(char *id, unsigned long table_size,
-               acpi_tbl_entry_handler handler,
                struct acpi_table_header *table_header,
-               int entry_id, unsigned int max_entries)
+               struct acpi_subtable_proc *proc, int proc_num,
+               unsigned int max_entries)
 {
        struct acpi_subtable_header *entry;
        int count = 0;
@@ -227,7 +227,7 @@ acpi_parse_entries(char *id, unsigned long table_size,
        if (acpi_disabled)
                return -ENODEV;
 
-       if (!id || !handler)
+       if (!id)
                return -EINVAL;
 
        if (!table_size)
@@ -247,12 +247,12 @@ acpi_parse_entries(char *id, unsigned long table_size,
 
        while (((unsigned long)entry) + sizeof(struct acpi_subtable_header) <
               table_end) {
-               if (entry->type == entry_id
+               if (entry->type == proc->id
                    && (!max_entries || count < max_entries)) {
-                       if (handler(entry, table_end))
+                       if (!proc->handler || proc->handler(entry, table_end))
                                return -EINVAL;
 
-                       count++;
+                       proc->count++;
                }
 
                /*
@@ -260,7 +260,7 @@ acpi_parse_entries(char *id, unsigned long table_size,
                 * infinite loop.
                 */
                if (entry->length == 0) {
-                       pr_err("[%4.4s:0x%02x] Invalid zero length\n", id, 
entry_id);
+                       pr_err("[%4.4s:0x%02x] Invalid zero length\n", id, 
proc->id);
                        return -EINVAL;
                }
 
@@ -268,9 +268,11 @@ acpi_parse_entries(char *id, unsigned long table_size,
                    ((unsigned long)entry + entry->length);
        }
 
+       count = proc->count;
+
        if (max_entries && count > max_entries) {
                pr_warn("[%4.4s:0x%02x] ignored %i entries of %i found\n",
-                       id, entry_id, count - max_entries, count);
+                       id, proc->id, count - max_entries, count);
        }
 
        return count;
@@ -279,8 +281,7 @@ acpi_parse_entries(char *id, unsigned long table_size,
 int __init
 acpi_table_parse_entries_array(char *id,
                         unsigned long table_size,
-                        int entry_id,
-                        acpi_tbl_entry_handler handler,
+                        struct acpi_subtable_proc *proc, int proc_num,
                         unsigned int max_entries)
 {
        struct acpi_table_header *table_header = NULL;
@@ -291,7 +292,7 @@ acpi_table_parse_entries_array(char *id,
        if (acpi_disabled)
                return -ENODEV;
 
-       if (!id || !handler)
+       if (!id)
                return -EINVAL;
 
        if (!strncmp(id, ACPI_SIG_MADT, 4))
@@ -303,8 +304,8 @@ acpi_table_parse_entries_array(char *id,
                return -ENODEV;
        }
 
-       count = acpi_parse_entries(id, table_size, handler, table_header,
-                       entry_id, max_entries);
+       count = acpi_parse_entries(id, table_size, table_header,
+                       proc, proc_num, max_entries);
 
        early_acpi_os_unmap_memory((char *)table_header, tbl_size);
        return count;
@@ -317,8 +318,17 @@ acpi_table_parse_entries(char *id,
                        acpi_tbl_entry_handler handler,
                        unsigned int max_entries)
 {
-       return acpi_table_parse_entries_array(id, table_size, entry_id,
-                                               handler, max_entries);
+       struct acpi_subtable_proc proc[1];
+
+       if (!handler)
+               return -EINVAL;
+
+       memset(proc, 0, sizeof(proc));
+       proc[0].id = entry_id;
+       proc[0].handler = handler;
+
+       return acpi_table_parse_entries_array(id, table_size, proc, 1,
+                                               max_entries);
 }
 
 int __init
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index 4dd8826..581336c 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -1091,12 +1091,16 @@ gic_v2_acpi_init(struct acpi_table_header *table)
 {
        void __iomem *cpu_base, *dist_base;
        int count;
+       struct acpi_subtable_proc gic_proc[1];
+
+       memset(gic_proc, 0, sizeof(gic_proc));
+       gic_proc[0].id = ACPI_MADT_TYPE_GENERIC_INTERRUPT;
+       gic_proc[0].handler = gic_acpi_parse_madt_cpu;
 
        /* Collect CPU base addresses */
        count = acpi_parse_entries(ACPI_SIG_MADT,
                                   sizeof(struct acpi_table_madt),
-                                  gic_acpi_parse_madt_cpu, table,
-                                  ACPI_MADT_TYPE_GENERIC_INTERRUPT, 0);
+                                  table, gic_proc, 1, 0);
        if (count <= 0) {
                pr_err("No valid GICC entries exist\n");
                return -EINVAL;
@@ -1106,10 +1110,13 @@ gic_v2_acpi_init(struct acpi_table_header *table)
         * Find distributor base address. We expect one distributor entry since
         * ACPI 5.1 spec neither support multi-GIC instances nor GIC cascade.
         */
+       memset(gic_proc, 0, sizeof(gic_proc));
+       gic_proc[0].id = ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR;
+       gic_proc[0].handler = gic_acpi_parse_madt_distributor;
+
        count = acpi_parse_entries(ACPI_SIG_MADT,
                                   sizeof(struct acpi_table_madt),
-                                  gic_acpi_parse_madt_distributor, table,
-                                  ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR, 0);
+                                  table, gic_proc, 1, 0);
        if (count <= 0) {
                pr_err("No valid GICD entries exist\n");
                return -EINVAL;
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 07fd1d1..52c8d20 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -135,6 +135,12 @@ static inline void acpi_initrd_override(void *data, size_t 
size)
                (!entry) || (unsigned long)entry + sizeof(*entry) > end ||  \
                ((struct acpi_subtable_header *)entry)->length < sizeof(*entry))
 
+struct acpi_subtable_proc {
+       int id;
+       acpi_tbl_entry_handler handler;
+       int count;
+};
+
 char * __acpi_map_table (unsigned long phys_addr, unsigned long size);
 void __acpi_unmap_table(char *map, unsigned long size);
 int early_acpi_boot_init(void);
@@ -146,16 +152,15 @@ int acpi_numa_init (void);
 int acpi_table_init (void);
 int acpi_table_parse(char *id, acpi_tbl_table_handler handler);
 int __init acpi_parse_entries(char *id, unsigned long table_size,
-                             acpi_tbl_entry_handler handler,
                              struct acpi_table_header *table_header,
-                             int entry_id, unsigned int max_entries);
+                             struct acpi_subtable_proc *proc, int proc_num,
+                             unsigned int max_entries);
 int __init acpi_table_parse_entries(char *id, unsigned long table_size,
                                    int entry_id,
                                    acpi_tbl_entry_handler handler,
                                    unsigned int max_entries);
 int __init acpi_table_parse_entries_array(char *id, unsigned long table_size,
-                                   int entry_id,
-                                   acpi_tbl_entry_handler handler,
+                                   struct acpi_subtable_proc *proc, int 
proc_num,
                                    unsigned int max_entries);
 int acpi_table_parse_madt(enum acpi_madt_type id,
                          acpi_tbl_entry_handler handler,
-- 
1.8.3.1

--
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