mvebu: backport mainline patches from kernel 3.13
[openwrt.git] / target / linux / mvebu / patches-3.10 / 0176-of-irq-create-interrupts-extended-property.patch
1 From 6dc29d94d92ccc558b946bd57cd8d7cb19d8def1 Mon Sep 17 00:00:00 2001
2 From: Grant Likely <grant.likely@linaro.org>
3 Date: Thu, 19 Dec 2013 09:30:47 -0300
4 Subject: [PATCH 176/203] of/irq: create interrupts-extended property
5
6 The standard interrupts property in device tree can only handle
7 interrupts coming from a single interrupt parent. If a device is wired
8 to multiple interrupt controllers, then it needs to be attached to a
9 node with an interrupt-map property to demux the interrupt specifiers
10 which is confusing. It would be a lot easier if there was a form of the
11 interrupts property that allows for a separate interrupt phandle for
12 each interrupt specifier.
13
14 This patch does exactly that by creating a new interrupts-extended
15 property which reuses the phandle+arguments pattern used by GPIOs and
16 other core bindings.
17
18 Signed-off-by: Grant Likely <grant.likely@linaro.org>
19 Acked-by: Tony Lindgren <tony@atomide.com>
20 Acked-by: Kumar Gala <galak@codeaurora.org>
21 [grant.likely: removed versatile platform hunks into separate patch]
22 Cc: Rob Herring <rob.herring@calxeda.com>
23
24 Conflicts:
25         arch/arm/boot/dts/testcases/tests-interrupts.dtsi
26         drivers/of/selftest.c
27 ---
28  .../bindings/interrupt-controller/interrupts.txt   | 29 +++++++++++++++++-----
29  drivers/of/irq.c                                   | 16 ++++++++----
30  2 files changed, 34 insertions(+), 11 deletions(-)
31
32 --- a/Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
33 +++ b/Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
34 @@ -4,16 +4,33 @@ Specifying interrupt information for dev
35  1) Interrupt client nodes
36  -------------------------
37  
38 -Nodes that describe devices which generate interrupts must contain an
39 -"interrupts" property. This property must contain a list of interrupt
40 -specifiers, one per output interrupt. The format of the interrupt specifier is
41 -determined by the interrupt controller to which the interrupts are routed; see
42 -section 2 below for details.
43 +Nodes that describe devices which generate interrupts must contain an either an
44 +"interrupts" property or an "interrupts-extended" property. These properties
45 +contain a list of interrupt specifiers, one per output interrupt. The format of
46 +the interrupt specifier is determined by the interrupt controller to which the
47 +interrupts are routed; see section 2 below for details.
48 +
49 +  Example:
50 +       interrupt-parent = <&intc1>;
51 +       interrupts = <5 0>, <6 0>;
52  
53  The "interrupt-parent" property is used to specify the controller to which
54  interrupts are routed and contains a single phandle referring to the interrupt
55  controller node. This property is inherited, so it may be specified in an
56 -interrupt client node or in any of its parent nodes.
57 +interrupt client node or in any of its parent nodes. Interrupts listed in the
58 +"interrupts" property are always in reference to the node's interrupt parent.
59 +
60 +The "interrupts-extended" property is a special form for use when a node needs
61 +to reference multiple interrupt parents. Each entry in this property contains
62 +both the parent phandle and the interrupt specifier. "interrupts-extended"
63 +should only be used when a device has multiple interrupt parents.
64 +
65 +  Example:
66 +       interrupts-extended = <&intc1 5 1>, <&intc2 1 0>;
67 +
68 +A device node may contain either "interrupts" or "interrupts-extended", but not
69 +both. If both properties are present, then the operating system should log an
70 +error and use only the data in "interrupts".
71  
72  2) Interrupt controller nodes
73  -----------------------------
74 --- a/drivers/of/irq.c
75 +++ b/drivers/of/irq.c
76 @@ -293,17 +293,23 @@ int of_irq_map_one(struct device_node *d
77         if (of_irq_workarounds & OF_IMAP_OLDWORLD_MAC)
78                 return of_irq_map_oldworld(device, index, out_irq);
79  
80 +       /* Get the reg property (if any) */
81 +       addr = of_get_property(device, "reg", NULL);
82 +
83         /* Get the interrupts property */
84         intspec = of_get_property(device, "interrupts", &intlen);
85 -       if (intspec == NULL)
86 -               return -EINVAL;
87 +       if (intspec == NULL) {
88 +               /* Try the new-style interrupts-extended */
89 +               res = of_parse_phandle_with_args(device, "interrupts-extended",
90 +                                               "#interrupt-cells", index, out_irq);
91 +               if (res)
92 +                       return -EINVAL;
93 +               return of_irq_parse_raw(addr, out_irq);
94 +       }
95         intlen /= sizeof(*intspec);
96  
97         pr_debug(" intspec=%d intlen=%d\n", be32_to_cpup(intspec), intlen);
98  
99 -       /* Get the reg property (if any) */
100 -       addr = of_get_property(device, "reg", NULL);
101 -
102         /* Look for the interrupt parent. */
103         p = of_irq_find_parent(device);
104         if (p == NULL)