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

of/irq: of_irq_find_parent: check for parent equal to child

An interrupt controller may often implicitly inherit itself from a parent
node when in fact the controller is the interrupt root controller. Guard
against the case of child == parent and return NULL in this case.

This can also be fixed by adding an explicit "interrupt-parent;" to a root
interrupt controller node.

Based on code from Grant Likely.

Signed-off-by: Rob Herring <rob.herring@calxeda.com>
Cc: Grant Likely <grant.likely@secretlab.ca>

+7 -7
+7 -7
drivers/of/irq.c
··· 58 58 */ 59 59 struct device_node *of_irq_find_parent(struct device_node *child) 60 60 { 61 - struct device_node *p; 61 + struct device_node *p, *c = child; 62 62 const __be32 *parp; 63 63 64 - if (!of_node_get(child)) 64 + if (!of_node_get(c)) 65 65 return NULL; 66 66 67 67 do { 68 - parp = of_get_property(child, "interrupt-parent", NULL); 68 + parp = of_get_property(c, "interrupt-parent", NULL); 69 69 if (parp == NULL) 70 - p = of_get_parent(child); 70 + p = of_get_parent(c); 71 71 else { 72 72 if (of_irq_workarounds & OF_IMAP_NO_PHANDLE) 73 73 p = of_node_get(of_irq_dflt_pic); 74 74 else 75 75 p = of_find_node_by_phandle(be32_to_cpup(parp)); 76 76 } 77 - of_node_put(child); 78 - child = p; 77 + of_node_put(c); 78 + c = p; 79 79 } while (p && of_get_property(p, "#interrupt-cells", NULL) == NULL); 80 80 81 - return p; 81 + return (p == child) ? NULL : p; 82 82 } 83 83 84 84 /**