From patchwork Sat Nov 23 01:50: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: 3224831 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 9A859C045B for ; Sat, 23 Nov 2013 01:51:17 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id A8FCA20717 for ; Sat, 23 Nov 2013 01:51:16 +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 9FE4320709 for ; Sat, 23 Nov 2013 01:51:15 +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 1Vk2NH-0004Ik-LL; Sat, 23 Nov 2013 01:51: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 1Vk2NF-0000pU-5a; Sat, 23 Nov 2013 01:51:05 +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 1Vk2NC-0000op-J0 for linux-arm-kernel@lists.infradead.org; Sat, 23 Nov 2013 01:51:03 +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 1Vk2Mp-000LEL-PF; Sat, 23 Nov 2013 01:50:40 +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: U2FsdGVkX18SP4Fai/RxRHoiZNAJzp6V Date: Fri, 22 Nov 2013 17:50:35 -0800 From: Tony Lindgren To: Russell King - ARM Linux Subject: Re: [PATCH] of/platform: Fix no irq domain found errors when populating interrupts Message-ID: <20131123015034.GP10023@atomide.com> References: <20131123004334.GJ10023@atomide.com> <20131123005509.GJ16735@n2100.arm.linux.org.uk> <20131123010850.GN10023@atomide.com> <20131123011515.GO10023@atomide.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20131123011515.GO10023@atomide.com> 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_205102_650130_DD2B0D63 X-CRM114-Status: GOOD ( 24.52 ) X-Spam-Score: -1.9 (-) Cc: Grant Likely , devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Rob Herring , 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 * Tony Lindgren [131122 17:16]: > * Tony Lindgren [131122 17:09]: > > * Russell King - ARM Linux [131122 16:56]: > > > On Fri, Nov 22, 2013 at 04:43:35PM -0800, Tony Lindgren wrote: > > > > + /* 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; > > > > > > NAK. Definitely a bad idea to start introducing magic values other into > > > resources. Please don't do this. > > > > Do you have any better ideas on how to sort out this issue then? > > I guess we could allocate all the resources lazily here, I'll take a look > at that. Here's a version that allocates the resources lazily with the notifier. Seems to boot, need to play with it a bit more though to make sure we're not overwriting resources for any legacy devices. Regards, Tony --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -141,13 +141,47 @@ struct platform_device *of_device_alloc(struct device_node *np, struct device *parent) { struct platform_device *dev; - int rc, i, num_reg = 0, num_irq; - struct resource *res, temp_res; dev = platform_device_alloc("", -1); if (!dev) return NULL; + dev->dev.of_node = of_node_get(np); +#if defined(CONFIG_MICROBLAZE) + dev->dev.dma_mask = &dev->archdata.dma_mask; +#endif + dev->dev.parent = parent; + + if (bus_id) + dev_set_name(&dev->dev, "%s", bus_id); + else + of_device_make_bus_id(&dev->dev); + + /* See of_device_resource_notify for populating the resources */ + + return dev; +} +EXPORT_SYMBOL(of_device_alloc); + +/* + * 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; + int rc, i, num_reg = 0, num_irq; + struct resource *res, temp_res; + + if (event != BUS_NOTIFY_BIND_DRIVER) + return 0; + + if (!np) + goto out; + /* count the io and irq resources */ if (of_can_translate_address(np)) while (of_address_to_resource(np, num_reg, &temp_res) == 0) @@ -158,12 +192,12 @@ struct platform_device *of_device_alloc(struct device_node *np, if (num_irq || num_reg) { res = kzalloc(sizeof(*res) * (num_irq + num_reg), GFP_KERNEL); if (!res) { - platform_device_put(dev); - return NULL; + platform_device_put(pdev); + goto out; } - dev->num_resources = num_reg + num_irq; - dev->resource = res; + pdev->num_resources = num_reg + num_irq; + pdev->resource = res; for (i = 0; i < num_reg; i++, res++) { rc = of_address_to_resource(np, i, res); WARN_ON(rc); @@ -171,20 +205,9 @@ struct platform_device *of_device_alloc(struct device_node *np, WARN_ON(of_irq_to_resource_table(np, res, num_irq) != num_irq); } - dev->dev.of_node = of_node_get(np); -#if defined(CONFIG_MICROBLAZE) - dev->dev.dma_mask = &dev->archdata.dma_mask; -#endif - dev->dev.parent = parent; - - if (bus_id) - dev_set_name(&dev->dev, "%s", bus_id); - else - of_device_make_bus_id(&dev->dev); - - return dev; +out: + return NOTIFY_DONE; } -EXPORT_SYMBOL(of_device_alloc); /** * of_platform_device_create_pdata - Alloc, initialize and register an of_device @@ -447,6 +470,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 +503,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)