Message ID | 1442152943-24493-4-git-send-email-marc.zyngier@arm.com (mailing list archive) |
---|---|
State | Superseded, archived |
Headers | show |
Hi Marc, On 09/13/2015 10:02 PM, Marc Zyngier wrote: [...] > diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c > index e6b7ed5..8a0b9c3 100644 > --- a/drivers/irqchip/irq-gic.c > +++ b/drivers/irqchip/irq-gic.c > @@ -41,7 +41,6 @@ > #include <linux/irqchip.h> > #include <linux/irqchip/chained_irq.h> > #include <linux/irqchip/arm-gic.h> > -#include <linux/irqchip/arm-gic-acpi.h> > > #include <asm/cputype.h> > #include <asm/irq.h> > @@ -1177,7 +1176,7 @@ IRQCHIP_DECLARE(msm_qgic2, "qcom,msm-qgic2", gic_of_init); > #endif > > #ifdef CONFIG_ACPI > -static phys_addr_t dist_phy_base, cpu_phy_base __initdata; > +static phys_addr_t cpu_phy_base __initdata; > > static int __init > gic_acpi_parse_madt_cpu(struct acpi_subtable_header *header, > @@ -1205,60 +1204,56 @@ gic_acpi_parse_madt_cpu(struct acpi_subtable_header *header, > return 0; > } > > -static int __init > -gic_acpi_parse_madt_distributor(struct acpi_subtable_header *header, > - const unsigned long end) > +/* The things you have to do to just *count* something... */ > +static int __init acpi_dummy_func(struct acpi_subtable_header *header, > + const unsigned long end) > { > - struct acpi_madt_generic_distributor *dist; > + return 0; > +} > > - dist = (struct acpi_madt_generic_distributor *)header; > +static bool __init acpi_gic_redist_is_present(void) > +{ > + return acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR, > + acpi_dummy_func, 0) > 0; > +} > > - if (BAD_MADT_ENTRY(dist, end)) > - return -EINVAL; > +static bool __init gic_validate_dist(struct acpi_subtable_header *header, > + struct acpi_probe_entry *ape) > +{ > + struct acpi_madt_generic_distributor *dist; > + dist = (struct acpi_madt_generic_distributor *)header; > > - dist_phy_base = dist->base_address; > - return 0; > + return (dist->version == ape->driver_data && > + (dist->version != ACPI_MADT_GIC_VERSION_NONE || > + !acpi_gic_redist_is_present())); > When I was rebasing the GICv3 patches on top of yours, I noticed that GICv3 will also needs to check the acpi_gic_redist_is_present(), can we move the code above to some common place, or just leave the code duplicate but self-contained? Thanks Hanjun -- To unsubscribe from this list: send the line "unsubscribe linux-acpi" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Hi Marc, On 09/13/2015 10:02 PM, Marc Zyngier wrote: [...] > diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c > index e6b7ed5..8a0b9c3 100644 > --- a/drivers/irqchip/irq-gic.c > +++ b/drivers/irqchip/irq-gic.c > @@ -41,7 +41,6 @@ > #include <linux/irqchip.h> > #include <linux/irqchip/chained_irq.h> > #include <linux/irqchip/arm-gic.h> > -#include <linux/irqchip/arm-gic-acpi.h> > > #include <asm/cputype.h> > #include <asm/irq.h> > @@ -1177,7 +1176,7 @@ IRQCHIP_DECLARE(msm_qgic2, "qcom,msm-qgic2", gic_of_init); > #endif > > #ifdef CONFIG_ACPI > -static phys_addr_t dist_phy_base, cpu_phy_base __initdata; > +static phys_addr_t cpu_phy_base __initdata; > > static int __init > gic_acpi_parse_madt_cpu(struct acpi_subtable_header *header, > @@ -1205,60 +1204,56 @@ gic_acpi_parse_madt_cpu(struct acpi_subtable_header *header, > return 0; > } > > -static int __init > -gic_acpi_parse_madt_distributor(struct acpi_subtable_header *header, > - const unsigned long end) > +/* The things you have to do to just *count* something... */ > +static int __init acpi_dummy_func(struct acpi_subtable_header *header, > + const unsigned long end) > { > - struct acpi_madt_generic_distributor *dist; > + return 0; > +} > > - dist = (struct acpi_madt_generic_distributor *)header; > +static bool __init acpi_gic_redist_is_present(void) > +{ > + return acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR, > + acpi_dummy_func, 0) > 0; > +} > > - if (BAD_MADT_ENTRY(dist, end)) > - return -EINVAL; > +static bool __init gic_validate_dist(struct acpi_subtable_header *header, > + struct acpi_probe_entry *ape) > +{ > + struct acpi_madt_generic_distributor *dist; > + dist = (struct acpi_madt_generic_distributor *)header; > > - dist_phy_base = dist->base_address; > - return 0; > + return (dist->version == ape->driver_data && > + (dist->version != ACPI_MADT_GIC_VERSION_NONE || > + !acpi_gic_redist_is_present())); > When I was rebasing the GICv3 patches on top of yours, I noticed that GICv3 will also needs to check the acpi_gic_redist_is_present(), can we move the code above to some common place, or just leave the code duplicate but self-contained? Thanks Hanjun -- To unsubscribe from this list: send the line "unsubscribe linux-acpi" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On 16/09/15 16:05, Hanjun Guo wrote: > Hi Marc, > > On 09/13/2015 10:02 PM, Marc Zyngier wrote: > [...] >> diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c >> index e6b7ed5..8a0b9c3 100644 >> --- a/drivers/irqchip/irq-gic.c >> +++ b/drivers/irqchip/irq-gic.c >> @@ -41,7 +41,6 @@ >> #include <linux/irqchip.h> >> #include <linux/irqchip/chained_irq.h> >> #include <linux/irqchip/arm-gic.h> >> -#include <linux/irqchip/arm-gic-acpi.h> >> >> #include <asm/cputype.h> >> #include <asm/irq.h> >> @@ -1177,7 +1176,7 @@ IRQCHIP_DECLARE(msm_qgic2, "qcom,msm-qgic2", gic_of_init); >> #endif >> >> #ifdef CONFIG_ACPI >> -static phys_addr_t dist_phy_base, cpu_phy_base __initdata; >> +static phys_addr_t cpu_phy_base __initdata; >> >> static int __init >> gic_acpi_parse_madt_cpu(struct acpi_subtable_header *header, >> @@ -1205,60 +1204,56 @@ gic_acpi_parse_madt_cpu(struct acpi_subtable_header *header, >> return 0; >> } >> >> -static int __init >> -gic_acpi_parse_madt_distributor(struct acpi_subtable_header *header, >> - const unsigned long end) >> +/* The things you have to do to just *count* something... */ >> +static int __init acpi_dummy_func(struct acpi_subtable_header *header, >> + const unsigned long end) >> { >> - struct acpi_madt_generic_distributor *dist; >> + return 0; >> +} >> >> - dist = (struct acpi_madt_generic_distributor *)header; >> +static bool __init acpi_gic_redist_is_present(void) >> +{ >> + return acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR, >> + acpi_dummy_func, 0) > 0; >> +} >> >> - if (BAD_MADT_ENTRY(dist, end)) >> - return -EINVAL; >> +static bool __init gic_validate_dist(struct acpi_subtable_header *header, >> + struct acpi_probe_entry *ape) >> +{ >> + struct acpi_madt_generic_distributor *dist; >> + dist = (struct acpi_madt_generic_distributor *)header; >> >> - dist_phy_base = dist->base_address; >> - return 0; >> + return (dist->version == ape->driver_data && >> + (dist->version != ACPI_MADT_GIC_VERSION_NONE || >> + !acpi_gic_redist_is_present())); >> > > When I was rebasing the GICv3 patches on top of yours, I noticed > that GICv3 will also needs to check the acpi_gic_redist_is_present(), > can we move the code above to some common place, or just leave > the code duplicate but self-contained? Please keep it self-contained so far. We can "optimize" later. Thanks, M.
diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h index 208cec0..6894205 100644 --- a/arch/arm64/include/asm/acpi.h +++ b/arch/arm64/include/asm/acpi.h @@ -12,7 +12,6 @@ #ifndef _ASM_ACPI_H #define _ASM_ACPI_H -#include <linux/irqchip/arm-gic-acpi.h> #include <linux/mm.h> #include <linux/psci.h> diff --git a/arch/arm64/include/asm/irq.h b/arch/arm64/include/asm/irq.h index 1a1037a..94c5367 100644 --- a/arch/arm64/include/asm/irq.h +++ b/arch/arm64/include/asm/irq.h @@ -1,8 +1,6 @@ #ifndef __ASM_IRQ_H #define __ASM_IRQ_H -#include <linux/irqchip/arm-gic-acpi.h> - #include <asm-generic/irq.h> struct pt_regs; diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c index 19de753..d6463bb 100644 --- a/arch/arm64/kernel/acpi.c +++ b/arch/arm64/kernel/acpi.c @@ -205,28 +205,3 @@ void __init acpi_boot_table_init(void) disable_acpi(); } } - -void __init acpi_gic_init(void) -{ - struct acpi_table_header *table; - acpi_status status; - acpi_size tbl_size; - int err; - - if (acpi_disabled) - return; - - status = acpi_get_table_with_size(ACPI_SIG_MADT, 0, &table, &tbl_size); - if (ACPI_FAILURE(status)) { - const char *msg = acpi_format_exception(status); - - pr_err("Failed to get MADT table, %s\n", msg); - return; - } - - err = gic_v2_acpi_init(table); - if (err) - pr_err("Failed to initialize GIC IRQ controller"); - - early_acpi_os_unmap_memory((char *)table, tbl_size); -} diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index e6b7ed5..8a0b9c3 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -41,7 +41,6 @@ #include <linux/irqchip.h> #include <linux/irqchip/chained_irq.h> #include <linux/irqchip/arm-gic.h> -#include <linux/irqchip/arm-gic-acpi.h> #include <asm/cputype.h> #include <asm/irq.h> @@ -1177,7 +1176,7 @@ IRQCHIP_DECLARE(msm_qgic2, "qcom,msm-qgic2", gic_of_init); #endif #ifdef CONFIG_ACPI -static phys_addr_t dist_phy_base, cpu_phy_base __initdata; +static phys_addr_t cpu_phy_base __initdata; static int __init gic_acpi_parse_madt_cpu(struct acpi_subtable_header *header, @@ -1205,60 +1204,56 @@ gic_acpi_parse_madt_cpu(struct acpi_subtable_header *header, return 0; } -static int __init -gic_acpi_parse_madt_distributor(struct acpi_subtable_header *header, - const unsigned long end) +/* The things you have to do to just *count* something... */ +static int __init acpi_dummy_func(struct acpi_subtable_header *header, + const unsigned long end) { - struct acpi_madt_generic_distributor *dist; + return 0; +} - dist = (struct acpi_madt_generic_distributor *)header; +static bool __init acpi_gic_redist_is_present(void) +{ + return acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR, + acpi_dummy_func, 0) > 0; +} - if (BAD_MADT_ENTRY(dist, end)) - return -EINVAL; +static bool __init gic_validate_dist(struct acpi_subtable_header *header, + struct acpi_probe_entry *ape) +{ + struct acpi_madt_generic_distributor *dist; + dist = (struct acpi_madt_generic_distributor *)header; - dist_phy_base = dist->base_address; - return 0; + return (dist->version == ape->driver_data && + (dist->version != ACPI_MADT_GIC_VERSION_NONE || + !acpi_gic_redist_is_present())); } -int __init -gic_v2_acpi_init(struct acpi_table_header *table) +#define ACPI_GICV2_DIST_MEM_SIZE (SZ_4K) +#define ACPI_GIC_CPU_IF_MEM_SIZE (SZ_8K) + +static int __init gic_v2_acpi_init(struct acpi_subtable_header *header, + const unsigned long end) { + struct acpi_madt_generic_distributor *dist; void __iomem *cpu_base, *dist_base; int count; /* 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); + count = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_INTERRUPT, + gic_acpi_parse_madt_cpu, 0); if (count <= 0) { pr_err("No valid GICC entries exist\n"); return -EINVAL; } - /* - * Find distributor base address. We expect one distributor entry since - * ACPI 5.1 spec neither support multi-GIC instances nor GIC cascade. - */ - count = acpi_parse_entries(ACPI_SIG_MADT, - sizeof(struct acpi_table_madt), - gic_acpi_parse_madt_distributor, table, - ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR, 0); - if (count <= 0) { - pr_err("No valid GICD entries exist\n"); - return -EINVAL; - } else if (count > 1) { - pr_err("More than one GICD entry detected\n"); - return -EINVAL; - } - cpu_base = ioremap(cpu_phy_base, ACPI_GIC_CPU_IF_MEM_SIZE); if (!cpu_base) { pr_err("Unable to map GICC registers\n"); return -ENOMEM; } - dist_base = ioremap(dist_phy_base, ACPI_GICV2_DIST_MEM_SIZE); + dist = (struct acpi_madt_generic_distributor *)header; + dist_base = ioremap(dist->base_address, ACPI_GICV2_DIST_MEM_SIZE); if (!dist_base) { pr_err("Unable to map GICD registers\n"); iounmap(cpu_base); @@ -1284,4 +1279,10 @@ gic_v2_acpi_init(struct acpi_table_header *table) acpi_irq_model = ACPI_IRQ_MODEL_GIC; return 0; } +IRQCHIP_ACPI_DECLARE(gic_v2, ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR, + gic_validate_dist, ACPI_MADT_GIC_VERSION_V2, + gic_v2_acpi_init); +IRQCHIP_ACPI_DECLARE(gic_v2_maybe, ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR, + gic_validate_dist, ACPI_MADT_GIC_VERSION_NONE, + gic_v2_acpi_init); #endif diff --git a/drivers/irqchip/irqchip.c b/drivers/irqchip/irqchip.c index 1ee773e..2b35e68 100644 --- a/drivers/irqchip/irqchip.c +++ b/drivers/irqchip/irqchip.c @@ -27,8 +27,5 @@ extern struct of_device_id __irqchip_of_table[]; void __init irqchip_init(void) { of_irq_init(__irqchip_of_table); -#if defined(CONFIG_ARM64) && defined(CONFIG_ACPI) - acpi_gic_init(); /* Temporary hack */ -#endif acpi_probe_device_table(irqchip); } diff --git a/include/linux/irqchip/arm-gic-acpi.h b/include/linux/irqchip/arm-gic-acpi.h deleted file mode 100644 index de3419e..0000000 --- a/include/linux/irqchip/arm-gic-acpi.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2014, Linaro Ltd. - * Author: Tomasz Nowicki <tomasz.nowicki@linaro.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef ARM_GIC_ACPI_H_ -#define ARM_GIC_ACPI_H_ - -#ifdef CONFIG_ACPI - -/* - * Hard code here, we can not get memory size from MADT (but FDT does), - * Actually no need to do that, because this size can be inferred - * from GIC spec. - */ -#define ACPI_GICV2_DIST_MEM_SIZE (SZ_4K) -#define ACPI_GIC_CPU_IF_MEM_SIZE (SZ_8K) - -struct acpi_table_header; - -int gic_v2_acpi_init(struct acpi_table_header *table); -void acpi_gic_init(void); -#else -static inline void acpi_gic_init(void) { } -#endif - -#endif /* ARM_GIC_ACPI_H_ */
Now that we have a basic infrastructure to register irqchips and call them on discovery of a matching entry in MADT, convert the GIC driver to this new probing method. It ends up being a code deletion party, which is a rather good thing. Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> --- arch/arm64/include/asm/acpi.h | 1 - arch/arm64/include/asm/irq.h | 2 -- arch/arm64/kernel/acpi.c | 25 ------------- drivers/irqchip/irq-gic.c | 69 ++++++++++++++++++------------------ drivers/irqchip/irqchip.c | 3 -- include/linux/irqchip/arm-gic-acpi.h | 31 ---------------- 6 files changed, 35 insertions(+), 96 deletions(-) delete mode 100644 include/linux/irqchip/arm-gic-acpi.h