aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGrant Likely <grant.likely@linaro.org>2013-11-01 10:50:50 -0700
committerGrant Likely <grant.likely@linaro.org>2013-11-03 23:16:35 +0000
commit78119fd1068cc068f6112a57a5f6de0e5b20245a (patch)
tree8e0726dc0a7527c0e7f571c7953e3115c7bded7f
parent0976c946a610d06e907335b7a3afa6db046f8e1b (diff)
of/irq: Fix bug in interrupt parsing refactor.
Commit 2361613206e6, "of/irq: Refactor interrupt-map parsing" introduced a bug. The irq parsing will fail for some nodes that don't have a reg property. It is fixed by deferring the check for reg until it is actually needed. Also adjust the testcase data to catch the bug. Signed-off-by: Grant Likely <grant.likely@linaro.org> Tested-by: Stephen Warren <swarren@nvidia.com> Tested-by: Ming Lei <tom.leiming@gmail.com> Tested-by: Stephen Warren <swarren@nvidia.com> Cc: Rob Herring <rob.herring@calxeda.com>
-rw-r--r--arch/arm/boot/dts/testcases/tests-interrupts.dtsi7
-rw-r--r--drivers/of/irq.c20
2 files changed, 14 insertions, 13 deletions
diff --git a/arch/arm/boot/dts/testcases/tests-interrupts.dtsi b/arch/arm/boot/dts/testcases/tests-interrupts.dtsi
index 560d6bf680b..c843720bd3e 100644
--- a/arch/arm/boot/dts/testcases/tests-interrupts.dtsi
+++ b/arch/arm/boot/dts/testcases/tests-interrupts.dtsi
@@ -2,7 +2,8 @@
/ {
testcase-data {
interrupts {
- #address-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <1>;
test_intc0: intc0 {
interrupt-controller;
#interrupt-cells = <1>;
@@ -29,8 +30,7 @@
test_intmap1: intmap1 {
#interrupt-cells = <2>;
- #address-cells = <0>;
- interrupt-map = <1 2 &test_intc0 15>;
+ interrupt-map = <0x5000 1 2 &test_intc0 15>;
};
interrupts0 {
@@ -44,6 +44,7 @@
};
interrupts-extended0 {
+ reg = <0x5000 0x100>;
interrupts-extended = <&test_intc0 1>,
<&test_intc1 2 3 4>,
<&test_intc2 5 6>,
diff --git a/drivers/of/irq.c b/drivers/of/irq.c
index 8cc62b4a798..52dba6a0142 100644
--- a/drivers/of/irq.c
+++ b/drivers/of/irq.c
@@ -147,18 +147,9 @@ int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq)
pr_debug(" -> addrsize=%d\n", addrsize);
- /* If we were passed no "reg" property and we attempt to parse
- * an interrupt-map, then #address-cells must be 0.
- * Fail if it's not.
- */
- if (addr == NULL && addrsize != 0) {
- pr_debug(" -> no reg passed in when needed !\n");
- return -EINVAL;
- }
-
/* Precalculate the match array - this simplifies match loop */
for (i = 0; i < addrsize; i++)
- initial_match_array[i] = addr[i];
+ initial_match_array[i] = addr ? addr[i] : 0;
for (i = 0; i < intsize; i++)
initial_match_array[addrsize + i] = cpu_to_be32(out_irq->args[i]);
@@ -174,6 +165,15 @@ int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq)
return 0;
}
+ /*
+ * interrupt-map parsing does not work without a reg
+ * property when #address-cells != 0
+ */
+ if (addrsize && !addr) {
+ pr_debug(" -> no reg passed in when needed !\n");
+ goto fail;
+ }
+
/* Now look for an interrupt-map */
imap = of_get_property(ipar, "interrupt-map", &imaplen);
/* No interrupt map, check for an interrupt parent */