[PATCH v3 28/62] arm/gic: Add ACPI support for GIC preinit

Stefano Stabellini stefano.stabellini at eu.citrix.com
Thu Nov 26 04:10:08 PST 2015


On Tue, 17 Nov 2015, shannon.zhao at linaro.org wrote:
> From: Shannon Zhao <shannon.zhao at linaro.org>
> 
> Since ACPI 6.0 defines that GIC Distributor Structure contains the GIC
> version filed, it could get GIC version from that. According to the
> version, call different preinit functions.
> 
> Signed-off-by: Shannon Zhao <shannon.zhao at linaro.org>
> ---
>  xen/arch/arm/gic.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++----
>  1 file changed, 51 insertions(+), 4 deletions(-)
> 
> diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c
> index 1e1e5ba..ac82588 100644
> --- a/xen/arch/arm/gic.c
> +++ b/xen/arch/arm/gic.c
> @@ -27,6 +27,7 @@
>  #include <xen/softirq.h>
>  #include <xen/list.h>
>  #include <xen/device_tree.h>
> +#include <xen/acpi.h>
>  #include <asm/p2m.h>
>  #include <asm/domain.h>
>  #include <asm/platform.h>
> @@ -34,6 +35,7 @@
>  #include <asm/io.h>
>  #include <asm/gic.h>
>  #include <asm/vgic.h>
> +#include <asm/acpi.h>
>  
>  static void gic_restore_pending_irqs(struct vcpu *v);
>  
> @@ -228,10 +230,7 @@ int gic_irq_xlate(const u32 *intspec, unsigned int intsize,
>      return 0;
>  }
>  
> -/* Find the interrupt controller and set up the callback to translate
> - * device tree IRQ.
> - */
> -void __init gic_preinit(void)
> +void __init dt_gic_preinit(void)
>  {
>      int rc;
>      struct dt_device_node *node;
> @@ -261,6 +260,54 @@ void __init gic_preinit(void)
>      dt_device_set_used_by(node, DOMID_XEN);
>  }
>  
> +#ifdef CONFIG_ACPI
> +static void __init acpi_gic_preinit(void)
> +{
> +    int rc = 0;
> +    acpi_status status;
> +    struct acpi_table_header *table;
> +    struct acpi_subtable_header * subtable;
> +    struct acpi_madt_generic_distributor *dist;
> +
> +    status = acpi_get_table(ACPI_SIG_MADT, 0, &table);
> +    if ( ACPI_FAILURE(status) )
> +    {
> +        const char *msg = acpi_format_exception(status);
> +
> +        panic("Failed to get MADT table, %s", msg);
> +    }
> +
> +    subtable = acpi_get_entry(ACPI_SIG_MADT, sizeof(struct acpi_table_madt),
> +                              table, ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR, 0);
> +    if ( !subtable )
> +        panic("No valid GICD entries exists");
> +
> +    dist = (struct acpi_madt_generic_distributor *)subtable;
> +
> +    if ( dist->version == ACPI_MADT_GIC_VERSION_V2 )
> +        rc = acpi_device_init(DEVICE_GIC, NULL, GIC_V2);
> +    else if ( dist->version == ACPI_MADT_GIC_VERSION_V3 )
> +        rc = acpi_device_init(DEVICE_GIC, NULL, GIC_V3);

I agree with your suggestion and Julien's previous comment. Something like:

ACPI_DEVICE_START(agicv2, "GICv2", DEVICE_GIC)
        .class_type = ACPI_MADT_GIC_VERSION_V2,
        .init = acpi_gicv2_preinit,
ACPI_DEVICE_END

would be better.


> +    else
> +        panic("Wrong GIC version or unsupported GIC");
> +    if ( rc )
> +        panic("Unable to find compatible GIC in the ACPI table");
> +}
> +#else
> +static void __init acpi_gic_preinit(void) {}
> +#endif
> +
> +/* Find the interrupt controller and set up the callback to translate
> + * device tree IRQ.
> + */
> +void __init gic_preinit(void)
> +{
> +    if( acpi_disabled )

coding style


> +        dt_gic_preinit();
> +    else
> +        acpi_gic_preinit();
> +}
> +
>  /* Set up the GIC */
>  void __init gic_init(void)
>  {
> -- 
> 2.1.0
> 



More information about the linux-arm-kernel mailing list