From patchwork Sat Nov 23 00:43:35 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tony Lindgren X-Patchwork-Id: 3224631 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 1D9B89F26C for ; Sat, 23 Nov 2013 00:44:18 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 3F0E420796 for ; Sat, 23 Nov 2013 00:44:17 +0000 (UTC) Received: from casper.infradead.org (casper.infradead.org [85.118.1.10]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 370F620635 for ; Sat, 23 Nov 2013 00:44:16 +0000 (UTC) Received: from merlin.infradead.org ([2001:4978:20e::2]) by casper.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1Vk1KR-00087x-6v; Sat, 23 Nov 2013 00:44:07 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1Vk1KO-0008D2-Vn; Sat, 23 Nov 2013 00:44:04 +0000 Received: from mho-02-ewr.mailhop.org ([204.13.248.72]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1Vk1KM-0008Ci-5O for linux-arm-kernel@lists.infradead.org; Sat, 23 Nov 2013 00:44:02 +0000 Received: from c-50-131-214-131.hsd1.ca.comcast.net ([50.131.214.131] helo=localhost.localdomain) by mho-02-ewr.mailhop.org with esmtpa (Exim 4.72) (envelope-from ) id 1Vk1Jz-000Erd-FT; Sat, 23 Nov 2013 00:43:39 +0000 Received: from Mutt by mutt-smtp-wrapper.pl 1.2 (www.zdo.com/articles/mutt-smtp-wrapper.shtml) X-Mail-Handler: Dyn Standard SMTP by Dyn X-Originating-IP: 50.131.214.131 X-Report-Abuse-To: abuse@dyndns.com (see http://www.dyndns.com/services/sendlabs/outbound_abuse.html for abuse reporting information) X-MHO-User: U2FsdGVkX1+l4BSk2qImFwSaY3ZmYyB8 Date: Fri, 22 Nov 2013 16:43:35 -0800 From: Tony Lindgren To: Grant Likely , Rob Herring Subject: [PATCH] of/platform: Fix no irq domain found errors when populating interrupts Message-ID: <20131123004334.GJ10023@atomide.com> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.20 (2009-06-14) X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20131122_194402_211590_F2202A3C X-CRM114-Status: GOOD ( 15.96 ) X-Spam-Score: -1.9 (-) Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.7 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Currently we get the following kind of errors if we try to use interrupt phandles to irqchips that have not yet initialized: irq: no irq domain found for /ocp/pinmux@48002030 ! WARNING: CPU: 0 PID: 1 at drivers/of/platform.c:171 of_device_alloc+0x144/0x184() Modules linked in: CPU: 0 PID: 1 Comm: swapper/0 Not tainted 3.12.0-00038-g42a9708 #1012 (show_stack+0x14/0x1c) (dump_stack+0x6c/0xa0) (warn_slowpath_common+0x64/0x84) (warn_slowpath_null+0x1c/0x24) (of_device_alloc+0x144/0x184) (of_platform_device_create_pdata+0x44/0x9c) (of_platform_bus_create+0xd0/0x170) (of_platform_bus_create+0x12c/0x170) (of_platform_populate+0x60/0x98) ... This is because we're wrongly trying to populate resources that are not yet available. It's perfectly valid to create irqchips dynamically, so let's fix up the issue by populating the interrupt resources based on a notifier call instead. Signed-off-by: Tony Lindgren --- Rob & Grant, care to merge this for the -rc if this looks OK to you? These happen for example when using interrupts-extended for omap wake-up interrupts where the irq domain is created by pinctrl-single.c at module_init time. --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -130,6 +130,56 @@ void of_device_make_bus_id(struct device *dev) dev_set_name(dev, "%s.%d", node->name, magic - 1); } +/* + * The device interrupts are not necessarily available for all + * irqdomains initially so we need to populate them using a + * notifier. + */ +static int of_device_resource_notify(struct notifier_block *nb, + unsigned long event, void *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct device_node *np = pdev->dev.of_node; + struct resource *res = pdev->resource; + struct resource *irqr = NULL; + int num_irq, i, found = 0; + + if (event != BUS_NOTIFY_BIND_DRIVER) + return 0; + + if (!np) + goto out; + + num_irq = of_irq_count(np); + if (!num_irq) + goto out; + + for (i = 0; i < pdev->num_resources; i++, res++) { + if (res->flags != IORESOURCE_IRQ || + res->start != -EPROBE_DEFER || + res->end != -EPROBE_DEFER) + continue; + + if (!irqr) + irqr = res; + found++; + } + + if (!found) + goto out; + + if (found != num_irq) { + dev_WARN(dev, "error populating irq resources: %i != %i\n", + found, num_irq); + goto out; + } + + WARN_ON(of_irq_to_resource_table(np, irqr, num_irq) != num_irq); + +out: + return NOTIFY_DONE; +} + /** * of_device_alloc - Allocate and initialize an of_device * @np: device node to assign to device @@ -168,7 +218,13 @@ struct platform_device *of_device_alloc(struct device_node *np, rc = of_address_to_resource(np, i, res); WARN_ON(rc); } - WARN_ON(of_irq_to_resource_table(np, res, num_irq) != num_irq); + + /* See of_device_resource_notify for populating interrupts */ + for (i = 0; i < num_irq; i++, res++) { + res->flags = IORESOURCE_IRQ; + res->start = -EPROBE_DEFER; + res->end = -EPROBE_DEFER; + } } dev->dev.of_node = of_node_get(np); @@ -447,6 +503,8 @@ int of_platform_bus_probe(struct device_node *root, } EXPORT_SYMBOL(of_platform_bus_probe); +static struct notifier_block resource_nb; + /** * of_platform_populate() - Populate platform_devices from device tree data * @root: parent of the first level to probe or NULL for the root of the tree @@ -478,6 +536,11 @@ int of_platform_populate(struct device_node *root, if (!root) return -EINVAL; + if (!resource_nb.notifier_call) { + resource_nb.notifier_call = of_device_resource_notify, + bus_register_notifier(&platform_bus_type, &resource_nb); + } + for_each_child_of_node(root, child) { rc = of_platform_bus_create(child, matches, lookup, parent, true); if (rc)