From b4bbb02934e4511d9083f15c23e90703482e84ad Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Tue, 22 Nov 2011 15:09:20 -0800 Subject: 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(-) (limited to 'drivers/of/irq.c') 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; } /** -- cgit From d7fb6d0adb86ed1c5290e754092a5a1e3de76ee9 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Sun, 27 Nov 2011 20:16:33 -0600 Subject: of/irq: of_irq_init: add check for parent equal to child node With the revert of "of/irq: of_irq_find_parent: check for parent equal to child" (dc9372808412edb), we need another way to handle parent node equal to the child node. This can simply be handled in of_irq_init by checking for this condition. Signed-off-by: Rob Herring Tested-by: Pawel Moll Tested-by: Stephen Warren --- drivers/of/irq.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/of/irq.c') diff --git a/drivers/of/irq.c b/drivers/of/irq.c index 791270b8bd1c..19c0115092dd 100644 --- a/drivers/of/irq.c +++ b/drivers/of/irq.c @@ -424,6 +424,8 @@ void __init of_irq_init(const struct of_device_id *matches) desc->dev = np; desc->interrupt_parent = of_irq_find_parent(np); + if (desc->interrupt_parent == np) + desc->interrupt_parent = NULL; list_add_tail(&desc->list, &intc_desc_list); } -- cgit From 77a7300abad7fe01891b400e88d746f97307ee5a Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Wed, 7 Dec 2011 03:16:26 +0400 Subject: of/irq: Get rid of NO_IRQ usage PPC32/64 defines NO_IRQ to zero, so no problems expected. ARM defines NO_IRQ to -1, but OF code relies on IRQ domains support, which returns correct ('0') value in 'no irq' case. So everything should be fine. Other arches might break if some of their OF drivers rely on NO_IRQ being not 0. If so, the drivers must be fixed, finally. [ Rob Herring points out that microblaze should be fixed, and has posted a patch for testing for that. - Linus ] Signed-off-by: Anton Vorontsov Acked-by: Wolfram Sang Signed-off-by: Linus Torvalds --- drivers/of/irq.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) (limited to 'drivers/of/irq.c') diff --git a/drivers/of/irq.c b/drivers/of/irq.c index 19c0115092dd..0f0cfa3bca30 100644 --- a/drivers/of/irq.c +++ b/drivers/of/irq.c @@ -26,11 +26,6 @@ #include #include -/* For archs that don't support NO_IRQ (such as x86), provide a dummy value */ -#ifndef NO_IRQ -#define NO_IRQ 0 -#endif - /** * irq_of_parse_and_map - Parse and map an interrupt into linux virq space * @device: Device node of the device whose interrupt is to be mapped @@ -44,7 +39,7 @@ unsigned int irq_of_parse_and_map(struct device_node *dev, int index) struct of_irq oirq; if (of_irq_map_one(dev, index, &oirq)) - return NO_IRQ; + return 0; return irq_create_of_mapping(oirq.controller, oirq.specifier, oirq.size); @@ -345,7 +340,7 @@ int of_irq_to_resource(struct device_node *dev, int index, struct resource *r) /* Only dereference the resource if both the * resource and the irq are valid. */ - if (r && irq != NO_IRQ) { + if (r && irq) { r->start = r->end = irq; r->flags = IORESOURCE_IRQ; r->name = dev->full_name; @@ -363,7 +358,7 @@ int of_irq_count(struct device_node *dev) { int nr = 0; - while (of_irq_to_resource(dev, nr, NULL) != NO_IRQ) + while (of_irq_to_resource(dev, nr, NULL)) nr++; return nr; @@ -383,7 +378,7 @@ int of_irq_to_resource_table(struct device_node *dev, struct resource *res, int i; for (i = 0; i < nr_irqs; i++, res++) - if (of_irq_to_resource(dev, i, res) == NO_IRQ) + if (!of_irq_to_resource(dev, i, res)) break; return i; -- cgit