Move OF specific logic to OF irq.c file and make it more generic so acpi can use it too.
Signed-off-by: Tomasz Nowicki tomasz.nowicki@linaro.org --- drivers/of/irq.c | 42 ++++++++++++++++++++++++++++++++++++++++++ include/linux/irqdomain.h | 3 +++ kernel/irq/irqdomain.c | 31 ++++++++++--------------------- 3 files changed, 55 insertions(+), 21 deletions(-)
diff --git a/drivers/of/irq.c b/drivers/of/irq.c index 786b0b4..2bac976 100644 --- a/drivers/of/irq.c +++ b/drivers/of/irq.c @@ -26,6 +26,48 @@ #include <linux/string.h> #include <linux/slab.h>
+ +/** + * irq_create_of_mapping - Look up for domain and map an interrupt given irq + * @irq_data: pointer to arguments structure + * + * This function looks for associated domain, optionally translates, and maps + * int linux virq space + */ +unsigned int irq_create_of_mapping(struct of_phandle_args *irq_data) +{ + struct irq_domain *domain; + irq_hw_number_t hwirq; + unsigned int type = IRQ_TYPE_NONE; + + if (!irq_data->np) { + /* + * Nothing wrong with that, try default domain. + */ + domain = NULL; + } else { + domain = irq_find_host(irq_data->np); + if (!domain) { + pr_warn("no irq domain found for %s !\n", + of_node_full_name(irq_data->np)); + return 0; + } + } + + /* If domain has no translation, then we assume interrupt line */ + if (domain->ops->xlate == NULL) + hwirq = irq_data->args[0]; + else { + if (domain->ops->xlate(domain, irq_data->np, irq_data->args, + irq_data->args_count, &hwirq, &type)) + return 0; + } + + /* Create mapping */ + return irq_create_mapping_type(domain, hwirq, type); +} +EXPORT_SYMBOL_GPL(irq_create_of_mapping); + /** * irq_of_parse_and_map - Parse and map an interrupt into linux virq space * @dev: Device node of the device whose interrupt is to be mapped diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h index c983ed1..c14f59b 100644 --- a/include/linux/irqdomain.h +++ b/include/linux/irqdomain.h @@ -175,6 +175,9 @@ extern void irq_domain_associate_many(struct irq_domain *domain,
extern unsigned int irq_create_mapping(struct irq_domain *host, irq_hw_number_t hwirq); +extern unsigned int irq_create_mapping_type(struct irq_domain *domain, + irq_hw_number_t hwirq, + unsigned int type); extern void irq_dispose_mapping(unsigned int virq);
/** diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c index c661552..bf74a0b 100644 --- a/kernel/irq/irqdomain.c +++ b/kernel/irq/irqdomain.c @@ -465,29 +465,18 @@ int irq_create_strict_mappings(struct irq_domain *domain, unsigned int irq_base, } EXPORT_SYMBOL_GPL(irq_create_strict_mappings);
-unsigned int irq_create_of_mapping(struct of_phandle_args *irq_data) +/** + * irq_create_mapping_type() - Create mapping and set given irq type + * @domain: domain owning this hardware interrupt + * @hwirq: hardware interrupt + * @type: interrupt type + */ +unsigned int irq_create_mapping_type(struct irq_domain *domain, + irq_hw_number_t hwirq, + unsigned int type) { - struct irq_domain *domain; - irq_hw_number_t hwirq; - unsigned int type = IRQ_TYPE_NONE; unsigned int virq;
- domain = irq_data->np ? irq_find_host(irq_data->np) : irq_default_domain; - if (!domain) { - pr_warn("no irq domain found for %s !\n", - of_node_full_name(irq_data->np)); - return 0; - } - - /* If domain has no translation, then we assume interrupt line */ - if (domain->ops->xlate == NULL) - hwirq = irq_data->args[0]; - else { - if (domain->ops->xlate(domain, irq_data->np, irq_data->args, - irq_data->args_count, &hwirq, &type)) - return 0; - } - /* Create mapping */ virq = irq_create_mapping(domain, hwirq); if (!virq) @@ -499,7 +488,7 @@ unsigned int irq_create_of_mapping(struct of_phandle_args *irq_data) irq_set_irq_type(virq, type); return virq; } -EXPORT_SYMBOL_GPL(irq_create_of_mapping); +EXPORT_SYMBOL_GPL(irq_create_mapping_type);
#ifdef CONFIG_ACPI unsigned int irq_create_acpi_mapping(irq_hw_number_t hwirq,