* [RFC part2 PATCH 2/9] ARM64 / ACPI: Prefill cpu possible/present maps and map logical cpu id to APIC id [not found] ` <1385999094-3152-3-git-send-email-hanjun.guo@linaro.org> @ 2013-12-10 12:53 ` Grant Likely 2013-12-10 15:07 ` Hanjun Guo 0 siblings, 1 reply; 8+ messages in thread From: Grant Likely @ 2013-12-10 12:53 UTC (permalink / raw) To: linux-arm-kernel On Mon, 2 Dec 2013 23:44:47 +0800, Hanjun Guo <hanjun.guo@linaro.org> wrote: > When boot the kernel with MADT, the cpu possible and present maps should be > prefilled for cpu topology and acpi based cpu hot-plug. > > The logic cpu id maps to APIC id (GIC id) is also implemented, it is needed > for acpi processor drivers. > > Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org> > --- [...] > diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c > index a0c2ca6..1428024 100644 > --- a/arch/arm64/kernel/smp.c > +++ b/arch/arm64/kernel/smp.c > @@ -420,7 +420,9 @@ void __init smp_prepare_cpus(unsigned int max_cpus) > if (err) > continue; > > +#ifndef CONFIG_ACPI > set_cpu_present(cpu, true); > +#endif > max_cpus--; > } > } This looks wrong. Will this break non-ACPI booting when CONFIG_ACPI is enabled? The decision on whether or not to run code must be made at runtime. g. ^ permalink raw reply [flat|nested] 8+ messages in thread
* [RFC part2 PATCH 2/9] ARM64 / ACPI: Prefill cpu possible/present maps and map logical cpu id to APIC id 2013-12-10 12:53 ` [RFC part2 PATCH 2/9] ARM64 / ACPI: Prefill cpu possible/present maps and map logical cpu id to APIC id Grant Likely @ 2013-12-10 15:07 ` Hanjun Guo 0 siblings, 0 replies; 8+ messages in thread From: Hanjun Guo @ 2013-12-10 15:07 UTC (permalink / raw) To: linux-arm-kernel On 2013?12?10? 20:53, Grant Likely wrote: > On Mon, 2 Dec 2013 23:44:47 +0800, Hanjun Guo <hanjun.guo@linaro.org> wrote: >> When boot the kernel with MADT, the cpu possible and present maps should be >> prefilled for cpu topology and acpi based cpu hot-plug. >> >> The logic cpu id maps to APIC id (GIC id) is also implemented, it is needed >> for acpi processor drivers. >> >> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org> >> --- > [...] >> diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c >> index a0c2ca6..1428024 100644 >> --- a/arch/arm64/kernel/smp.c >> +++ b/arch/arm64/kernel/smp.c >> @@ -420,7 +420,9 @@ void __init smp_prepare_cpus(unsigned int max_cpus) >> if (err) >> continue; >> >> +#ifndef CONFIG_ACPI >> set_cpu_present(cpu, true); >> +#endif >> max_cpus--; >> } >> } > This looks wrong. Will this break non-ACPI booting when CONFIG_ACPI is > enabled? The decision on whether or not to run code must be made at > runtime. Yes, you are right. I'm reworking on this patch now. Thanks Hanjun ^ permalink raw reply [flat|nested] 8+ messages in thread
[parent not found: < 1385999094-3152-5-git-send-email-hanjun.guo@linaro.org>]
[parent not found: <1385999094-3152-5-git-send-email-hanjun.guo@linaro.org>]
* [RFC part2 PATCH 4/9] ARM64 / ACPI: Use Parked Address in GIC structure for spin table SMP initialisation [not found] ` <1385999094-3152-5-git-send-email-hanjun.guo@linaro.org> @ 2013-12-10 13:03 ` Grant Likely 2013-12-11 7:02 ` Hanjun Guo 0 siblings, 1 reply; 8+ messages in thread From: Grant Likely @ 2013-12-10 13:03 UTC (permalink / raw) To: linux-arm-kernel On Mon, 2 Dec 2013 23:44:49 +0800, Hanjun Guo <hanjun.guo@linaro.org> wrote: > Parked Address in GIC structure can be used as cpu release address > for spin table SMP initialisation. > > This patch gets parked address from MADT and use it for SMP > initialisation when DT is not available. > > Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org> > --- > arch/arm64/include/asm/acpi.h | 3 +++ > arch/arm64/kernel/smp_spin_table.c | 16 +++++++++--- > drivers/acpi/plat/arm-core.c | 50 ++++++++++++++++++++++++++++++++++++ > 3 files changed, 66 insertions(+), 3 deletions(-) > > diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h > index 423a32c..180de4a 100644 > --- a/arch/arm64/include/asm/acpi.h > +++ b/arch/arm64/include/asm/acpi.h > @@ -90,6 +90,9 @@ extern int boot_cpu_apic_id; > > extern void prefill_possible_map(void); > > +extern int acpi_get_parked_address_with_gic_id(u32 gic_id, > + u64 *parked_address); > + > #else /* !CONFIG_ACPI */ > #define acpi_disabled 1 /* ACPI sometimes enabled on ARM */ > #define acpi_noirq 1 /* ACPI sometimes enabled on ARM */ > diff --git a/arch/arm64/kernel/smp_spin_table.c b/arch/arm64/kernel/smp_spin_table.c > index 44c2280..7997873 100644 > --- a/arch/arm64/kernel/smp_spin_table.c > +++ b/arch/arm64/kernel/smp_spin_table.c > @@ -25,6 +25,7 @@ > #include <asm/cpu_ops.h> > #include <asm/cputype.h> > #include <asm/smp_plat.h> > +#include <asm/acpi.h> > > extern void secondary_holding_pen(void); > volatile unsigned long secondary_holding_pen_release = INVALID_HWID; > @@ -47,6 +48,11 @@ static void write_pen_release(u64 val) > __flush_dcache_area(start, size); > } > > +static int get_cpu_release_addr_acpi(unsigned int cpu, u64 *parked_address) > +{ > + return acpi_get_parked_address_with_gic_id(arm_cpu_to_apicid[cpu], > + parked_address); > +} > > static int smp_spin_table_cpu_init(struct device_node *dn, unsigned int cpu) > { > @@ -55,10 +61,14 @@ static int smp_spin_table_cpu_init(struct device_node *dn, unsigned int cpu) > */ > if (of_property_read_u64(dn, "cpu-release-addr", > &cpu_release_addr[cpu])) { > - pr_err("CPU %d: missing or invalid cpu-release-addr property\n", > - cpu); > > - return -1; > + /* try ACPI way */ > + if (get_cpu_release_addr_acpi(cpu, &cpu_release_addr[cpu])) { > + pr_err("CPU %d: missing or invalid cpu-release-addr property\n", > + cpu); > + > + return -1; > + } > } > > return 0; > diff --git a/drivers/acpi/plat/arm-core.c b/drivers/acpi/plat/arm-core.c > index 8527ecc..c4c8c68 100644 > --- a/drivers/acpi/plat/arm-core.c > +++ b/drivers/acpi/plat/arm-core.c > @@ -262,6 +262,56 @@ static int __init acpi_parse_madt_gic_entries(void) > return 0; > } > > +/* Parked Address in ACPI GIC structure can be used as cpu release addr */ > +int acpi_get_parked_address_with_gic_id(u32 gic_id, u64 *parked_address) > +{ > + struct acpi_table_header *table_header = NULL; > + struct acpi_subtable_header *entry; > + int err = 0; > + unsigned long table_end; > + acpi_size tbl_size; > + struct acpi_madt_generic_interrupt *processor = NULL; > + > + if (!parked_address) > + return -EINVAL; > + > + acpi_get_table_with_size(ACPI_SIG_MADT, 0, &table_header, &tbl_size); > + if (!table_header) { > + pr_warn(PREFIX "MADT table not present\n"); > + return -ENODEV; > + } > + > + table_end = (unsigned long)table_header + table_header->length; > + > + /* Parse all entries looking for a match. */ > + entry = (struct acpi_subtable_header *) > + ((unsigned long)table_header + sizeof(struct acpi_table_madt)); > + > + while (((unsigned long)entry) + sizeof(struct acpi_subtable_header) < > + table_end) { > + if (entry->type != ACPI_MADT_TYPE_GENERIC_INTERRUPT > + || BAD_MADT_ENTRY(entry, table_end)) > + continue; > + > + processor = (struct acpi_madt_generic_interrupt *)entry; > + > + if (processor->gic_id == gic_id) { > + *parked_address = processor->parked_address; > + goto out; > + } > + > + entry = (struct acpi_subtable_header *) > + ((unsigned long)entry + entry->length); All of the casting in this table looks suspicious. If you have to resort to casting, then the variable types are very likely wrong. In the case immediately above, it seems that the entry size doesn't necessarily equal the acpi_subtable_header size, in which case you should cast the values to a void* instead of an unsigned long. That would mean you can do this: entry = ((void*)entry) + entry->length; In fact, if I were writing the code, I would have two variables; the iterator pointer as a void* and a header pointer as a struct acpi_subtable_header*. Like so: void *entry, *table_end; struct acpi_subtable_header *header; entry = ((void*)table_header) + sizeof(struct acpi_table_madt); table_end = ((void*)table_header) + table_header->length; while (entry + sizeof(*header)) < table_end) { header = entry; if (header->type != ACPI_MADT_TYPE_GENERIC_INTERRUPT || BAD_MADT_ENTRY(entry, table_end)) continue; processor = entry; if (processor->gic_id == gic_id) { *parked_address = processor->parked_address; goto out; } entry += header->length; } See? Much cleaner code. g. ^ permalink raw reply [flat|nested] 8+ messages in thread
* [RFC part2 PATCH 4/9] ARM64 / ACPI: Use Parked Address in GIC structure for spin table SMP initialisation 2013-12-10 13:03 ` [RFC part2 PATCH 4/9] ARM64 / ACPI: Use Parked Address in GIC structure for spin table SMP initialisation Grant Likely @ 2013-12-11 7:02 ` Hanjun Guo 0 siblings, 0 replies; 8+ messages in thread From: Hanjun Guo @ 2013-12-11 7:02 UTC (permalink / raw) To: linux-arm-kernel On 2013-12-10 21:03, Grant Likely wrote: [...] >> +/* Parked Address in ACPI GIC structure can be used as cpu release addr */ >> +int acpi_get_parked_address_with_gic_id(u32 gic_id, u64 *parked_address) >> +{ >> + struct acpi_table_header *table_header = NULL; >> + struct acpi_subtable_header *entry; >> + int err = 0; >> + unsigned long table_end; >> + acpi_size tbl_size; >> + struct acpi_madt_generic_interrupt *processor = NULL; >> + >> + if (!parked_address) >> + return -EINVAL; >> + >> + acpi_get_table_with_size(ACPI_SIG_MADT, 0, &table_header, &tbl_size); >> + if (!table_header) { >> + pr_warn(PREFIX "MADT table not present\n"); >> + return -ENODEV; >> + } >> + >> + table_end = (unsigned long)table_header + table_header->length; >> + >> + /* Parse all entries looking for a match. */ >> + entry = (struct acpi_subtable_header *) >> + ((unsigned long)table_header + sizeof(struct acpi_table_madt)); >> + >> + while (((unsigned long)entry) + sizeof(struct acpi_subtable_header) < >> + table_end) { >> + if (entry->type != ACPI_MADT_TYPE_GENERIC_INTERRUPT >> + || BAD_MADT_ENTRY(entry, table_end)) >> + continue; >> + >> + processor = (struct acpi_madt_generic_interrupt *)entry; >> + >> + if (processor->gic_id == gic_id) { >> + *parked_address = processor->parked_address; >> + goto out; >> + } >> + >> + entry = (struct acpi_subtable_header *) >> + ((unsigned long)entry + entry->length); > > All of the casting in this table looks suspicious. If you have to resort > to casting, then the variable types are very likely wrong. > > In the case immediately above, it seems that the entry size doesn't > necessarily equal the acpi_subtable_header size, in which case you > should cast the values to a void* instead of an unsigned long. That > would mean you can do this: > > entry = ((void*)entry) + entry->length; > > In fact, if I were writing the code, I would have two variables; the > iterator pointer as a void* and a header pointer as a struct > acpi_subtable_header*. Like so: > > void *entry, *table_end; > struct acpi_subtable_header *header; > > entry = ((void*)table_header) + sizeof(struct acpi_table_madt); > table_end = ((void*)table_header) + table_header->length; > while (entry + sizeof(*header)) < table_end) { > header = entry; > > if (header->type != ACPI_MADT_TYPE_GENERIC_INTERRUPT || > BAD_MADT_ENTRY(entry, table_end)) > continue; > processor = entry; > > if (processor->gic_id == gic_id) { > *parked_address = processor->parked_address; > goto out; > } > > entry += header->length; > } > > See? Much cleaner code. Aha, much much cleaner, thanks for the guidance, will rework my patch and test it. Hanjun ^ permalink raw reply [flat|nested] 8+ messages in thread
[parent not found: < 1385999094-3152-9-git-send-email-hanjun.guo@linaro.org>]
[parent not found: <1385999094-3152-9-git-send-email-hanjun.guo@linaro.org>]
* [RFC part2 PATCH 8/9] ACPI / ARM64: Update acpi_register_gsi to register with the core IRQ subsystem [not found] ` <1385999094-3152-9-git-send-email-hanjun.guo@linaro.org> @ 2013-12-10 13:05 ` Grant Likely 2013-12-11 5:23 ` Arnd Bergmann 0 siblings, 1 reply; 8+ messages in thread From: Grant Likely @ 2013-12-10 13:05 UTC (permalink / raw) To: linux-arm-kernel On Mon, 2 Dec 2013 23:44:53 +0800, Hanjun Guo <hanjun.guo@linaro.org> wrote: > This API is similar to DT based irq_of_parse_and_map but does link > parent/child IRQ controllers. This is tested for primary GIC PPI and GIC SPI > interrupts and not for secondary child irq controllers. > > Signed-off-by: Amit Daniel Kachhap <amit.daniel@samsung.com> > Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org> > --- > drivers/acpi/plat/arm-core.c | 36 ++++++++++++++++++++++++++++++++++-- > 1 file changed, 34 insertions(+), 2 deletions(-) > > diff --git a/drivers/acpi/plat/arm-core.c b/drivers/acpi/plat/arm-core.c > index 9cc0208..17c99e1 100644 > --- a/drivers/acpi/plat/arm-core.c > +++ b/drivers/acpi/plat/arm-core.c > @@ -90,7 +90,7 @@ enum acpi_irq_model_id acpi_irq_model = ACPI_IRQ_MODEL_GIC; > > static unsigned int gsi_to_irq(unsigned int gsi) > { > - int irq = irq_create_mapping(NULL, gsi); > + int irq = irq_find_mapping(NULL, gsi); I suspect this will break FDT users that depend on the old behaviour. g. > > return irq; > } > @@ -407,7 +407,39 @@ EXPORT_SYMBOL_GPL(acpi_gsi_to_irq); > */ > int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity) > { > - return -1; > + unsigned int irq; > + unsigned int irq_type; > + > + /* > + * ACPI have no bindings to indicate SPI or PPI, so we > + * use different mappings from DT in ACPI. > + * > + * For FDT > + * PPI interrupt: in the range [0, 15]; > + * SPI interrupt: in the range [0, 987]; > + * > + * For ACPI, using identity mapping for hwirq: > + * PPI interrupt: in the range [16, 31]; > + * SPI interrupt: in the range [32, 1019]; > + */ > + > + if (trigger == ACPI_EDGE_SENSITIVE && > + polarity == ACPI_ACTIVE_LOW) > + irq_type = IRQ_TYPE_EDGE_FALLING; > + else if (trigger == ACPI_EDGE_SENSITIVE && > + polarity == ACPI_ACTIVE_HIGH) > + irq_type = IRQ_TYPE_EDGE_RISING; > + else if (trigger == ACPI_LEVEL_SENSITIVE && > + polarity == ACPI_ACTIVE_LOW) > + irq_type = IRQ_TYPE_LEVEL_LOW; > + else if (trigger == ACPI_LEVEL_SENSITIVE && > + polarity == ACPI_ACTIVE_HIGH) > + irq_type = IRQ_TYPE_LEVEL_HIGH; > + else > + irq_type = IRQ_TYPE_NONE; > + > + irq = irq_create_acpi_mapping(gsi, irq_type); > + return irq; > } > EXPORT_SYMBOL_GPL(acpi_register_gsi); > > -- > 1.7.9.5 > > > _______________________________________________ > linaro-kernel mailing list > linaro-kernel at lists.linaro.org > http://lists.linaro.org/mailman/listinfo/linaro-kernel ^ permalink raw reply [flat|nested] 8+ messages in thread
* [RFC part2 PATCH 8/9] ACPI / ARM64: Update acpi_register_gsi to register with the core IRQ subsystem 2013-12-10 13:05 ` [RFC part2 PATCH 8/9] ACPI / ARM64: Update acpi_register_gsi to register with the core IRQ subsystem Grant Likely @ 2013-12-11 5:23 ` Arnd Bergmann 2014-01-20 14:36 ` Grant Likely 0 siblings, 1 reply; 8+ messages in thread From: Arnd Bergmann @ 2013-12-11 5:23 UTC (permalink / raw) To: linux-arm-kernel On Tuesday 10 December 2013, Grant Likely wrote: > > --- a/drivers/acpi/plat/arm-core.c > > +++ b/drivers/acpi/plat/arm-core.c > > @@ -90,7 +90,7 @@ enum acpi_irq_model_id acpi_irq_model = ACPI_IRQ_MODEL_GIC; > > > > static unsigned int gsi_to_irq(unsigned int gsi) > > { > > - int irq = irq_create_mapping(NULL, gsi); > > + int irq = irq_find_mapping(NULL, gsi); > > I suspect this will break FDT users that depend on the old behaviour. I think not, given this is only in drivers/acpi and gets added in one of the prior patches of the same series. Arnd ^ permalink raw reply [flat|nested] 8+ messages in thread
* [RFC part2 PATCH 8/9] ACPI / ARM64: Update acpi_register_gsi to register with the core IRQ subsystem 2013-12-11 5:23 ` Arnd Bergmann @ 2014-01-20 14:36 ` Grant Likely 0 siblings, 0 replies; 8+ messages in thread From: Grant Likely @ 2014-01-20 14:36 UTC (permalink / raw) To: linux-arm-kernel On Wed, 11 Dec 2013 06:23:04 +0100, Arnd Bergmann <arnd@arndb.de> wrote: > On Tuesday 10 December 2013, Grant Likely wrote: > > > --- a/drivers/acpi/plat/arm-core.c > > > +++ b/drivers/acpi/plat/arm-core.c > > > @@ -90,7 +90,7 @@ enum acpi_irq_model_id acpi_irq_model = ACPI_IRQ_MODEL_GIC; > > > > > > static unsigned int gsi_to_irq(unsigned int gsi) > > > { > > > - int irq = irq_create_mapping(NULL, gsi); > > > + int irq = irq_find_mapping(NULL, gsi); > > > > I suspect this will break FDT users that depend on the old behaviour. > > I think not, given this is only in drivers/acpi and gets added in one > of the prior patches of the same series. Ah, okay. g. ^ permalink raw reply [flat|nested] 8+ messages in thread
* [RFC part2 PATCH 0/9] Using ACPI MADT table to initialise SMP and GIC @ 2013-12-03 16:39 Hanjun Guo 2013-12-03 16:39 ` [RFC part2 PATCH 4/9] ARM64 / ACPI: Use Parked Address in GIC structure for spin table SMP initialisation Hanjun Guo 0 siblings, 1 reply; 8+ messages in thread From: Hanjun Guo @ 2013-12-03 16:39 UTC (permalink / raw) To: linux-arm-kernel This patch set is based on part1 "Make ACPI core running on ARM64" patch set. After we can get the ACPI tables from UEFI, we can use these tables to initialise the system now. GIC (means GIC cpu interface) structure and GIC distributor structure in MADT table contains the information of GIC cpu interface base address and GIC distributor base address, which can be used to initialise GIC. Further more, parked address in GIC structure can be used as cpu release address for spin table SMP initialisation. This patch set use these information to init SMP and GIC. Please refer to chapter 5.2.12.14/15 of ACPI 5.0 spec for GIC and GIC distributor structure information. Amit Daniel Kachhap (1): irqdomain: Add a new API irq_create_acpi_mapping() Hanjun Guo (8): ARM64 / ACPI: Implement core functions for parsing MADT table ARM64 / ACPI: Prefill cpu possible/present maps and map logical cpu id to APIC id ARM64 / ACPI: Introduce map_gic_id() to get apic id from MADT or _MAT method ARM64 / ACPI: Use Parked Address in GIC structure for spin table SMP initialisation ACPI: Define ACPI_IRQ_MODEL_GIC needed for arm Irqchip / gic: Set as default domain so we can access from ACPI ACPI / ARM64: Update acpi_register_gsi to register with the core IRQ subsystem ACPI / GIC: Initialize GIC using the information in MADT arch/arm64/include/asm/acpi.h | 16 +- arch/arm64/kernel/irq.c | 5 + arch/arm64/kernel/setup.c | 2 + arch/arm64/kernel/smp.c | 2 + arch/arm64/kernel/smp_spin_table.c | 16 +- drivers/acpi/bus.c | 3 + drivers/acpi/plat/arm-core.c | 397 +++++++++++++++++++++++++++++++++++- drivers/acpi/processor_core.c | 26 +++ drivers/acpi/tables.c | 21 ++ drivers/irqchip/irq-gic.c | 7 + include/linux/acpi.h | 9 + kernel/irq/irqdomain.c | 27 +++ 12 files changed, 521 insertions(+), 10 deletions(-) -- 1.7.9.5 ^ permalink raw reply [flat|nested] 8+ messages in thread
* [RFC part2 PATCH 4/9] ARM64 / ACPI: Use Parked Address in GIC structure for spin table SMP initialisation 2013-12-03 16:39 [RFC part2 PATCH 0/9] Using ACPI MADT table to initialise SMP and GIC Hanjun Guo @ 2013-12-03 16:39 ` Hanjun Guo 0 siblings, 0 replies; 8+ messages in thread From: Hanjun Guo @ 2013-12-03 16:39 UTC (permalink / raw) To: linux-arm-kernel Parked Address in GIC structure can be used as cpu release address for spin table SMP initialisation. This patch gets parked address from MADT and use it for SMP initialisation when DT is not available. Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org> --- arch/arm64/include/asm/acpi.h | 3 +++ arch/arm64/kernel/smp_spin_table.c | 16 +++++++++--- drivers/acpi/plat/arm-core.c | 50 ++++++++++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+), 3 deletions(-) diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h index 423a32c..180de4a 100644 --- a/arch/arm64/include/asm/acpi.h +++ b/arch/arm64/include/asm/acpi.h @@ -90,6 +90,9 @@ extern int boot_cpu_apic_id; extern void prefill_possible_map(void); +extern int acpi_get_parked_address_with_gic_id(u32 gic_id, + u64 *parked_address); + #else /* !CONFIG_ACPI */ #define acpi_disabled 1 /* ACPI sometimes enabled on ARM */ #define acpi_noirq 1 /* ACPI sometimes enabled on ARM */ diff --git a/arch/arm64/kernel/smp_spin_table.c b/arch/arm64/kernel/smp_spin_table.c index 44c2280..7997873 100644 --- a/arch/arm64/kernel/smp_spin_table.c +++ b/arch/arm64/kernel/smp_spin_table.c @@ -25,6 +25,7 @@ #include <asm/cpu_ops.h> #include <asm/cputype.h> #include <asm/smp_plat.h> +#include <asm/acpi.h> extern void secondary_holding_pen(void); volatile unsigned long secondary_holding_pen_release = INVALID_HWID; @@ -47,6 +48,11 @@ static void write_pen_release(u64 val) __flush_dcache_area(start, size); } +static int get_cpu_release_addr_acpi(unsigned int cpu, u64 *parked_address) +{ + return acpi_get_parked_address_with_gic_id(arm_cpu_to_apicid[cpu], + parked_address); +} static int smp_spin_table_cpu_init(struct device_node *dn, unsigned int cpu) { @@ -55,10 +61,14 @@ static int smp_spin_table_cpu_init(struct device_node *dn, unsigned int cpu) */ if (of_property_read_u64(dn, "cpu-release-addr", &cpu_release_addr[cpu])) { - pr_err("CPU %d: missing or invalid cpu-release-addr property\n", - cpu); - return -1; + /* try ACPI way */ + if (get_cpu_release_addr_acpi(cpu, &cpu_release_addr[cpu])) { + pr_err("CPU %d: missing or invalid cpu-release-addr property\n", + cpu); + + return -1; + } } return 0; diff --git a/drivers/acpi/plat/arm-core.c b/drivers/acpi/plat/arm-core.c index 8527ecc..c4c8c68 100644 --- a/drivers/acpi/plat/arm-core.c +++ b/drivers/acpi/plat/arm-core.c @@ -262,6 +262,56 @@ static int __init acpi_parse_madt_gic_entries(void) return 0; } +/* Parked Address in ACPI GIC structure can be used as cpu release addr */ +int acpi_get_parked_address_with_gic_id(u32 gic_id, u64 *parked_address) +{ + struct acpi_table_header *table_header = NULL; + struct acpi_subtable_header *entry; + int err = 0; + unsigned long table_end; + acpi_size tbl_size; + struct acpi_madt_generic_interrupt *processor = NULL; + + if (!parked_address) + return -EINVAL; + + acpi_get_table_with_size(ACPI_SIG_MADT, 0, &table_header, &tbl_size); + if (!table_header) { + pr_warn(PREFIX "MADT table not present\n"); + return -ENODEV; + } + + table_end = (unsigned long)table_header + table_header->length; + + /* Parse all entries looking for a match. */ + entry = (struct acpi_subtable_header *) + ((unsigned long)table_header + sizeof(struct acpi_table_madt)); + + while (((unsigned long)entry) + sizeof(struct acpi_subtable_header) < + table_end) { + if (entry->type != ACPI_MADT_TYPE_GENERIC_INTERRUPT + || BAD_MADT_ENTRY(entry, table_end)) + continue; + + processor = (struct acpi_madt_generic_interrupt *)entry; + + if (processor->gic_id == gic_id) { + *parked_address = processor->parked_address; + goto out; + } + + entry = (struct acpi_subtable_header *) + ((unsigned long)entry + entry->length); + } + + err = -ENODEV; +out: + if (!acpi_gbl_permanent_mmap) + __acpi_unmap_table((char *)table_header, tbl_size); + + return err; +} + /* * Parse GIC distributor related entries in MADT * returns 0 on success, < 0 on error -- 1.7.9.5 ^ permalink raw reply related [flat|nested] 8+ messages in thread
end of thread, other threads:[~2014-01-20 14:36 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- [not found] <1385999094-3152-1-git-send-email-hanjun.guo@linaro.org> [not found] ` < 1385999094-3152-3-git-send-email-hanjun.guo@linaro.org> [not found] ` <1385999094-3152-3-git-send-email-hanjun.guo@linaro.org> 2013-12-10 12:53 ` [RFC part2 PATCH 2/9] ARM64 / ACPI: Prefill cpu possible/present maps and map logical cpu id to APIC id Grant Likely 2013-12-10 15:07 ` Hanjun Guo [not found] ` < 1385999094-3152-5-git-send-email-hanjun.guo@linaro.org> [not found] ` <1385999094-3152-5-git-send-email-hanjun.guo@linaro.org> 2013-12-10 13:03 ` [RFC part2 PATCH 4/9] ARM64 / ACPI: Use Parked Address in GIC structure for spin table SMP initialisation Grant Likely 2013-12-11 7:02 ` Hanjun Guo [not found] ` < 1385999094-3152-9-git-send-email-hanjun.guo@linaro.org> [not found] ` <1385999094-3152-9-git-send-email-hanjun.guo@linaro.org> 2013-12-10 13:05 ` [RFC part2 PATCH 8/9] ACPI / ARM64: Update acpi_register_gsi to register with the core IRQ subsystem Grant Likely 2013-12-11 5:23 ` Arnd Bergmann 2014-01-20 14:36 ` Grant Likely 2013-12-03 16:39 [RFC part2 PATCH 0/9] Using ACPI MADT table to initialise SMP and GIC Hanjun Guo 2013-12-03 16:39 ` [RFC part2 PATCH 4/9] ARM64 / ACPI: Use Parked Address in GIC structure for spin table SMP initialisation Hanjun Guo
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).