From patchwork Thu Nov 28 15:46:23 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thierry Reding X-Patchwork-Id: 3255051 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 5FB2DC045B for ; Thu, 28 Nov 2013 15:47:45 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 0A724205F4 for ; Thu, 28 Nov 2013 15:47:44 +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 8D62E205E7 for ; Thu, 28 Nov 2013 15:47:42 +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 1Vm3oX-0004J5-22; Thu, 28 Nov 2013 15:47:37 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1Vm3oU-0006KP-NH; Thu, 28 Nov 2013 15:47:34 +0000 Received: from mail-bk0-x22d.google.com ([2a00:1450:4008:c01::22d]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1Vm3oR-0006JK-OK for linux-arm-kernel@lists.infradead.org; Thu, 28 Nov 2013 15:47:32 +0000 Received: by mail-bk0-f45.google.com with SMTP id mx13so3835118bkb.4 for ; Thu, 28 Nov 2013 07:47:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=date:from:to:cc:subject:message-id:references:mime-version :content-type:content-disposition:in-reply-to:user-agent; bh=UkVvbktBblTGFyZwfj1w2IEGzDe9tTMf1LSZ2tiKSbE=; b=01cfpsKrSv3AoadmmLj9WVrkPAKpzWvvidD1K/wlxWSQK/IbxmhIFQTNwVUJ1lftzc +5AVIUULrS7lmFYMbMHq7d8lHniWfYd5pZucfk/xaXUi00DypoylQ6Wmkft/N3UiSBDP CX7Q9wej/PdRVYX585hUuucHEGnVyRCR7yjmBPoQ28v488znD4o+41+foOrO0cdoYPjz a6JJbTeH6hPxbirn0b9DqTDMyTFBO8wJeqX4KGSPTBskfXkGjobhpJFq4Wk0sabCJoZu Geh2eOYBep1nM93i6AnniYHdrS9iSBJzyStVCmAKle1QAtkbO4PI1dWkkYO3mxl4m0pS 1tLA== X-Received: by 10.204.166.15 with SMTP id k15mr91577bky.78.1385653628211; Thu, 28 Nov 2013 07:47:08 -0800 (PST) Received: from localhost (port-2717.pppoe.wtnet.de. [84.46.10.167]) by mx.google.com with ESMTPSA id w9sm60151012bkn.12.2013.11.28.07.47.06 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 28 Nov 2013 07:47:07 -0800 (PST) Date: Thu, 28 Nov 2013 16:46:23 +0100 From: Thierry Reding To: Grant Likely Subject: Re: [PATCH] of/platform: Fix no irq domain found errors when populating interrupts Message-ID: <20131128154622.GB23201@ulmo.nvidia.com> References: <20131123004334.GJ10023@atomide.com> <20131124213651.59750C402C3@trevor.secretlab.ca> <20131125092549.GD22043@ulmo.nvidia.com> <20131125094954.GF22043@ulmo.nvidia.com> <20131127155629.DB612C404EC@trevor.secretlab.ca> MIME-Version: 1.0 In-Reply-To: <20131127155629.DB612C404EC@trevor.secretlab.ca> User-Agent: Mutt/1.5.22 (2013-10-16) X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20131128_104732_040840_B75C0EF2 X-CRM114-Status: GOOD ( 45.85 ) X-Spam-Score: -2.0 (--) Cc: Tony Lindgren , 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.1 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=ham 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 On Wed, Nov 27, 2013 at 03:56:29PM +0000, Grant Likely wrote: > On Mon, 25 Nov 2013 10:49:55 +0100, Thierry Reding wrote: > > On Mon, Nov 25, 2013 at 10:25:50AM +0100, Thierry Reding wrote: > > > On Sun, Nov 24, 2013 at 09:36:51PM +0000, Grant Likely wrote: > > > > On Fri, 22 Nov 2013 16:43:35 -0800, Tony Lindgren wrote: > > > > > 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; > > > > > + } > > > > > > > > I actually like the idea of completely allocating the resource structure > > > > but leaving some entries empty. However, I agree with rmk that putting > > > > garbage into a resource structure is a bad idea. What about changing the > > > > value of flags to 0 or some other value to be obviously an empty > > > > property and give the follow up parsing some context about which ones it > > > > needs to attempt to recalculate? > > > > > > When I worked on this a while back I came to the same conclusion. It's > > > nice to allocate all the resources at once, because the number of them > > > doesn't change, only their actually values. > > > > I should maybe add: one issue that was raised during review of my > > initial patch series was that we'll also need to cope with situations > > like the following: > > > > 1) device's interrupt parent is probed (assigned IRQ base X) > > 2) device is probed (interrupt parent there, therefore gets > > assigned IRQ (X + z) > > 3) device in removed > > 4) device's interrupt parent is removed > > 5) device is probed (deferred because interrupt parent isn't > > there) > > 6) device's interrupt parent is probed (assigned IRQ base Y) > > 7) device is probed, gets assigned IRQ (Y + z) > > > > So not only do we have to track which resources are interrupt resources, > > but we also need to have them reassigned everytime the device is probed, > > therefore interrupt mappings need to be properly disposed and the values > > invalidated when probing is deferred or the device removed. > > Yes, that is a problem, but the only way to handle that is to always > recalcuate all resource references at probe time. I don't feel good > about handling that in the core. I'd rather move drivers away from > referencing the resources table directly and instead use an API. Then > the resources table could be missing entirely. Are you suggesting something like this? diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 3a94b799f166..c894d1af3a5e 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -87,7 +88,12 @@ int platform_get_irq(struct platform_device *dev, unsigned int num) return -ENXIO; return dev->archdata.irqs[num]; #else - struct resource *r = platform_get_resource(dev, IORESOURCE_IRQ, num); + struct resource *r; + + if (IS_ENABLED(CONFIG_OF) && dev->dev.of_node) + return irq_of_parse_and_map(dev->dev.of_node, num); + + r = platform_get_resource(dev, IORESOURCE_IRQ, num); return r ? r->start : -ENXIO; #endif