+++ /dev/null
-From 9ec36cafe43bf835f8f29273597a5b0cbc8267ef Mon Sep 17 00:00:00 2001
-From: Rob Herring <robh@kernel.org>
-Date: Wed, 23 Apr 2014 17:57:41 -0500
-Subject: of/irq: do irq resolution in platform_get_irq
-
-From: Rob Herring <robh@kernel.org>
-
-commit 9ec36cafe43bf835f8f29273597a5b0cbc8267ef upstream.
-
-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 !
-------------[ cut here ]------------
-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 resolving the interrupt resources when
-platform_get_irq is called.
-
-And then we also need to accept the fact that some irqdomains do not
-exist that early on, and only get initialized later on. So we can
-make the current WARN_ON into just into a pr_debug().
-
-We still attempt to populate irq resources when we create the devices.
-This allows current drivers which don't use platform_get_irq to continue
-to function. Once all drivers are fixed, this code can be removed.
-
-Suggested-by: Russell King <linux@arm.linux.org.uk>
-Signed-off-by: Rob Herring <robh@kernel.org>
-Signed-off-by: Tony Lindgren <tony@atomide.com>
-Tested-by: Tony Lindgren <tony@atomide.com>
-Signed-off-by: Grant Likely <grant.likely@linaro.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
----
- drivers/base/platform.c | 7 ++++++-
- drivers/of/irq.c | 26 ++++++++++++++++++++++++++
- drivers/of/platform.c | 4 +++-
- include/linux/of_irq.h | 6 ++++++
- 4 files changed, 41 insertions(+), 2 deletions(-)
-
---- 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>
-@@ -90,7 +91,11 @@ int platform_get_irq(struct platform_dev
- 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
---- a/drivers/of/irq.c
-+++ b/drivers/of/irq.c
-@@ -362,6 +362,32 @@ int of_irq_to_resource(struct device_nod
- 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 rc;
-+ struct of_phandle_args oirq;
-+ struct irq_domain *domain;
-+
-+ rc = of_irq_parse_one(dev, index, &oirq);
-+ if (rc)
-+ return rc;
-+
-+ domain = irq_find_host(oirq.np);
-+ if (!domain)
-+ return -EPROBE_DEFER;
-+
-+ return irq_create_of_mapping(&oirq);
-+}
-+
-+/**
- * of_irq_count - Count the number of IRQs a node uses
- * @dev: pointer to device tree node
- */
---- a/drivers/of/platform.c
-+++ b/drivers/of/platform.c
-@@ -168,7 +168,9 @@ struct platform_device *of_device_alloc(
- rc = of_address_to_resource(np, i, res);
- WARN_ON(rc);
- }
-- WARN_ON(of_irq_to_resource_table(np, res, num_irq) != num_irq);
-+ if (of_irq_to_resource_table(np, res, num_irq) != num_irq)
-+ pr_debug("not all legacy IRQ resources mapped for %s\n",
-+ np->name);
- }
-
- dev->dev.of_node = of_node_get(np);
---- a/include/linux/of_irq.h
-+++ b/include/linux/of_irq.h
-@@ -69,6 +69,7 @@ extern unsigned int irq_create_of_mappin
- extern int of_irq_to_resource(struct device_node *dev, int index,
- struct resource *r);
- extern int of_irq_count(struct device_node *dev);
-+extern int of_irq_get(struct device_node *dev, int index);
- extern int of_irq_to_resource_table(struct device_node *dev,
- struct resource *res, int nr_irqs);
- extern struct device_node *of_irq_find_parent(struct device_node *child);
-@@ -88,6 +89,11 @@ static inline void *of_irq_find_parent(s
- {
- return NULL;
- }
-+
-+static inline int of_irq_get(struct device_node *dev, int index)
-+{
-+ return 0;
-+}
- #endif /* !CONFIG_OF */
-
- #endif /* __OF_IRQ_H */