From: Amit Daniel Kachhap amit.daniel@samsung.com
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.
[Hanjun: Add some comments for interrupt mapping from DT to ACPI, and rework it according to the API of irq_create_acpi_mapping()]
Signed-off-by: Amit Daniel Kachhap amit.daniel@samsung.com Signed-off-by: Hanjun Guo hanjun.guo@linaro.org --- drivers/acpi/plat/arm/boot.c | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-)
diff --git a/drivers/acpi/plat/arm/boot.c b/drivers/acpi/plat/arm/boot.c index 4fcdd9f..38a6a9d 100644 --- a/drivers/acpi/plat/arm/boot.c +++ b/drivers/acpi/plat/arm/boot.c @@ -254,12 +254,36 @@ int (*__acpi_register_gsi)(struct device *dev, u32 gsi, int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity) { unsigned int irq; - unsigned int plat_gsi = gsi; - - plat_gsi = (*__acpi_register_gsi)(dev, gsi, trigger, polarity); - - irq = gsi_to_irq(plat_gsi); + unsigned int irq_type; + irq_hw_number_t hwirq = gsi; + + /* ACPI hae no bindings to indicate SPI or PPI, so we + * use following mapping from DT to ACPI: + * + * PPI interrupt: the same as DT, in the range [0, 15]; + * SPI interrupt: are in the range [32, 1019]; + */ + if (gsi < 32) { + /* PPI interrupts, add 16 to skip over SGIs */ + hwirq = gsi + 16; + }
+ 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(hwirq, irq_type); return irq; } EXPORT_SYMBOL_GPL(acpi_register_gsi);