Merge tag 'gpio-v5.1-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux...
[linux-2.6-microblaze.git] / kernel / irq / irqdomain.c
index 3bf9793..9ed29e4 100644 (file)
@@ -743,16 +743,17 @@ static int irq_domain_translate(struct irq_domain *d,
        return 0;
 }
 
-static void of_phandle_args_to_fwspec(struct of_phandle_args *irq_data,
+static void of_phandle_args_to_fwspec(struct device_node *np, const u32 *args,
+                                     unsigned int count,
                                      struct irq_fwspec *fwspec)
 {
        int i;
 
-       fwspec->fwnode = irq_data->np ? &irq_data->np->fwnode : NULL;
-       fwspec->param_count = irq_data->args_count;
+       fwspec->fwnode = np ? &np->fwnode : NULL;
+       fwspec->param_count = count;
 
-       for (i = 0; i < irq_data->args_count; i++)
-               fwspec->param[i] = irq_data->args[i];
+       for (i = 0; i < count; i++)
+               fwspec->param[i] = args[i];
 }
 
 unsigned int irq_create_fwspec_mapping(struct irq_fwspec *fwspec)
@@ -850,7 +851,9 @@ unsigned int irq_create_of_mapping(struct of_phandle_args *irq_data)
 {
        struct irq_fwspec fwspec;
 
-       of_phandle_args_to_fwspec(irq_data, &fwspec);
+       of_phandle_args_to_fwspec(irq_data->np, irq_data->args,
+                                 irq_data->args_count, &fwspec);
+
        return irq_create_fwspec_mapping(&fwspec);
 }
 EXPORT_SYMBOL_GPL(irq_create_of_mapping);
@@ -942,11 +945,10 @@ int irq_domain_xlate_twocell(struct irq_domain *d, struct device_node *ctrlr,
                        const u32 *intspec, unsigned int intsize,
                        irq_hw_number_t *out_hwirq, unsigned int *out_type)
 {
-       if (WARN_ON(intsize < 2))
-               return -EINVAL;
-       *out_hwirq = intspec[0];
-       *out_type = intspec[1] & IRQ_TYPE_SENSE_MASK;
-       return 0;
+       struct irq_fwspec fwspec;
+
+       of_phandle_args_to_fwspec(ctrlr, intspec, intsize, &fwspec);
+       return irq_domain_translate_twocell(d, &fwspec, out_hwirq, out_type);
 }
 EXPORT_SYMBOL_GPL(irq_domain_xlate_twocell);
 
@@ -982,6 +984,27 @@ const struct irq_domain_ops irq_domain_simple_ops = {
 };
 EXPORT_SYMBOL_GPL(irq_domain_simple_ops);
 
+/**
+ * irq_domain_translate_twocell() - Generic translate for direct two cell
+ * bindings
+ *
+ * Device Tree IRQ specifier translation function which works with two cell
+ * bindings where the cell values map directly to the hwirq number
+ * and linux irq flags.
+ */
+int irq_domain_translate_twocell(struct irq_domain *d,
+                                struct irq_fwspec *fwspec,
+                                unsigned long *out_hwirq,
+                                unsigned int *out_type)
+{
+       if (WARN_ON(fwspec->param_count < 2))
+               return -EINVAL;
+       *out_hwirq = fwspec->param[0];
+       *out_type = fwspec->param[1] & IRQ_TYPE_SENSE_MASK;
+       return 0;
+}
+EXPORT_SYMBOL_GPL(irq_domain_translate_twocell);
+
 int irq_domain_alloc_descs(int virq, unsigned int cnt, irq_hw_number_t hwirq,
                           int node, const struct irq_affinity_desc *affinity)
 {