Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

of/irq: Fix lookup to use 'interrupts-extended' property first

In case the Device Tree blob passed by the boot agent supplies both an
'interrupts-extended' and an 'interrupts' property in order to allow for
older kernels to be usable, prefer the new-style 'interrupts-extended'
property which conveys a lot more information.

This allows us to have bootloaders willingly maintaining backwards
compatibility with older kernels without entirely deprecating the
'interrupts' property.

Update the bindings documentation to describe a situation where both the
'interrupts-extended' and the 'interrupts' property are present, and
which one takes precedence over the other.

Cc: stable@vger.kernel.org # 3.13+
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Grant Likely <grant.likely@linaro.org>

authored by

Florian Fainelli and committed by
Grant Likely
a9ecdc0f b951f9dc

+16 -13
+7 -5
Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
··· 4 4 1) Interrupt client nodes 5 5 ------------------------- 6 6 7 - Nodes that describe devices which generate interrupts must contain an either an 8 - "interrupts" property or an "interrupts-extended" property. These properties 9 - contain a list of interrupt specifiers, one per output interrupt. The format of 10 - the interrupt specifier is determined by the interrupt controller to which the 11 - interrupts are routed; see section 2 below for details. 7 + Nodes that describe devices which generate interrupts must contain an 8 + "interrupts" property, an "interrupts-extended" property, or both. If both are 9 + present, the latter should take precedence; the former may be provided simply 10 + for compatibility with software that does not recognize the latter. These 11 + properties contain a list of interrupt specifiers, one per output interrupt. The 12 + format of the interrupt specifier is determined by the interrupt controller to 13 + which the interrupts are routed; see section 2 below for details. 12 14 13 15 Example: 14 16 interrupt-parent = <&intc1>;
+9 -8
drivers/of/irq.c
··· 301 301 /* Get the reg property (if any) */ 302 302 addr = of_get_property(device, "reg", NULL); 303 303 304 + /* Try the new-style interrupts-extended first */ 305 + res = of_parse_phandle_with_args(device, "interrupts-extended", 306 + "#interrupt-cells", index, out_irq); 307 + if (!res) 308 + return of_irq_parse_raw(addr, out_irq); 309 + 304 310 /* Get the interrupts property */ 305 311 intspec = of_get_property(device, "interrupts", &intlen); 306 - if (intspec == NULL) { 307 - /* Try the new-style interrupts-extended */ 308 - res = of_parse_phandle_with_args(device, "interrupts-extended", 309 - "#interrupt-cells", index, out_irq); 310 - if (res) 311 - return -EINVAL; 312 - return of_irq_parse_raw(addr, out_irq); 313 - } 312 + if (intspec == NULL) 313 + return -EINVAL; 314 + 314 315 intlen /= sizeof(*intspec); 315 316 316 317 pr_debug(" intspec=%d intlen=%d\n", be32_to_cpup(intspec), intlen);