From b4bbb02934e4511d9083f15c23e90703482e84ad Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Tue, 22 Nov 2011 15:09:20 -0800 Subject: [PATCH] Revert "of/irq: of_irq_find_parent: check for parent equal to child" This reverts commit dc9372808412edbc653a675a526c2ee6c0c14a91. As requested by Ben Herrenschmidt: "This breaks some powerpc platforms at least. The practice of having a node provide an explicit "interrupt-parent" property pointing to itself is an old trick that we've used in the past to allow a device-node to have interrupts routed to different controllers. In that case, the node also contains an interrupt-map, so the node is its own parent, the interrupt resolution hits the map, which then can route each individual interrupt to a different parent." Grant says: "Ah, nuts, yes that is broken then. Yes, please revert the commit and Rob & I will come up with a better solution. Rob, I think it can be done by explicitly checking for np == desc->interrupt_parent in of_irq_init() instead of relying on of_irq_find_parent() returning NULL." Requested-by: Benjamin Herrenschmidt Acked-by: Grant Likely Cc: Rob Herring Cc: devicetree-discuss@lists.ozlabs.org Cc: linuxppc-dev Cc: Tanmay Inamdar Signed-off-by: Linus Torvalds --- drivers/of/irq.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/of/irq.c b/drivers/of/irq.c index 6d3dd3988d0f..791270b8bd1c 100644 --- a/drivers/of/irq.c +++ b/drivers/of/irq.c @@ -60,27 +60,27 @@ EXPORT_SYMBOL_GPL(irq_of_parse_and_map); */ struct device_node *of_irq_find_parent(struct device_node *child) { - struct device_node *p, *c = child; + struct device_node *p; const __be32 *parp; - if (!of_node_get(c)) + if (!of_node_get(child)) return NULL; do { - parp = of_get_property(c, "interrupt-parent", NULL); + parp = of_get_property(child, "interrupt-parent", NULL); if (parp == NULL) - p = of_get_parent(c); + p = of_get_parent(child); else { if (of_irq_workarounds & OF_IMAP_NO_PHANDLE) p = of_node_get(of_irq_dflt_pic); else p = of_find_node_by_phandle(be32_to_cpup(parp)); } - of_node_put(c); - c = p; + of_node_put(child); + child = p; } while (p && of_get_property(p, "#interrupt-cells", NULL) == NULL); - return (p == child) ? NULL : p; + return p; } /**