105 lines
4.4 KiB
Diff
105 lines
4.4 KiB
Diff
|
From 6dc29d94d92ccc558b946bd57cd8d7cb19d8def1 Mon Sep 17 00:00:00 2001
|
||
|
From: Grant Likely <grant.likely@linaro.org>
|
||
|
Date: Thu, 19 Dec 2013 09:30:47 -0300
|
||
|
Subject: [PATCH 176/203] of/irq: create interrupts-extended property
|
||
|
|
||
|
The standard interrupts property in device tree can only handle
|
||
|
interrupts coming from a single interrupt parent. If a device is wired
|
||
|
to multiple interrupt controllers, then it needs to be attached to a
|
||
|
node with an interrupt-map property to demux the interrupt specifiers
|
||
|
which is confusing. It would be a lot easier if there was a form of the
|
||
|
interrupts property that allows for a separate interrupt phandle for
|
||
|
each interrupt specifier.
|
||
|
|
||
|
This patch does exactly that by creating a new interrupts-extended
|
||
|
property which reuses the phandle+arguments pattern used by GPIOs and
|
||
|
other core bindings.
|
||
|
|
||
|
Signed-off-by: Grant Likely <grant.likely@linaro.org>
|
||
|
Acked-by: Tony Lindgren <tony@atomide.com>
|
||
|
Acked-by: Kumar Gala <galak@codeaurora.org>
|
||
|
[grant.likely: removed versatile platform hunks into separate patch]
|
||
|
Cc: Rob Herring <rob.herring@calxeda.com>
|
||
|
|
||
|
Conflicts:
|
||
|
arch/arm/boot/dts/testcases/tests-interrupts.dtsi
|
||
|
drivers/of/selftest.c
|
||
|
---
|
||
|
.../bindings/interrupt-controller/interrupts.txt | 29 +++++++++++++++++-----
|
||
|
drivers/of/irq.c | 16 ++++++++----
|
||
|
2 files changed, 34 insertions(+), 11 deletions(-)
|
||
|
|
||
|
--- a/Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
|
||
|
+++ b/Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
|
||
|
@@ -4,16 +4,33 @@ Specifying interrupt information for dev
|
||
|
1) Interrupt client nodes
|
||
|
-------------------------
|
||
|
|
||
|
-Nodes that describe devices which generate interrupts must contain an
|
||
|
-"interrupts" property. This property must contain a list of interrupt
|
||
|
-specifiers, one per output interrupt. The format of the interrupt specifier is
|
||
|
-determined by the interrupt controller to which the interrupts are routed; see
|
||
|
-section 2 below for details.
|
||
|
+Nodes that describe devices which generate interrupts must contain an either an
|
||
|
+"interrupts" property or an "interrupts-extended" property. These properties
|
||
|
+contain a list of interrupt specifiers, one per output interrupt. The format of
|
||
|
+the interrupt specifier is determined by the interrupt controller to which the
|
||
|
+interrupts are routed; see section 2 below for details.
|
||
|
+
|
||
|
+ Example:
|
||
|
+ interrupt-parent = <&intc1>;
|
||
|
+ interrupts = <5 0>, <6 0>;
|
||
|
|
||
|
The "interrupt-parent" property is used to specify the controller to which
|
||
|
interrupts are routed and contains a single phandle referring to the interrupt
|
||
|
controller node. This property is inherited, so it may be specified in an
|
||
|
-interrupt client node or in any of its parent nodes.
|
||
|
+interrupt client node or in any of its parent nodes. Interrupts listed in the
|
||
|
+"interrupts" property are always in reference to the node's interrupt parent.
|
||
|
+
|
||
|
+The "interrupts-extended" property is a special form for use when a node needs
|
||
|
+to reference multiple interrupt parents. Each entry in this property contains
|
||
|
+both the parent phandle and the interrupt specifier. "interrupts-extended"
|
||
|
+should only be used when a device has multiple interrupt parents.
|
||
|
+
|
||
|
+ Example:
|
||
|
+ interrupts-extended = <&intc1 5 1>, <&intc2 1 0>;
|
||
|
+
|
||
|
+A device node may contain either "interrupts" or "interrupts-extended", but not
|
||
|
+both. If both properties are present, then the operating system should log an
|
||
|
+error and use only the data in "interrupts".
|
||
|
|
||
|
2) Interrupt controller nodes
|
||
|
-----------------------------
|
||
|
--- a/drivers/of/irq.c
|
||
|
+++ b/drivers/of/irq.c
|
||
|
@@ -293,17 +293,23 @@ int of_irq_map_one(struct device_node *d
|
||
|
if (of_irq_workarounds & OF_IMAP_OLDWORLD_MAC)
|
||
|
return of_irq_map_oldworld(device, index, out_irq);
|
||
|
|
||
|
+ /* Get the reg property (if any) */
|
||
|
+ addr = of_get_property(device, "reg", NULL);
|
||
|
+
|
||
|
/* Get the interrupts property */
|
||
|
intspec = of_get_property(device, "interrupts", &intlen);
|
||
|
- if (intspec == NULL)
|
||
|
- return -EINVAL;
|
||
|
+ if (intspec == NULL) {
|
||
|
+ /* Try the new-style interrupts-extended */
|
||
|
+ res = of_parse_phandle_with_args(device, "interrupts-extended",
|
||
|
+ "#interrupt-cells", index, out_irq);
|
||
|
+ if (res)
|
||
|
+ return -EINVAL;
|
||
|
+ return of_irq_parse_raw(addr, out_irq);
|
||
|
+ }
|
||
|
intlen /= sizeof(*intspec);
|
||
|
|
||
|
pr_debug(" intspec=%d intlen=%d\n", be32_to_cpup(intspec), intlen);
|
||
|
|
||
|
- /* Get the reg property (if any) */
|
||
|
- addr = of_get_property(device, "reg", NULL);
|
||
|
-
|
||
|
/* Look for the interrupt parent. */
|
||
|
p = of_irq_find_parent(device);
|
||
|
if (p == NULL)
|