public inbox for linux-arm-kernel@lists.infradead.org 
 help / color / mirror / Atom feed
From: thierry.reding@gmail•com (Thierry Reding)
To: linux-arm-kernel@lists•infradead.org
Subject: [PATCH] of/platform: Fix no irq domain found errors when populating interrupts
Date: Thu, 28 Nov 2013 16:46:23 +0100	[thread overview]
Message-ID: <20131128154622.GB23201@ulmo.nvidia.com> (raw)
In-Reply-To: <20131127155629.DB612C404EC@trevor.secretlab.ca>

On Wed, Nov 27, 2013 at 03:56:29PM +0000, Grant Likely wrote:
> On Mon, 25 Nov 2013 10:49:55 +0100, Thierry Reding <thierry.reding@gmail•com> 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 <tony@atomide•com> 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 at 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 <tony@atomide•com>
> > > > > 
> > > > > ---
> > > > > 
> > > > > 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 <linux/string.h>
 #include <linux/platform_device.h>
 #include <linux/of_device.h>
+#include <linux/of_irq.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/dma-mapping.h>
@@ -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
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20131128/9007f9ca/attachment.sig>

  reply	other threads:[~2013-11-28 15:46 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-11-23  0:43 [PATCH] of/platform: Fix no irq domain found errors when populating interrupts Tony Lindgren
2013-11-23  0:55 ` Russell King - ARM Linux
2013-11-23  1:08   ` Tony Lindgren
2013-11-23  1:15     ` Tony Lindgren
2013-11-23  1:50       ` Tony Lindgren
2013-11-23 15:42         ` Rob Herring
2013-11-23 16:32           ` Tony Lindgren
2013-11-25  9:34             ` Thierry Reding
2013-11-25 19:46               ` Tony Lindgren
2013-11-24 21:27         ` Grant Likely
2013-12-10  3:39           ` Paul Walmsley
2013-12-30 22:10             ` Paul Walmsley
2013-12-31 16:33               ` Rob Herring
2014-01-06 23:41                 ` Paul Walmsley
2014-01-08  1:19                   ` Tony Lindgren
2014-01-08 12:51                     ` [PATCH] driver-core: platform: Resolve DT interrupt references late Thierry Reding
2014-01-08 13:41                       ` Arnd Bergmann
2014-01-08 14:55                         ` Thierry Reding
2014-01-08 15:11                           ` Arnd Bergmann
2014-01-08 15:58                             ` Thierry Reding
2014-01-08 16:25                               ` Arnd Bergmann
2014-01-08 19:59                                 ` Thierry Reding
2014-01-08 20:09                                   ` Arnd Bergmann
2014-01-08 20:24                                     ` Thierry Reding
2014-01-08 21:01                                       ` Arnd Bergmann
2014-01-08 16:40                       ` Tony Lindgren
2014-01-08 19:28                         ` Thierry Reding
2014-01-08 21:43                           ` Tony Lindgren
2013-11-23  1:07 ` [PATCH] of/platform: Fix no irq domain found errors when populating interrupts Tony Lindgren
2013-11-24 21:36 ` Grant Likely
2013-11-25  9:25   ` Thierry Reding
     [not found]     ` < 20131125094954.GF22043@ulmo.nvidia.com>
2013-11-25  9:49     ` Thierry Reding
2013-11-25 19:50       ` Tony Lindgren
2013-11-27 15:56       ` Grant Likely
2013-11-28 15:46         ` Thierry Reding [this message]
2013-12-11 13:45           ` Grant Likely
2013-12-11 15:12             ` Thierry Reding
2013-12-11 16:43               ` Tony Lindgren
2013-11-27 15:54     ` Grant Likely
2013-11-27 21:53   ` Tony Lindgren

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20131128154622.GB23201@ulmo.nvidia.com \
    --to=thierry.reding@gmail$(echo .)com \
    --cc=linux-arm-kernel@lists$(echo .)infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox