mirror of https://gitee.com/openkylin/linux.git
of/irq: Fix bug in interrupt parsing refactor.
Commit 2361613206
, "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>
This commit is contained in:
parent
0976c946a6
commit
78119fd106
|
@ -2,7 +2,8 @@
|
||||||
/ {
|
/ {
|
||||||
testcase-data {
|
testcase-data {
|
||||||
interrupts {
|
interrupts {
|
||||||
#address-cells = <0>;
|
#address-cells = <1>;
|
||||||
|
#size-cells = <1>;
|
||||||
test_intc0: intc0 {
|
test_intc0: intc0 {
|
||||||
interrupt-controller;
|
interrupt-controller;
|
||||||
#interrupt-cells = <1>;
|
#interrupt-cells = <1>;
|
||||||
|
@ -29,8 +30,7 @@ test_intmap0: intmap0 {
|
||||||
|
|
||||||
test_intmap1: intmap1 {
|
test_intmap1: intmap1 {
|
||||||
#interrupt-cells = <2>;
|
#interrupt-cells = <2>;
|
||||||
#address-cells = <0>;
|
interrupt-map = <0x5000 1 2 &test_intc0 15>;
|
||||||
interrupt-map = <1 2 &test_intc0 15>;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
interrupts0 {
|
interrupts0 {
|
||||||
|
@ -44,6 +44,7 @@ interrupts1 {
|
||||||
};
|
};
|
||||||
|
|
||||||
interrupts-extended0 {
|
interrupts-extended0 {
|
||||||
|
reg = <0x5000 0x100>;
|
||||||
interrupts-extended = <&test_intc0 1>,
|
interrupts-extended = <&test_intc0 1>,
|
||||||
<&test_intc1 2 3 4>,
|
<&test_intc1 2 3 4>,
|
||||||
<&test_intc2 5 6>,
|
<&test_intc2 5 6>,
|
||||||
|
|
|
@ -147,18 +147,9 @@ int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq)
|
||||||
|
|
||||||
pr_debug(" -> addrsize=%d\n", addrsize);
|
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 */
|
/* Precalculate the match array - this simplifies match loop */
|
||||||
for (i = 0; i < addrsize; i++)
|
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++)
|
for (i = 0; i < intsize; i++)
|
||||||
initial_match_array[addrsize + i] = cpu_to_be32(out_irq->args[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;
|
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 */
|
/* Now look for an interrupt-map */
|
||||||
imap = of_get_property(ipar, "interrupt-map", &imaplen);
|
imap = of_get_property(ipar, "interrupt-map", &imaplen);
|
||||||
/* No interrupt map, check for an interrupt parent */
|
/* No interrupt map, check for an interrupt parent */
|
||||||
|
|
Loading…
Reference in New Issue