On Thu, Jul 09, 2015 at 06:44:28AM +0100, Suravee Suthikulpanit wrote:
This patch declares acpi_register_gsi() as weak and allows architecture to specify its own acpi_register_gsi().
In ARM64 case, we need to specify GIC_INT_TYPE_XXX when calling irq_domain_ops.init_alloc_info(), which is specific to ARM64.
I think it is better to define an ACPI hook that allows you to retrieve what interrupt controller type you want to alloc from instead of adding an acpi_register_gsi function that is 99% generic to arm64 code.
I will review this code on the kernel mailing lists, but I am not happy with this patch approach.
Lorenzo
Signed-off-by: Suravee Suthikulpanit Suravee.Suthikulpanit@amd.com
arch/arm64/kernel/acpi.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ drivers/acpi/gsi.c | 4 ++-- include/linux/acpi.h | 4 ++++ 3 files changed, 54 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c index 19de753..05e9c07 100644 --- a/arch/arm64/kernel/acpi.c +++ b/arch/arm64/kernel/acpi.c @@ -20,6 +20,7 @@ #include <linux/cpumask.h> #include <linux/init.h> #include <linux/irq.h> +#include <linux/irqchip/arm-gic.h> #include <linux/irqdomain.h> #include <linux/memblock.h> #include <linux/of_fdt.h> @@ -230,3 +231,50 @@ void __init acpi_gic_init(void) early_acpi_os_unmap_memory((char *)table, tbl_size); }
+int acpi_register_gsi(struct device *dev, u32 gsi, int trigger,
int polarity)
+{
- unsigned int irq;
- unsigned int irq_type = acpi_gsi_get_irq_type(trigger, polarity);
- struct irq_data *d = NULL;
- if (acpi_irq_domain && acpi_irq_domain->ops->init_alloc_info) {
void *info;
int err;
uint32_t data[3] = {GIC_INT_TYPE_NONE, gsi, irq_type};
err = acpi_irq_domain->ops->init_alloc_info(data, 3,
NULL, &info);
if (err)
return err;
irq = irq_domain_alloc_irqs(acpi_irq_domain, 1,
dev_to_node(dev), info);
if (irq < 0)
return -ENOSPC;
d = irq_domain_get_irq_data(acpi_irq_domain, irq);
if (!d)
return -EFAULT;
- } else {
/*
* There is no IRQ domain on ACPI,
* hence always create mapping referring to the default domain
* by passing NULL as irq_domain parameter
*/
irq = irq_create_mapping(NULL, gsi);
if (!irq)
return -EINVAL;
- }
- /* Set irq type if specified and different than the current one */
- if (irq_type != IRQ_TYPE_NONE &&
irq_type != irq_get_trigger_type(irq)) {
if (d)
d->chip->irq_set_type(d, irq_type);
else
irq_set_irq_type(irq, irq_type);
- }
- return irq;
+} diff --git a/drivers/acpi/gsi.c b/drivers/acpi/gsi.c index 8fa8a01..a015d9e 100644 --- a/drivers/acpi/gsi.c +++ b/drivers/acpi/gsi.c @@ -80,8 +80,8 @@ EXPORT_SYMBOL_GPL(acpi_gsi_to_irq);
- Returns: a valid linux IRQ number on success
-EINVAL on failure
*/ -int acpi_register_gsi(struct device *dev, u32 gsi, int trigger,
int polarity)
+int __weak acpi_register_gsi(struct device *dev, u32 gsi, int trigger,
int polarity)
{ unsigned int irq; unsigned int irq_type = acpi_gsi_get_irq_type(trigger, polarity); diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 6826ca4..5254d39 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -221,6 +221,10 @@ extern unsigned long acpi_realmode_flags; int acpi_register_gsi (struct device *dev, u32 gsi, int triggering, int polarity); int acpi_gsi_to_irq (u32 gsi, unsigned int *irq); int acpi_isa_irq_to_gsi (unsigned isa_irq, u32 *gsi); +unsigned int acpi_gsi_get_irq_type(int trigger, int polarity);
+extern struct irq_domain *acpi_irq_domain; +int acpi_gsi_set_domain(struct irq_domain *domain); #ifdef CONFIG_X86_IO_APIC extern int acpi_get_override_irq(u32 gsi, int *trigger, int *polarity); -- 2.1.0