summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Masney <masneyb@onstation.org>2019-02-07 21:16:22 -0500
committerLinus Walleij <linus.walleij@linaro.org>2019-02-13 03:22:05 -0500
commitb5c231d8c8037f63d34199ea1667bbe1cd9f940f (patch)
treec73972b330070d8f07b626888b1baccfa80d0d25
parent86291029e97eaf6a9c2ed43e7968ba8cf9f9f3b7 (diff)
genirq: introduce irq_domain_translate_twocell
Add a new function irq_domain_translate_twocell() that is to be used as the translate function in struct irq_domain_ops for the v2 IRQ API. This patch also changes irq_domain_xlate_twocell() from the v1 IRQ API to call irq_domain_translate_twocell() in the v2 IRQ API. This required changes to of_phandle_args_to_fwspec()'s arguments so that it can be called from multiple places. Cc: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Marc Zyngier <marc.zyngier@arm.com> Signed-off-by: Brian Masney <masneyb@onstation.org> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-rw-r--r--include/linux/irqdomain.h5
-rw-r--r--kernel/irq/irqdomain.c45
2 files changed, 39 insertions, 11 deletions
diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index 35965f41d7be..fcefe0c7263f 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -419,6 +419,11 @@ int irq_domain_xlate_onetwocell(struct irq_domain *d, struct device_node *ctrlr,
419 const u32 *intspec, unsigned int intsize, 419 const u32 *intspec, unsigned int intsize,
420 irq_hw_number_t *out_hwirq, unsigned int *out_type); 420 irq_hw_number_t *out_hwirq, unsigned int *out_type);
421 421
422int irq_domain_translate_twocell(struct irq_domain *d,
423 struct irq_fwspec *fwspec,
424 unsigned long *out_hwirq,
425 unsigned int *out_type);
426
422/* IPI functions */ 427/* IPI functions */
423int irq_reserve_ipi(struct irq_domain *domain, const struct cpumask *dest); 428int irq_reserve_ipi(struct irq_domain *domain, const struct cpumask *dest);
424int irq_destroy_ipi(unsigned int irq, const struct cpumask *dest); 429int irq_destroy_ipi(unsigned int irq, const struct cpumask *dest);
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 8b0be4bd6565..56a30d542b8e 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -729,16 +729,17 @@ static int irq_domain_translate(struct irq_domain *d,
729 return 0; 729 return 0;
730} 730}
731 731
732static void of_phandle_args_to_fwspec(struct of_phandle_args *irq_data, 732static void of_phandle_args_to_fwspec(struct device_node *np, const u32 *args,
733 unsigned int count,
733 struct irq_fwspec *fwspec) 734 struct irq_fwspec *fwspec)
734{ 735{
735 int i; 736 int i;
736 737
737 fwspec->fwnode = irq_data->np ? &irq_data->np->fwnode : NULL; 738 fwspec->fwnode = np ? &np->fwnode : NULL;
738 fwspec->param_count = irq_data->args_count; 739 fwspec->param_count = count;
739 740
740 for (i = 0; i < irq_data->args_count; i++) 741 for (i = 0; i < count; i++)
741 fwspec->param[i] = irq_data->args[i]; 742 fwspec->param[i] = args[i];
742} 743}
743 744
744unsigned int irq_create_fwspec_mapping(struct irq_fwspec *fwspec) 745unsigned int irq_create_fwspec_mapping(struct irq_fwspec *fwspec)
@@ -836,7 +837,9 @@ unsigned int irq_create_of_mapping(struct of_phandle_args *irq_data)
836{ 837{
837 struct irq_fwspec fwspec; 838 struct irq_fwspec fwspec;
838 839
839 of_phandle_args_to_fwspec(irq_data, &fwspec); 840 of_phandle_args_to_fwspec(irq_data->np, irq_data->args,
841 irq_data->args_count, &fwspec);
842
840 return irq_create_fwspec_mapping(&fwspec); 843 return irq_create_fwspec_mapping(&fwspec);
841} 844}
842EXPORT_SYMBOL_GPL(irq_create_of_mapping); 845EXPORT_SYMBOL_GPL(irq_create_of_mapping);
@@ -928,11 +931,10 @@ int irq_domain_xlate_twocell(struct irq_domain *d, struct device_node *ctrlr,
928 const u32 *intspec, unsigned int intsize, 931 const u32 *intspec, unsigned int intsize,
929 irq_hw_number_t *out_hwirq, unsigned int *out_type) 932 irq_hw_number_t *out_hwirq, unsigned int *out_type)
930{ 933{
931 if (WARN_ON(intsize < 2)) 934 struct irq_fwspec fwspec;
932 return -EINVAL; 935
933 *out_hwirq = intspec[0]; 936 of_phandle_args_to_fwspec(ctrlr, intspec, intsize, &fwspec);
934 *out_type = intspec[1] & IRQ_TYPE_SENSE_MASK; 937 return irq_domain_translate_twocell(d, &fwspec, out_hwirq, out_type);
935 return 0;
936} 938}
937EXPORT_SYMBOL_GPL(irq_domain_xlate_twocell); 939EXPORT_SYMBOL_GPL(irq_domain_xlate_twocell);
938 940
@@ -968,6 +970,27 @@ const struct irq_domain_ops irq_domain_simple_ops = {
968}; 970};
969EXPORT_SYMBOL_GPL(irq_domain_simple_ops); 971EXPORT_SYMBOL_GPL(irq_domain_simple_ops);
970 972
973/**
974 * irq_domain_translate_twocell() - Generic translate for direct two cell
975 * bindings
976 *
977 * Device Tree IRQ specifier translation function which works with two cell
978 * bindings where the cell values map directly to the hwirq number
979 * and linux irq flags.
980 */
981int irq_domain_translate_twocell(struct irq_domain *d,
982 struct irq_fwspec *fwspec,
983 unsigned long *out_hwirq,
984 unsigned int *out_type)
985{
986 if (WARN_ON(fwspec->param_count < 2))
987 return -EINVAL;
988 *out_hwirq = fwspec->param[0];
989 *out_type = fwspec->param[1] & IRQ_TYPE_SENSE_MASK;
990 return 0;
991}
992EXPORT_SYMBOL_GPL(irq_domain_translate_twocell);
993
971int irq_domain_alloc_descs(int virq, unsigned int cnt, irq_hw_number_t hwirq, 994int irq_domain_alloc_descs(int virq, unsigned int cnt, irq_hw_number_t hwirq,
972 int node, const struct irq_affinity_desc *affinity) 995 int node, const struct irq_affinity_desc *affinity)
973{ 996{