[PATCH v3 2/2] dt: platform driver: Fill the resources before probe and defer if needed
Russell King - ARM Linux
linux at arm.linux.org.uk
Wed Apr 23 10:38:54 PDT 2014
On Mon, Apr 21, 2014 at 02:01:05PM -0500, Rob Herring wrote:
> Ah, right. Except for those drivers you need to work with deferred probe
> would have to use platform_get_irq. That fact makes this solution quite
> a bit easier.
>
> Something like this is what you had in mind?
The below is what I had in mind... :) This moves it to the right place
for deferred probing to work - the alternative is we need some way to
"register" a device which can't be probed immediately, track it's
resources, have some way for it to be notified when those resources
become available (or poll for them becoming available... eg at the
same time as the deferred probing trigger) and then make it properly
available to drivers. That brings up all sorts of questions about
whether it should be registered in sysfs, what if another device with
the same name comes along, etc.
So the solution below is very much a simple and nice solution to the
problem - it makes full use of our existing infrastructure to deal with
the problem.
> diff --git a/drivers/base/platform.c b/drivers/base/platform.c
> index e714709..5b47210 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,11 @@ 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_IRQ) && dev->dev.of_node)
> + return of_irq_get(dev->dev.of_node, num);
> +
> + r = platform_get_resource(dev, IORESOURCE_IRQ, num);
>
> return r ? r->start : -ENXIO;
> #endif
> diff --git a/drivers/of/irq.c b/drivers/of/irq.c
> index 7d3184f..30449ad 100644
> --- a/drivers/of/irq.c
> +++ b/drivers/of/irq.c
> @@ -400,6 +400,26 @@ int of_irq_to_resource(struct device_node *dev, int
> index, struct resource *r)
> EXPORT_SYMBOL_GPL(of_irq_to_resource);
>
> /**
> + * of_irq_get - Decode a node's IRQ and return it as a Linux irq number
> + * @dev: pointer to device tree node
> + * @index: zero-based index of the irq
> + *
> + * Returns Linux irq number on success, or -EPROBE_DEFER if the irq domain
> + * is not yet created.
> + *
> + */
> +int of_irq_get(struct device_node *dev, int index)
> +{
> + int irq = irq_of_parse_and_map(dev, index);
> +
> + if (!irq && of_find_irq_domain(dev, index) == NULL)
> + return -EPROBE_DEFER;
> +
> + return irq;
> +}
> +EXPORT_SYMBOL_GPL(of_irq_get);
> +
> +/**
> * of_irq_count - Count the number of IRQs a node uses
> * @dev: pointer to device tree node
> */
--
FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly
improving, and getting towards what was expected from it.
More information about the linux-arm-kernel
mailing list