lkml.org 
[lkml]   [2014]   [Jul]   [24]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 12/19] ARM64 / ACPI: Introduce ACPI_IRQ_MODEL_GIC and register device's gsi
    Date
    Introduce ACPI_IRQ_MODEL_GIC which is needed for ARM64 as GIC is
    used, and then register device's gsi with the core IRQ subsystem.

    acpi_register_gsi() is similar to DT based irq_of_parse_and_map(),
    since gsi is unique in the system, so use hwirq number directly
    for the mapping.

    Originally-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
    Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
    ---
    arch/arm64/kernel/acpi.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++
    drivers/acpi/bus.c | 3 ++
    include/linux/acpi.h | 1 +
    3 files changed, 77 insertions(+)

    diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
    index ef06e91..3a078dc 100644
    --- a/arch/arm64/kernel/acpi.c
    +++ b/arch/arm64/kernel/acpi.c
    @@ -48,6 +48,12 @@ int acpi_psci_use_hvc;
    static int enabled_cpus;

    /*
    + * Since we're on ARM, the default interrupt routing model
    + * clearly has to be GIC.
    + */
    +enum acpi_irq_model_id acpi_irq_model = ACPI_IRQ_MODEL_GIC;
    +
    +/*
    * __acpi_map_table() will be called before page_init(), so early_ioremap()
    * or early_memremap() should be called here to for ACPI table mapping.
    */
    @@ -183,6 +189,73 @@ static int __init acpi_parse_madt_gic_cpu_interface_entries(void)
    return 0;
    }

    +int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)
    +{
    + *irq = irq_find_mapping(NULL, gsi);
    +
    + return 0;
    +}
    +EXPORT_SYMBOL_GPL(acpi_gsi_to_irq);
    +
    +/*
    + * success: return IRQ number (>0)
    + * failure: return =< 0
    + */
    +int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
    +{
    + 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, GSI should be unique so using
    + * the hwirq directly for the mapping:
    + * 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;
    +
    + /*
    + * Since only one GIC is supported in ACPI 5.0, we can
    + * create mapping refer to the default domain
    + */
    + irq = irq_create_mapping(NULL, gsi);
    + if (!irq)
    + return irq;
    +
    + /* Set irq type if specified and different than the current one */
    + if (irq_type != IRQ_TYPE_NONE &&
    + irq_type != irq_get_trigger_type(irq))
    + irq_set_irq_type(irq, irq_type);
    + return irq;
    +}
    +EXPORT_SYMBOL_GPL(acpi_register_gsi);
    +
    +void acpi_unregister_gsi(u32 gsi)
    +{
    +}
    +EXPORT_SYMBOL_GPL(acpi_unregister_gsi);
    +
    /* Protocol to bring up secondary CPUs */
    enum acpi_smp_boot_protocol smp_boot_protocol(void)
    {
    diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
    index c5bc8cf..301529c 100644
    --- a/drivers/acpi/bus.c
    +++ b/drivers/acpi/bus.c
    @@ -458,6 +458,9 @@ static int __init acpi_bus_init_irq(void)
    case ACPI_IRQ_MODEL_IOSAPIC:
    message = "IOSAPIC";
    break;
    + case ACPI_IRQ_MODEL_GIC:
    + message = "GIC";
    + break;
    case ACPI_IRQ_MODEL_PLATFORM:
    message = "platform specific model";
    break;
    diff --git a/include/linux/acpi.h b/include/linux/acpi.h
    index 358c01b..ad6c30f 100644
    --- a/include/linux/acpi.h
    +++ b/include/linux/acpi.h
    @@ -71,6 +71,7 @@ enum acpi_irq_model_id {
    ACPI_IRQ_MODEL_IOAPIC,
    ACPI_IRQ_MODEL_IOSAPIC,
    ACPI_IRQ_MODEL_PLATFORM,
    + ACPI_IRQ_MODEL_GIC,
    ACPI_IRQ_MODEL_COUNT
    };

    --
    1.7.9.5


    \
     
     \ /
      Last update: 2014-07-24 15:41    [W:3.950 / U:0.036 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site