* [PATCH 1/2] ARM: vic: device tree binding
@ 2011-09-27 12:16 ` Jamie Iles
0 siblings, 0 replies; 16+ messages in thread
From: Jamie Iles @ 2011-09-27 12:16 UTC (permalink / raw)
To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ
This adds a device tree binding for the VIC based on the of_irq_init()
support.
Cc: Rob Herring <robherring2-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Signed-off-by: Jamie Iles <jamie-wmLquQDDieKakBO8gow8eQ@public.gmane.org>
---
Documentation/devicetree/bindings/arm/vic.txt | 29 ++++++
arch/arm/common/vic.c | 121 ++++++++++++++++++++-----
arch/arm/include/asm/hardware/vic.h | 13 +++-
3 files changed, 137 insertions(+), 26 deletions(-)
create mode 100644 Documentation/devicetree/bindings/arm/vic.txt
diff --git a/Documentation/devicetree/bindings/arm/vic.txt b/Documentation/devicetree/bindings/arm/vic.txt
new file mode 100644
index 0000000..266716b
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/vic.txt
@@ -0,0 +1,29 @@
+* ARM Vectored Interrupt Controller
+
+One or more Vectored Interrupt Controllers (VIC's) can be connected in an ARM
+system for interrupt routing. For multiple controllers they can either be
+nested or have the outputs wire-OR'd together.
+
+Required properties:
+
+- compatible : should be one of
+ "arm,pl190-vic"
+ "arm,pl192-vic"
+- interrupt-controller : Identifies the node as an interrupt controller
+- #interrupt-cells : The number of cells to define the interrupts. Must be 1 as
+ the VIC has no configuration options for interrupt sources. The cell is a u32
+ and defines the interrupt number.
+- reg : The register bank for the VIC.
+
+Optional properties:
+
+- interrupts : Interrupt source for parent controllers if the VIC is nested.
+
+Example:
+
+ vic0: interrupt-controller@60000 {
+ compatible = "arm,pl192-vic";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0x60000 0x1000>;
+ };
diff --git a/arch/arm/common/vic.c b/arch/arm/common/vic.c
index 7aa4262..3658579 100644
--- a/arch/arm/common/vic.c
+++ b/arch/arm/common/vic.c
@@ -22,6 +22,10 @@
#include <linux/init.h>
#include <linux/list.h>
#include <linux/io.h>
+#include <linux/irqdomain.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
#include <linux/syscore_ops.h>
#include <linux/device.h>
#include <linux/amba/bus.h>
@@ -29,7 +33,6 @@
#include <asm/mach/irq.h>
#include <asm/hardware/vic.h>
-#ifdef CONFIG_PM
/**
* struct vic_device - VIC PM device
* @irq: The IRQ number for the base of the VIC.
@@ -50,13 +53,15 @@ struct vic_device {
u32 int_enable;
u32 soft_int;
u32 protect;
+#ifdef CONFIG_IRQ_DOMAIN
+ struct irq_domain domain;
+#endif /* CONFIG_IRQ_DOMAIN */
};
/* we cannot allocate memory when VICs are initially registered */
static struct vic_device vic_devices[CONFIG_ARM_VIC_NR];
static int vic_id;
-#endif /* CONFIG_PM */
/**
* vic_init2 - common initialisation code
@@ -156,9 +161,10 @@ static int __init vic_pm_init(void)
return 0;
}
late_initcall(vic_pm_init);
+#endif /* CONFIG_PM */
/**
- * vic_pm_register - Register a VIC for later power management control
+ * vic_register - Register a VIC.
* @base: The base address of the VIC.
* @irq: The base IRQ for the VIC.
* @resume_sources: bitmask of interrupts allowed for resume sources.
@@ -166,24 +172,28 @@ late_initcall(vic_pm_init);
* Register the VIC with the system device tree so that it can be notified
* of suspend and resume requests and ensure that the correct actions are
* taken to re-instate the settings on resume.
+ *
+ * We return the VIC so that it can be used for IRQ domain operations for
+ * device tree translation.
*/
-static void __init vic_pm_register(void __iomem *base, unsigned int irq, u32 resume_sources)
+static struct vic_device * __init
+vic_register(void __iomem *base, unsigned int irq, u32 resume_sources)
{
struct vic_device *v;
- if (vic_id >= ARRAY_SIZE(vic_devices))
+ if (vic_id >= ARRAY_SIZE(vic_devices)) {
printk(KERN_ERR "%s: too few VICs, increase CONFIG_ARM_VIC_NR\n", __func__);
- else {
- v = &vic_devices[vic_id];
- v->base = base;
- v->resume_sources = resume_sources;
- v->irq = irq;
- vic_id++;
+ return NULL;
}
+
+ v = &vic_devices[vic_id];
+ v->base = base;
+ v->resume_sources = resume_sources;
+ v->irq = irq;
+ vic_id++;
+
+ return v;
}
-#else
-static inline void vic_pm_register(void __iomem *base, unsigned int irq, u32 arg1) { }
-#endif /* CONFIG_PM */
static void vic_ack_irq(struct irq_data *d)
{
@@ -331,15 +341,9 @@ static void __init vic_init_st(void __iomem *base, unsigned int irq_start,
vic_set_irq_sources(base, irq_start, vic_sources);
}
-/**
- * vic_init - initialise a vectored interrupt controller
- * @base: iomem base address
- * @irq_start: starting interrupt number, must be muliple of 32
- * @vic_sources: bitmask of interrupt sources to allow
- * @resume_sources: bitmask of interrupt sources to allow for resume
- */
-void __init vic_init(void __iomem *base, unsigned int irq_start,
- u32 vic_sources, u32 resume_sources)
+static struct vic_device * __init
+__vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources,
+ u32 resume_sources)
{
unsigned int i;
u32 cellid = 0;
@@ -357,7 +361,7 @@ void __init vic_init(void __iomem *base, unsigned int irq_start,
switch(vendor) {
case AMBA_VENDOR_ST:
vic_init_st(base, irq_start, vic_sources);
- return;
+ return NULL;
default:
printk(KERN_WARNING "VIC: unknown vendor, continuing anyways\n");
/* fall through */
@@ -375,5 +379,72 @@ void __init vic_init(void __iomem *base, unsigned int irq_start,
vic_set_irq_sources(base, irq_start, vic_sources);
- vic_pm_register(base, irq_start, resume_sources);
+ return vic_register(base, irq_start, resume_sources);
}
+
+/**
+ * vic_init - initialise a vectored interrupt controller
+ * @base: iomem base address
+ * @irq_start: starting interrupt number, must be muliple of 32
+ * @vic_sources: bitmask of interrupt sources to allow
+ * @resume_sources: bitmask of interrupt sources to allow for resume
+ */
+void __init vic_init(void __iomem *base, unsigned int irq_start,
+ u32 vic_sources, u32 resume_sources)
+{
+ __vic_init(base, irq_start, vic_sources, resume_sources);
+}
+
+#ifdef CONFIG_OF
+static int
+vic_irq_domain_dt_translate(struct irq_domain *d, struct device_node *np,
+ const u32 *intspec, unsigned int intsize,
+ unsigned long *out_hwirq, unsigned int *out_type)
+{
+ if (d->of_node != np)
+ return -EINVAL;
+ if (intsize < 1)
+ return -EINVAL;
+
+ *out_hwirq = intspec[0];
+ *out_type = IRQ_TYPE_NONE;
+
+ return 0;
+}
+
+static const struct irq_domain_ops vic_irq_domain_ops = {
+ .dt_translate = vic_irq_domain_dt_translate,
+};
+
+int __init vic_of_init(struct device_node *node, struct device_node *parent)
+{
+ void __iomem *regs = of_iomap(node, 0);
+ struct vic_device *vic;
+ int irq_base;
+
+ if (WARN_ON(!regs))
+ return -EIO;
+
+ irq_base = irq_alloc_descs(-1, 0, 32, numa_node_id());
+ if (WARN_ON(irq_base < 0))
+ goto out_unmap;
+
+ vic = __vic_init(regs, irq_base, ~0, ~0);
+ if (WARN_ON(!vic))
+ goto out_unmap;
+
+ vic->domain.irq_base = irq_base;
+ vic->domain.nr_irq = 32;
+ vic->domain.of_node = of_node_get(node);
+ vic->domain.ops = &vic_irq_domain_ops;
+ irq_domain_add(&vic->domain);
+
+ return 0;
+
+out_unmap:
+ iounmap(regs);
+
+ return -EIO;
+}
+
+#endif /* CONFIG OF */
diff --git a/arch/arm/include/asm/hardware/vic.h b/arch/arm/include/asm/hardware/vic.h
index 5d72550..df1d895 100644
--- a/arch/arm/include/asm/hardware/vic.h
+++ b/arch/arm/include/asm/hardware/vic.h
@@ -41,7 +41,18 @@
#define VIC_PL192_VECT_ADDR 0xF00
#ifndef __ASSEMBLY__
+struct device_node;
void vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources, u32 resume_sources);
-#endif
+
+#ifdef CONFIG_OF
+int vic_of_init(struct device_node *node, struct device_node *parent);
+#else /* CONFIG_OF */
+static inline int vic_of_init(struct device_node *node,
+ struct device_node *parent)
+{
+ return -ENOSYS;
+}
+#endif /* CONFIG_OF */
+#endif /* __ASSEMBLY__ */
#endif
--
1.7.4.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 1/2] ARM: vic: device tree binding
@ 2011-09-27 12:16 ` Jamie Iles
0 siblings, 0 replies; 16+ messages in thread
From: Jamie Iles @ 2011-09-27 12:16 UTC (permalink / raw)
To: linux-arm-kernel
This adds a device tree binding for the VIC based on the of_irq_init()
support.
Cc: Rob Herring <robherring2@gmail.com>
Signed-off-by: Jamie Iles <jamie@jamieiles.com>
---
Documentation/devicetree/bindings/arm/vic.txt | 29 ++++++
arch/arm/common/vic.c | 121 ++++++++++++++++++++-----
arch/arm/include/asm/hardware/vic.h | 13 +++-
3 files changed, 137 insertions(+), 26 deletions(-)
create mode 100644 Documentation/devicetree/bindings/arm/vic.txt
diff --git a/Documentation/devicetree/bindings/arm/vic.txt b/Documentation/devicetree/bindings/arm/vic.txt
new file mode 100644
index 0000000..266716b
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/vic.txt
@@ -0,0 +1,29 @@
+* ARM Vectored Interrupt Controller
+
+One or more Vectored Interrupt Controllers (VIC's) can be connected in an ARM
+system for interrupt routing. For multiple controllers they can either be
+nested or have the outputs wire-OR'd together.
+
+Required properties:
+
+- compatible : should be one of
+ "arm,pl190-vic"
+ "arm,pl192-vic"
+- interrupt-controller : Identifies the node as an interrupt controller
+- #interrupt-cells : The number of cells to define the interrupts. Must be 1 as
+ the VIC has no configuration options for interrupt sources. The cell is a u32
+ and defines the interrupt number.
+- reg : The register bank for the VIC.
+
+Optional properties:
+
+- interrupts : Interrupt source for parent controllers if the VIC is nested.
+
+Example:
+
+ vic0: interrupt-controller at 60000 {
+ compatible = "arm,pl192-vic";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0x60000 0x1000>;
+ };
diff --git a/arch/arm/common/vic.c b/arch/arm/common/vic.c
index 7aa4262..3658579 100644
--- a/arch/arm/common/vic.c
+++ b/arch/arm/common/vic.c
@@ -22,6 +22,10 @@
#include <linux/init.h>
#include <linux/list.h>
#include <linux/io.h>
+#include <linux/irqdomain.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
#include <linux/syscore_ops.h>
#include <linux/device.h>
#include <linux/amba/bus.h>
@@ -29,7 +33,6 @@
#include <asm/mach/irq.h>
#include <asm/hardware/vic.h>
-#ifdef CONFIG_PM
/**
* struct vic_device - VIC PM device
* @irq: The IRQ number for the base of the VIC.
@@ -50,13 +53,15 @@ struct vic_device {
u32 int_enable;
u32 soft_int;
u32 protect;
+#ifdef CONFIG_IRQ_DOMAIN
+ struct irq_domain domain;
+#endif /* CONFIG_IRQ_DOMAIN */
};
/* we cannot allocate memory when VICs are initially registered */
static struct vic_device vic_devices[CONFIG_ARM_VIC_NR];
static int vic_id;
-#endif /* CONFIG_PM */
/**
* vic_init2 - common initialisation code
@@ -156,9 +161,10 @@ static int __init vic_pm_init(void)
return 0;
}
late_initcall(vic_pm_init);
+#endif /* CONFIG_PM */
/**
- * vic_pm_register - Register a VIC for later power management control
+ * vic_register - Register a VIC.
* @base: The base address of the VIC.
* @irq: The base IRQ for the VIC.
* @resume_sources: bitmask of interrupts allowed for resume sources.
@@ -166,24 +172,28 @@ late_initcall(vic_pm_init);
* Register the VIC with the system device tree so that it can be notified
* of suspend and resume requests and ensure that the correct actions are
* taken to re-instate the settings on resume.
+ *
+ * We return the VIC so that it can be used for IRQ domain operations for
+ * device tree translation.
*/
-static void __init vic_pm_register(void __iomem *base, unsigned int irq, u32 resume_sources)
+static struct vic_device * __init
+vic_register(void __iomem *base, unsigned int irq, u32 resume_sources)
{
struct vic_device *v;
- if (vic_id >= ARRAY_SIZE(vic_devices))
+ if (vic_id >= ARRAY_SIZE(vic_devices)) {
printk(KERN_ERR "%s: too few VICs, increase CONFIG_ARM_VIC_NR\n", __func__);
- else {
- v = &vic_devices[vic_id];
- v->base = base;
- v->resume_sources = resume_sources;
- v->irq = irq;
- vic_id++;
+ return NULL;
}
+
+ v = &vic_devices[vic_id];
+ v->base = base;
+ v->resume_sources = resume_sources;
+ v->irq = irq;
+ vic_id++;
+
+ return v;
}
-#else
-static inline void vic_pm_register(void __iomem *base, unsigned int irq, u32 arg1) { }
-#endif /* CONFIG_PM */
static void vic_ack_irq(struct irq_data *d)
{
@@ -331,15 +341,9 @@ static void __init vic_init_st(void __iomem *base, unsigned int irq_start,
vic_set_irq_sources(base, irq_start, vic_sources);
}
-/**
- * vic_init - initialise a vectored interrupt controller
- * @base: iomem base address
- * @irq_start: starting interrupt number, must be muliple of 32
- * @vic_sources: bitmask of interrupt sources to allow
- * @resume_sources: bitmask of interrupt sources to allow for resume
- */
-void __init vic_init(void __iomem *base, unsigned int irq_start,
- u32 vic_sources, u32 resume_sources)
+static struct vic_device * __init
+__vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources,
+ u32 resume_sources)
{
unsigned int i;
u32 cellid = 0;
@@ -357,7 +361,7 @@ void __init vic_init(void __iomem *base, unsigned int irq_start,
switch(vendor) {
case AMBA_VENDOR_ST:
vic_init_st(base, irq_start, vic_sources);
- return;
+ return NULL;
default:
printk(KERN_WARNING "VIC: unknown vendor, continuing anyways\n");
/* fall through */
@@ -375,5 +379,72 @@ void __init vic_init(void __iomem *base, unsigned int irq_start,
vic_set_irq_sources(base, irq_start, vic_sources);
- vic_pm_register(base, irq_start, resume_sources);
+ return vic_register(base, irq_start, resume_sources);
}
+
+/**
+ * vic_init - initialise a vectored interrupt controller
+ * @base: iomem base address
+ * @irq_start: starting interrupt number, must be muliple of 32
+ * @vic_sources: bitmask of interrupt sources to allow
+ * @resume_sources: bitmask of interrupt sources to allow for resume
+ */
+void __init vic_init(void __iomem *base, unsigned int irq_start,
+ u32 vic_sources, u32 resume_sources)
+{
+ __vic_init(base, irq_start, vic_sources, resume_sources);
+}
+
+#ifdef CONFIG_OF
+static int
+vic_irq_domain_dt_translate(struct irq_domain *d, struct device_node *np,
+ const u32 *intspec, unsigned int intsize,
+ unsigned long *out_hwirq, unsigned int *out_type)
+{
+ if (d->of_node != np)
+ return -EINVAL;
+ if (intsize < 1)
+ return -EINVAL;
+
+ *out_hwirq = intspec[0];
+ *out_type = IRQ_TYPE_NONE;
+
+ return 0;
+}
+
+static const struct irq_domain_ops vic_irq_domain_ops = {
+ .dt_translate = vic_irq_domain_dt_translate,
+};
+
+int __init vic_of_init(struct device_node *node, struct device_node *parent)
+{
+ void __iomem *regs = of_iomap(node, 0);
+ struct vic_device *vic;
+ int irq_base;
+
+ if (WARN_ON(!regs))
+ return -EIO;
+
+ irq_base = irq_alloc_descs(-1, 0, 32, numa_node_id());
+ if (WARN_ON(irq_base < 0))
+ goto out_unmap;
+
+ vic = __vic_init(regs, irq_base, ~0, ~0);
+ if (WARN_ON(!vic))
+ goto out_unmap;
+
+ vic->domain.irq_base = irq_base;
+ vic->domain.nr_irq = 32;
+ vic->domain.of_node = of_node_get(node);
+ vic->domain.ops = &vic_irq_domain_ops;
+ irq_domain_add(&vic->domain);
+
+ return 0;
+
+out_unmap:
+ iounmap(regs);
+
+ return -EIO;
+}
+
+#endif /* CONFIG OF */
diff --git a/arch/arm/include/asm/hardware/vic.h b/arch/arm/include/asm/hardware/vic.h
index 5d72550..df1d895 100644
--- a/arch/arm/include/asm/hardware/vic.h
+++ b/arch/arm/include/asm/hardware/vic.h
@@ -41,7 +41,18 @@
#define VIC_PL192_VECT_ADDR 0xF00
#ifndef __ASSEMBLY__
+struct device_node;
void vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources, u32 resume_sources);
-#endif
+
+#ifdef CONFIG_OF
+int vic_of_init(struct device_node *node, struct device_node *parent);
+#else /* CONFIG_OF */
+static inline int vic_of_init(struct device_node *node,
+ struct device_node *parent)
+{
+ return -ENOSYS;
+}
+#endif /* CONFIG_OF */
+#endif /* __ASSEMBLY__ */
#endif
--
1.7.4.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 2/2] ARM: vic: MULTI_IRQ_HANDLER handler
2011-09-27 12:16 ` Jamie Iles
@ 2011-09-27 12:16 ` Jamie Iles
-1 siblings, 0 replies; 16+ messages in thread
From: Jamie Iles @ 2011-09-27 12:16 UTC (permalink / raw)
To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ
Add a handler for the VIC that is suitable for MULTI_IRQ_HANDLER
platforms. This only works for platforms with CONFIG_OF=y as we can
determine which controllers are the primary controllers (no parent).
Signed-off-by: Jamie Iles <jamie-wmLquQDDieKakBO8gow8eQ@public.gmane.org>
---
arch/arm/common/vic.c | 48 +++++++++++++++++++++++++++++++++++
arch/arm/include/asm/hardware/vic.h | 1 +
2 files changed, 49 insertions(+), 0 deletions(-)
diff --git a/arch/arm/common/vic.c b/arch/arm/common/vic.c
index 3658579..e9b72d3 100644
--- a/arch/arm/common/vic.c
+++ b/arch/arm/common/vic.c
@@ -63,6 +63,22 @@ static struct vic_device vic_devices[CONFIG_ARM_VIC_NR];
static int vic_id;
+#if defined(CONFIG_OF) && defined(CONFIG_MULTI_IRQ_HANDLER)
+/*
+ * The root VIC's. We keep track of these so that we can do the IRQ demuxing
+ * as we can have more than one root VIC.
+ */
+static struct vic_device *vic_root_devices[CONFIG_ARM_VIC_NR];
+static int nr_root_vics;
+
+static void vic_register_root_controller(struct vic_device *vic)
+{
+ vic_root_devices[nr_root_vics++] = vic;
+}
+#else /* CONFIG_OF && CONFIG_MULTI_IRQ_HANDLER */
+static inline void vic_register_root_controller(struct vic_device *vic) {}
+#endif /* CONFIG_OF && CONFIG_MULTI_IRQ_HANDLER */
+
/**
* vic_init2 - common initialisation code
* @base: Base of the VIC.
@@ -439,6 +455,9 @@ int __init vic_of_init(struct device_node *node, struct device_node *parent)
vic->domain.ops = &vic_irq_domain_ops;
irq_domain_add(&vic->domain);
+ if (!parent)
+ vic_register_root_controller(vic);
+
return 0;
out_unmap:
@@ -447,4 +466,33 @@ out_unmap:
return -EIO;
}
+#ifdef CONFIG_MULTI_IRQ_HANDLER
+static void vic_single_handle_irq(struct vic_device *vic, struct pt_regs *regs)
+{
+ u32 stat, irq;
+ bool handled = false;
+
+ while (!handled) {
+ stat = readl_relaxed(vic->base + VIC_IRQ_STATUS);
+ if (!stat)
+ break;
+
+ while (stat) {
+ irq = fls(stat) - 1;
+ handle_IRQ(irq + vic->irq, regs);
+ stat &= ~(1 << irq);
+ handled = true;
+ }
+ }
+}
+
+asmlinkage void __exception_irq_entry vic_handle_irq(struct pt_regs *regs)
+{
+ int i;
+
+ for (i = 0; i < nr_root_vics; ++i)
+ vic_single_handle_irq(vic_root_devices[i], regs);
+}
+#endif /* CONFIG_MULTI_IRQ_HANDLER */
+
#endif /* CONFIG OF */
diff --git a/arch/arm/include/asm/hardware/vic.h b/arch/arm/include/asm/hardware/vic.h
index df1d895..451788c 100644
--- a/arch/arm/include/asm/hardware/vic.h
+++ b/arch/arm/include/asm/hardware/vic.h
@@ -53,6 +53,7 @@ static inline int vic_of_init(struct device_node *node,
return -ENOSYS;
}
#endif /* CONFIG_OF */
+void vic_handle_irq(struct pt_regs *regs);
#endif /* __ASSEMBLY__ */
#endif
--
1.7.4.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 2/2] ARM: vic: MULTI_IRQ_HANDLER handler
@ 2011-09-27 12:16 ` Jamie Iles
0 siblings, 0 replies; 16+ messages in thread
From: Jamie Iles @ 2011-09-27 12:16 UTC (permalink / raw)
To: linux-arm-kernel
Add a handler for the VIC that is suitable for MULTI_IRQ_HANDLER
platforms. This only works for platforms with CONFIG_OF=y as we can
determine which controllers are the primary controllers (no parent).
Signed-off-by: Jamie Iles <jamie@jamieiles.com>
---
arch/arm/common/vic.c | 48 +++++++++++++++++++++++++++++++++++
arch/arm/include/asm/hardware/vic.h | 1 +
2 files changed, 49 insertions(+), 0 deletions(-)
diff --git a/arch/arm/common/vic.c b/arch/arm/common/vic.c
index 3658579..e9b72d3 100644
--- a/arch/arm/common/vic.c
+++ b/arch/arm/common/vic.c
@@ -63,6 +63,22 @@ static struct vic_device vic_devices[CONFIG_ARM_VIC_NR];
static int vic_id;
+#if defined(CONFIG_OF) && defined(CONFIG_MULTI_IRQ_HANDLER)
+/*
+ * The root VIC's. We keep track of these so that we can do the IRQ demuxing
+ * as we can have more than one root VIC.
+ */
+static struct vic_device *vic_root_devices[CONFIG_ARM_VIC_NR];
+static int nr_root_vics;
+
+static void vic_register_root_controller(struct vic_device *vic)
+{
+ vic_root_devices[nr_root_vics++] = vic;
+}
+#else /* CONFIG_OF && CONFIG_MULTI_IRQ_HANDLER */
+static inline void vic_register_root_controller(struct vic_device *vic) {}
+#endif /* CONFIG_OF && CONFIG_MULTI_IRQ_HANDLER */
+
/**
* vic_init2 - common initialisation code
* @base: Base of the VIC.
@@ -439,6 +455,9 @@ int __init vic_of_init(struct device_node *node, struct device_node *parent)
vic->domain.ops = &vic_irq_domain_ops;
irq_domain_add(&vic->domain);
+ if (!parent)
+ vic_register_root_controller(vic);
+
return 0;
out_unmap:
@@ -447,4 +466,33 @@ out_unmap:
return -EIO;
}
+#ifdef CONFIG_MULTI_IRQ_HANDLER
+static void vic_single_handle_irq(struct vic_device *vic, struct pt_regs *regs)
+{
+ u32 stat, irq;
+ bool handled = false;
+
+ while (!handled) {
+ stat = readl_relaxed(vic->base + VIC_IRQ_STATUS);
+ if (!stat)
+ break;
+
+ while (stat) {
+ irq = fls(stat) - 1;
+ handle_IRQ(irq + vic->irq, regs);
+ stat &= ~(1 << irq);
+ handled = true;
+ }
+ }
+}
+
+asmlinkage void __exception_irq_entry vic_handle_irq(struct pt_regs *regs)
+{
+ int i;
+
+ for (i = 0; i < nr_root_vics; ++i)
+ vic_single_handle_irq(vic_root_devices[i], regs);
+}
+#endif /* CONFIG_MULTI_IRQ_HANDLER */
+
#endif /* CONFIG OF */
diff --git a/arch/arm/include/asm/hardware/vic.h b/arch/arm/include/asm/hardware/vic.h
index df1d895..451788c 100644
--- a/arch/arm/include/asm/hardware/vic.h
+++ b/arch/arm/include/asm/hardware/vic.h
@@ -53,6 +53,7 @@ static inline int vic_of_init(struct device_node *node,
return -ENOSYS;
}
#endif /* CONFIG_OF */
+void vic_handle_irq(struct pt_regs *regs);
#endif /* __ASSEMBLY__ */
#endif
--
1.7.4.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH 2/2] ARM: vic: MULTI_IRQ_HANDLER handler
2011-09-27 12:16 ` Jamie Iles
@ 2011-09-27 13:25 ` Rob Herring
-1 siblings, 0 replies; 16+ messages in thread
From: Rob Herring @ 2011-09-27 13:25 UTC (permalink / raw)
To: Jamie Iles
Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
On 09/27/2011 07:16 AM, Jamie Iles wrote:
> Add a handler for the VIC that is suitable for MULTI_IRQ_HANDLER
> platforms. This only works for platforms with CONFIG_OF=y as we can
> determine which controllers are the primary controllers (no parent).
That's probably not an acceptable limitation. I guess this is hard-wired
into entry-macro.S files currently? Perhaps adding an "is_root" flag to
vic_init would fix it for non-DT.
Rob
>
> Signed-off-by: Jamie Iles <jamie-wmLquQDDieKakBO8gow8eQ@public.gmane.org>
> ---
> arch/arm/common/vic.c | 48 +++++++++++++++++++++++++++++++++++
> arch/arm/include/asm/hardware/vic.h | 1 +
> 2 files changed, 49 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/common/vic.c b/arch/arm/common/vic.c
> index 3658579..e9b72d3 100644
> --- a/arch/arm/common/vic.c
> +++ b/arch/arm/common/vic.c
> @@ -63,6 +63,22 @@ static struct vic_device vic_devices[CONFIG_ARM_VIC_NR];
>
> static int vic_id;
>
> +#if defined(CONFIG_OF) && defined(CONFIG_MULTI_IRQ_HANDLER)
> +/*
> + * The root VIC's. We keep track of these so that we can do the IRQ demuxing
> + * as we can have more than one root VIC.
> + */
> +static struct vic_device *vic_root_devices[CONFIG_ARM_VIC_NR];
> +static int nr_root_vics;
> +
> +static void vic_register_root_controller(struct vic_device *vic)
> +{
> + vic_root_devices[nr_root_vics++] = vic;
> +}
> +#else /* CONFIG_OF && CONFIG_MULTI_IRQ_HANDLER */
> +static inline void vic_register_root_controller(struct vic_device *vic) {}
> +#endif /* CONFIG_OF && CONFIG_MULTI_IRQ_HANDLER */
> +
> /**
> * vic_init2 - common initialisation code
> * @base: Base of the VIC.
> @@ -439,6 +455,9 @@ int __init vic_of_init(struct device_node *node, struct device_node *parent)
> vic->domain.ops = &vic_irq_domain_ops;
> irq_domain_add(&vic->domain);
>
> + if (!parent)
> + vic_register_root_controller(vic);
> +
> return 0;
>
> out_unmap:
> @@ -447,4 +466,33 @@ out_unmap:
> return -EIO;
> }
>
> +#ifdef CONFIG_MULTI_IRQ_HANDLER
> +static void vic_single_handle_irq(struct vic_device *vic, struct pt_regs *regs)
> +{
> + u32 stat, irq;
> + bool handled = false;
> +
> + while (!handled) {
> + stat = readl_relaxed(vic->base + VIC_IRQ_STATUS);
> + if (!stat)
> + break;
> +
> + while (stat) {
> + irq = fls(stat) - 1;
> + handle_IRQ(irq + vic->irq, regs);
> + stat &= ~(1 << irq);
> + handled = true;
> + }
> + }
> +}
> +
> +asmlinkage void __exception_irq_entry vic_handle_irq(struct pt_regs *regs)
> +{
> + int i;
> +
> + for (i = 0; i < nr_root_vics; ++i)
> + vic_single_handle_irq(vic_root_devices[i], regs);
> +}
> +#endif /* CONFIG_MULTI_IRQ_HANDLER */
> +
> #endif /* CONFIG OF */
> diff --git a/arch/arm/include/asm/hardware/vic.h b/arch/arm/include/asm/hardware/vic.h
> index df1d895..451788c 100644
> --- a/arch/arm/include/asm/hardware/vic.h
> +++ b/arch/arm/include/asm/hardware/vic.h
> @@ -53,6 +53,7 @@ static inline int vic_of_init(struct device_node *node,
> return -ENOSYS;
> }
> #endif /* CONFIG_OF */
> +void vic_handle_irq(struct pt_regs *regs);
> #endif /* __ASSEMBLY__ */
>
> #endif
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 2/2] ARM: vic: MULTI_IRQ_HANDLER handler
@ 2011-09-27 13:25 ` Rob Herring
0 siblings, 0 replies; 16+ messages in thread
From: Rob Herring @ 2011-09-27 13:25 UTC (permalink / raw)
To: linux-arm-kernel
On 09/27/2011 07:16 AM, Jamie Iles wrote:
> Add a handler for the VIC that is suitable for MULTI_IRQ_HANDLER
> platforms. This only works for platforms with CONFIG_OF=y as we can
> determine which controllers are the primary controllers (no parent).
That's probably not an acceptable limitation. I guess this is hard-wired
into entry-macro.S files currently? Perhaps adding an "is_root" flag to
vic_init would fix it for non-DT.
Rob
>
> Signed-off-by: Jamie Iles <jamie@jamieiles.com>
> ---
> arch/arm/common/vic.c | 48 +++++++++++++++++++++++++++++++++++
> arch/arm/include/asm/hardware/vic.h | 1 +
> 2 files changed, 49 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/common/vic.c b/arch/arm/common/vic.c
> index 3658579..e9b72d3 100644
> --- a/arch/arm/common/vic.c
> +++ b/arch/arm/common/vic.c
> @@ -63,6 +63,22 @@ static struct vic_device vic_devices[CONFIG_ARM_VIC_NR];
>
> static int vic_id;
>
> +#if defined(CONFIG_OF) && defined(CONFIG_MULTI_IRQ_HANDLER)
> +/*
> + * The root VIC's. We keep track of these so that we can do the IRQ demuxing
> + * as we can have more than one root VIC.
> + */
> +static struct vic_device *vic_root_devices[CONFIG_ARM_VIC_NR];
> +static int nr_root_vics;
> +
> +static void vic_register_root_controller(struct vic_device *vic)
> +{
> + vic_root_devices[nr_root_vics++] = vic;
> +}
> +#else /* CONFIG_OF && CONFIG_MULTI_IRQ_HANDLER */
> +static inline void vic_register_root_controller(struct vic_device *vic) {}
> +#endif /* CONFIG_OF && CONFIG_MULTI_IRQ_HANDLER */
> +
> /**
> * vic_init2 - common initialisation code
> * @base: Base of the VIC.
> @@ -439,6 +455,9 @@ int __init vic_of_init(struct device_node *node, struct device_node *parent)
> vic->domain.ops = &vic_irq_domain_ops;
> irq_domain_add(&vic->domain);
>
> + if (!parent)
> + vic_register_root_controller(vic);
> +
> return 0;
>
> out_unmap:
> @@ -447,4 +466,33 @@ out_unmap:
> return -EIO;
> }
>
> +#ifdef CONFIG_MULTI_IRQ_HANDLER
> +static void vic_single_handle_irq(struct vic_device *vic, struct pt_regs *regs)
> +{
> + u32 stat, irq;
> + bool handled = false;
> +
> + while (!handled) {
> + stat = readl_relaxed(vic->base + VIC_IRQ_STATUS);
> + if (!stat)
> + break;
> +
> + while (stat) {
> + irq = fls(stat) - 1;
> + handle_IRQ(irq + vic->irq, regs);
> + stat &= ~(1 << irq);
> + handled = true;
> + }
> + }
> +}
> +
> +asmlinkage void __exception_irq_entry vic_handle_irq(struct pt_regs *regs)
> +{
> + int i;
> +
> + for (i = 0; i < nr_root_vics; ++i)
> + vic_single_handle_irq(vic_root_devices[i], regs);
> +}
> +#endif /* CONFIG_MULTI_IRQ_HANDLER */
> +
> #endif /* CONFIG OF */
> diff --git a/arch/arm/include/asm/hardware/vic.h b/arch/arm/include/asm/hardware/vic.h
> index df1d895..451788c 100644
> --- a/arch/arm/include/asm/hardware/vic.h
> +++ b/arch/arm/include/asm/hardware/vic.h
> @@ -53,6 +53,7 @@ static inline int vic_of_init(struct device_node *node,
> return -ENOSYS;
> }
> #endif /* CONFIG_OF */
> +void vic_handle_irq(struct pt_regs *regs);
> #endif /* __ASSEMBLY__ */
>
> #endif
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 1/2] ARM: vic: device tree binding
2011-09-27 12:16 ` Jamie Iles
@ 2011-09-27 13:30 ` Rob Herring
-1 siblings, 0 replies; 16+ messages in thread
From: Rob Herring @ 2011-09-27 13:30 UTC (permalink / raw)
To: Jamie Iles
Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
On 09/27/2011 07:16 AM, Jamie Iles wrote:
> This adds a device tree binding for the VIC based on the of_irq_init()
> support.
>
> Cc: Rob Herring <robherring2-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> Signed-off-by: Jamie Iles <jamie-wmLquQDDieKakBO8gow8eQ@public.gmane.org>
> ---
> Documentation/devicetree/bindings/arm/vic.txt | 29 ++++++
> arch/arm/common/vic.c | 121 ++++++++++++++++++++-----
> arch/arm/include/asm/hardware/vic.h | 13 +++-
> 3 files changed, 137 insertions(+), 26 deletions(-)
> create mode 100644 Documentation/devicetree/bindings/arm/vic.txt
>
> diff --git a/Documentation/devicetree/bindings/arm/vic.txt b/Documentation/devicetree/bindings/arm/vic.txt
> new file mode 100644
> index 0000000..266716b
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/arm/vic.txt
> @@ -0,0 +1,29 @@
> +* ARM Vectored Interrupt Controller
> +
> +One or more Vectored Interrupt Controllers (VIC's) can be connected in an ARM
> +system for interrupt routing. For multiple controllers they can either be
> +nested or have the outputs wire-OR'd together.
> +
> +Required properties:
> +
> +- compatible : should be one of
> + "arm,pl190-vic"
> + "arm,pl192-vic"
> +- interrupt-controller : Identifies the node as an interrupt controller
> +- #interrupt-cells : The number of cells to define the interrupts. Must be 1 as
> + the VIC has no configuration options for interrupt sources. The cell is a u32
> + and defines the interrupt number.
> +- reg : The register bank for the VIC.
> +
> +Optional properties:
> +
> +- interrupts : Interrupt source for parent controllers if the VIC is nested.
> +
> +Example:
> +
> + vic0: interrupt-controller@60000 {
> + compatible = "arm,pl192-vic";
> + interrupt-controller;
> + #interrupt-cells = <1>;
> + reg = <0x60000 0x1000>;
> + };
> diff --git a/arch/arm/common/vic.c b/arch/arm/common/vic.c
> index 7aa4262..3658579 100644
> --- a/arch/arm/common/vic.c
> +++ b/arch/arm/common/vic.c
> @@ -22,6 +22,10 @@
> #include <linux/init.h>
> #include <linux/list.h>
> #include <linux/io.h>
> +#include <linux/irqdomain.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/of_irq.h>
> #include <linux/syscore_ops.h>
> #include <linux/device.h>
> #include <linux/amba/bus.h>
> @@ -29,7 +33,6 @@
> #include <asm/mach/irq.h>
> #include <asm/hardware/vic.h>
>
> -#ifdef CONFIG_PM
> /**
> * struct vic_device - VIC PM device
> * @irq: The IRQ number for the base of the VIC.
> @@ -50,13 +53,15 @@ struct vic_device {
> u32 int_enable;
> u32 soft_int;
> u32 protect;
> +#ifdef CONFIG_IRQ_DOMAIN
> + struct irq_domain domain;
> +#endif /* CONFIG_IRQ_DOMAIN */
> };
>
> /* we cannot allocate memory when VICs are initially registered */
> static struct vic_device vic_devices[CONFIG_ARM_VIC_NR];
>
> static int vic_id;
> -#endif /* CONFIG_PM */
>
> /**
> * vic_init2 - common initialisation code
> @@ -156,9 +161,10 @@ static int __init vic_pm_init(void)
> return 0;
> }
> late_initcall(vic_pm_init);
> +#endif /* CONFIG_PM */
>
> /**
> - * vic_pm_register - Register a VIC for later power management control
> + * vic_register - Register a VIC.
> * @base: The base address of the VIC.
> * @irq: The base IRQ for the VIC.
> * @resume_sources: bitmask of interrupts allowed for resume sources.
> @@ -166,24 +172,28 @@ late_initcall(vic_pm_init);
> * Register the VIC with the system device tree so that it can be notified
> * of suspend and resume requests and ensure that the correct actions are
> * taken to re-instate the settings on resume.
> + *
> + * We return the VIC so that it can be used for IRQ domain operations for
> + * device tree translation.
> */
> -static void __init vic_pm_register(void __iomem *base, unsigned int irq, u32 resume_sources)
> +static struct vic_device * __init
> +vic_register(void __iomem *base, unsigned int irq, u32 resume_sources)
> {
> struct vic_device *v;
>
> - if (vic_id >= ARRAY_SIZE(vic_devices))
> + if (vic_id >= ARRAY_SIZE(vic_devices)) {
> printk(KERN_ERR "%s: too few VICs, increase CONFIG_ARM_VIC_NR\n", __func__);
> - else {
> - v = &vic_devices[vic_id];
> - v->base = base;
> - v->resume_sources = resume_sources;
> - v->irq = irq;
> - vic_id++;
> + return NULL;
> }
> +
> + v = &vic_devices[vic_id];
> + v->base = base;
> + v->resume_sources = resume_sources;
> + v->irq = irq;
> + vic_id++;
> +
> + return v;
> }
> -#else
> -static inline void vic_pm_register(void __iomem *base, unsigned int irq, u32 arg1) { }
> -#endif /* CONFIG_PM */
>
> static void vic_ack_irq(struct irq_data *d)
> {
> @@ -331,15 +341,9 @@ static void __init vic_init_st(void __iomem *base, unsigned int irq_start,
> vic_set_irq_sources(base, irq_start, vic_sources);
> }
>
> -/**
> - * vic_init - initialise a vectored interrupt controller
> - * @base: iomem base address
> - * @irq_start: starting interrupt number, must be muliple of 32
> - * @vic_sources: bitmask of interrupt sources to allow
> - * @resume_sources: bitmask of interrupt sources to allow for resume
> - */
> -void __init vic_init(void __iomem *base, unsigned int irq_start,
> - u32 vic_sources, u32 resume_sources)
> +static struct vic_device * __init
> +__vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources,
> + u32 resume_sources)
> {
> unsigned int i;
> u32 cellid = 0;
> @@ -357,7 +361,7 @@ void __init vic_init(void __iomem *base, unsigned int irq_start,
> switch(vendor) {
> case AMBA_VENDOR_ST:
> vic_init_st(base, irq_start, vic_sources);
> - return;
> + return NULL;
> default:
> printk(KERN_WARNING "VIC: unknown vendor, continuing anyways\n");
> /* fall through */
> @@ -375,5 +379,72 @@ void __init vic_init(void __iomem *base, unsigned int irq_start,
>
> vic_set_irq_sources(base, irq_start, vic_sources);
>
> - vic_pm_register(base, irq_start, resume_sources);
> + return vic_register(base, irq_start, resume_sources);
> }
> +
> +/**
> + * vic_init - initialise a vectored interrupt controller
> + * @base: iomem base address
> + * @irq_start: starting interrupt number, must be muliple of 32
> + * @vic_sources: bitmask of interrupt sources to allow
> + * @resume_sources: bitmask of interrupt sources to allow for resume
> + */
> +void __init vic_init(void __iomem *base, unsigned int irq_start,
> + u32 vic_sources, u32 resume_sources)
> +{
> + __vic_init(base, irq_start, vic_sources, resume_sources);
> +}
> +
> +#ifdef CONFIG_OF
> +static int
> +vic_irq_domain_dt_translate(struct irq_domain *d, struct device_node *np,
> + const u32 *intspec, unsigned int intsize,
> + unsigned long *out_hwirq, unsigned int *out_type)
> +{
> + if (d->of_node != np)
> + return -EINVAL;
> + if (intsize < 1)
> + return -EINVAL;
> +
> + *out_hwirq = intspec[0];
> + *out_type = IRQ_TYPE_NONE;
> +
> + return 0;
> +}
> +
> +static const struct irq_domain_ops vic_irq_domain_ops = {
> + .dt_translate = vic_irq_domain_dt_translate,
> +};
You should be able to use the simple ops here. You'll need this patch if
you don't already have it:
https://lkml.org/lkml/2011/9/14/189
> +
> +int __init vic_of_init(struct device_node *node, struct device_node *parent)
> +{
> + void __iomem *regs = of_iomap(node, 0);
> + struct vic_device *vic;
> + int irq_base;
> +
> + if (WARN_ON(!regs))
> + return -EIO;
> +
> + irq_base = irq_alloc_descs(-1, 0, 32, numa_node_id());
> + if (WARN_ON(irq_base < 0))
> + goto out_unmap;
> +
> + vic = __vic_init(regs, irq_base, ~0, ~0);
> + if (WARN_ON(!vic))
> + goto out_unmap;
> +
> + vic->domain.irq_base = irq_base;
> + vic->domain.nr_irq = 32;
> + vic->domain.of_node = of_node_get(node);
> + vic->domain.ops = &vic_irq_domain_ops;
> + irq_domain_add(&vic->domain);
> +
> + return 0;
> +
> +out_unmap:
> + iounmap(regs);
> +
> + return -EIO;
> +}
> +
> +#endif /* CONFIG OF */
> diff --git a/arch/arm/include/asm/hardware/vic.h b/arch/arm/include/asm/hardware/vic.h
> index 5d72550..df1d895 100644
> --- a/arch/arm/include/asm/hardware/vic.h
> +++ b/arch/arm/include/asm/hardware/vic.h
> @@ -41,7 +41,18 @@
> #define VIC_PL192_VECT_ADDR 0xF00
>
> #ifndef __ASSEMBLY__
> +struct device_node;
> void vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources, u32 resume_sources);
> -#endif
> +
> +#ifdef CONFIG_OF
> +int vic_of_init(struct device_node *node, struct device_node *parent);
> +#else /* CONFIG_OF */
> +static inline int vic_of_init(struct device_node *node,
> + struct device_node *parent)
> +{
> + return -ENOSYS;
I'm doing ENODEV here for gic. We should be consistent. Which is right?
Rob
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 1/2] ARM: vic: device tree binding
@ 2011-09-27 13:30 ` Rob Herring
0 siblings, 0 replies; 16+ messages in thread
From: Rob Herring @ 2011-09-27 13:30 UTC (permalink / raw)
To: linux-arm-kernel
On 09/27/2011 07:16 AM, Jamie Iles wrote:
> This adds a device tree binding for the VIC based on the of_irq_init()
> support.
>
> Cc: Rob Herring <robherring2@gmail.com>
> Signed-off-by: Jamie Iles <jamie@jamieiles.com>
> ---
> Documentation/devicetree/bindings/arm/vic.txt | 29 ++++++
> arch/arm/common/vic.c | 121 ++++++++++++++++++++-----
> arch/arm/include/asm/hardware/vic.h | 13 +++-
> 3 files changed, 137 insertions(+), 26 deletions(-)
> create mode 100644 Documentation/devicetree/bindings/arm/vic.txt
>
> diff --git a/Documentation/devicetree/bindings/arm/vic.txt b/Documentation/devicetree/bindings/arm/vic.txt
> new file mode 100644
> index 0000000..266716b
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/arm/vic.txt
> @@ -0,0 +1,29 @@
> +* ARM Vectored Interrupt Controller
> +
> +One or more Vectored Interrupt Controllers (VIC's) can be connected in an ARM
> +system for interrupt routing. For multiple controllers they can either be
> +nested or have the outputs wire-OR'd together.
> +
> +Required properties:
> +
> +- compatible : should be one of
> + "arm,pl190-vic"
> + "arm,pl192-vic"
> +- interrupt-controller : Identifies the node as an interrupt controller
> +- #interrupt-cells : The number of cells to define the interrupts. Must be 1 as
> + the VIC has no configuration options for interrupt sources. The cell is a u32
> + and defines the interrupt number.
> +- reg : The register bank for the VIC.
> +
> +Optional properties:
> +
> +- interrupts : Interrupt source for parent controllers if the VIC is nested.
> +
> +Example:
> +
> + vic0: interrupt-controller at 60000 {
> + compatible = "arm,pl192-vic";
> + interrupt-controller;
> + #interrupt-cells = <1>;
> + reg = <0x60000 0x1000>;
> + };
> diff --git a/arch/arm/common/vic.c b/arch/arm/common/vic.c
> index 7aa4262..3658579 100644
> --- a/arch/arm/common/vic.c
> +++ b/arch/arm/common/vic.c
> @@ -22,6 +22,10 @@
> #include <linux/init.h>
> #include <linux/list.h>
> #include <linux/io.h>
> +#include <linux/irqdomain.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/of_irq.h>
> #include <linux/syscore_ops.h>
> #include <linux/device.h>
> #include <linux/amba/bus.h>
> @@ -29,7 +33,6 @@
> #include <asm/mach/irq.h>
> #include <asm/hardware/vic.h>
>
> -#ifdef CONFIG_PM
> /**
> * struct vic_device - VIC PM device
> * @irq: The IRQ number for the base of the VIC.
> @@ -50,13 +53,15 @@ struct vic_device {
> u32 int_enable;
> u32 soft_int;
> u32 protect;
> +#ifdef CONFIG_IRQ_DOMAIN
> + struct irq_domain domain;
> +#endif /* CONFIG_IRQ_DOMAIN */
> };
>
> /* we cannot allocate memory when VICs are initially registered */
> static struct vic_device vic_devices[CONFIG_ARM_VIC_NR];
>
> static int vic_id;
> -#endif /* CONFIG_PM */
>
> /**
> * vic_init2 - common initialisation code
> @@ -156,9 +161,10 @@ static int __init vic_pm_init(void)
> return 0;
> }
> late_initcall(vic_pm_init);
> +#endif /* CONFIG_PM */
>
> /**
> - * vic_pm_register - Register a VIC for later power management control
> + * vic_register - Register a VIC.
> * @base: The base address of the VIC.
> * @irq: The base IRQ for the VIC.
> * @resume_sources: bitmask of interrupts allowed for resume sources.
> @@ -166,24 +172,28 @@ late_initcall(vic_pm_init);
> * Register the VIC with the system device tree so that it can be notified
> * of suspend and resume requests and ensure that the correct actions are
> * taken to re-instate the settings on resume.
> + *
> + * We return the VIC so that it can be used for IRQ domain operations for
> + * device tree translation.
> */
> -static void __init vic_pm_register(void __iomem *base, unsigned int irq, u32 resume_sources)
> +static struct vic_device * __init
> +vic_register(void __iomem *base, unsigned int irq, u32 resume_sources)
> {
> struct vic_device *v;
>
> - if (vic_id >= ARRAY_SIZE(vic_devices))
> + if (vic_id >= ARRAY_SIZE(vic_devices)) {
> printk(KERN_ERR "%s: too few VICs, increase CONFIG_ARM_VIC_NR\n", __func__);
> - else {
> - v = &vic_devices[vic_id];
> - v->base = base;
> - v->resume_sources = resume_sources;
> - v->irq = irq;
> - vic_id++;
> + return NULL;
> }
> +
> + v = &vic_devices[vic_id];
> + v->base = base;
> + v->resume_sources = resume_sources;
> + v->irq = irq;
> + vic_id++;
> +
> + return v;
> }
> -#else
> -static inline void vic_pm_register(void __iomem *base, unsigned int irq, u32 arg1) { }
> -#endif /* CONFIG_PM */
>
> static void vic_ack_irq(struct irq_data *d)
> {
> @@ -331,15 +341,9 @@ static void __init vic_init_st(void __iomem *base, unsigned int irq_start,
> vic_set_irq_sources(base, irq_start, vic_sources);
> }
>
> -/**
> - * vic_init - initialise a vectored interrupt controller
> - * @base: iomem base address
> - * @irq_start: starting interrupt number, must be muliple of 32
> - * @vic_sources: bitmask of interrupt sources to allow
> - * @resume_sources: bitmask of interrupt sources to allow for resume
> - */
> -void __init vic_init(void __iomem *base, unsigned int irq_start,
> - u32 vic_sources, u32 resume_sources)
> +static struct vic_device * __init
> +__vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources,
> + u32 resume_sources)
> {
> unsigned int i;
> u32 cellid = 0;
> @@ -357,7 +361,7 @@ void __init vic_init(void __iomem *base, unsigned int irq_start,
> switch(vendor) {
> case AMBA_VENDOR_ST:
> vic_init_st(base, irq_start, vic_sources);
> - return;
> + return NULL;
> default:
> printk(KERN_WARNING "VIC: unknown vendor, continuing anyways\n");
> /* fall through */
> @@ -375,5 +379,72 @@ void __init vic_init(void __iomem *base, unsigned int irq_start,
>
> vic_set_irq_sources(base, irq_start, vic_sources);
>
> - vic_pm_register(base, irq_start, resume_sources);
> + return vic_register(base, irq_start, resume_sources);
> }
> +
> +/**
> + * vic_init - initialise a vectored interrupt controller
> + * @base: iomem base address
> + * @irq_start: starting interrupt number, must be muliple of 32
> + * @vic_sources: bitmask of interrupt sources to allow
> + * @resume_sources: bitmask of interrupt sources to allow for resume
> + */
> +void __init vic_init(void __iomem *base, unsigned int irq_start,
> + u32 vic_sources, u32 resume_sources)
> +{
> + __vic_init(base, irq_start, vic_sources, resume_sources);
> +}
> +
> +#ifdef CONFIG_OF
> +static int
> +vic_irq_domain_dt_translate(struct irq_domain *d, struct device_node *np,
> + const u32 *intspec, unsigned int intsize,
> + unsigned long *out_hwirq, unsigned int *out_type)
> +{
> + if (d->of_node != np)
> + return -EINVAL;
> + if (intsize < 1)
> + return -EINVAL;
> +
> + *out_hwirq = intspec[0];
> + *out_type = IRQ_TYPE_NONE;
> +
> + return 0;
> +}
> +
> +static const struct irq_domain_ops vic_irq_domain_ops = {
> + .dt_translate = vic_irq_domain_dt_translate,
> +};
You should be able to use the simple ops here. You'll need this patch if
you don't already have it:
https://lkml.org/lkml/2011/9/14/189
> +
> +int __init vic_of_init(struct device_node *node, struct device_node *parent)
> +{
> + void __iomem *regs = of_iomap(node, 0);
> + struct vic_device *vic;
> + int irq_base;
> +
> + if (WARN_ON(!regs))
> + return -EIO;
> +
> + irq_base = irq_alloc_descs(-1, 0, 32, numa_node_id());
> + if (WARN_ON(irq_base < 0))
> + goto out_unmap;
> +
> + vic = __vic_init(regs, irq_base, ~0, ~0);
> + if (WARN_ON(!vic))
> + goto out_unmap;
> +
> + vic->domain.irq_base = irq_base;
> + vic->domain.nr_irq = 32;
> + vic->domain.of_node = of_node_get(node);
> + vic->domain.ops = &vic_irq_domain_ops;
> + irq_domain_add(&vic->domain);
> +
> + return 0;
> +
> +out_unmap:
> + iounmap(regs);
> +
> + return -EIO;
> +}
> +
> +#endif /* CONFIG OF */
> diff --git a/arch/arm/include/asm/hardware/vic.h b/arch/arm/include/asm/hardware/vic.h
> index 5d72550..df1d895 100644
> --- a/arch/arm/include/asm/hardware/vic.h
> +++ b/arch/arm/include/asm/hardware/vic.h
> @@ -41,7 +41,18 @@
> #define VIC_PL192_VECT_ADDR 0xF00
>
> #ifndef __ASSEMBLY__
> +struct device_node;
> void vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources, u32 resume_sources);
> -#endif
> +
> +#ifdef CONFIG_OF
> +int vic_of_init(struct device_node *node, struct device_node *parent);
> +#else /* CONFIG_OF */
> +static inline int vic_of_init(struct device_node *node,
> + struct device_node *parent)
> +{
> + return -ENOSYS;
I'm doing ENODEV here for gic. We should be consistent. Which is right?
Rob
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 1/2] ARM: vic: device tree binding
2011-09-27 13:30 ` Rob Herring
@ 2011-09-27 13:38 ` Jamie Iles
-1 siblings, 0 replies; 16+ messages in thread
From: Jamie Iles @ 2011-09-27 13:38 UTC (permalink / raw)
To: Rob Herring
Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
Hi Rob,
On Tue, Sep 27, 2011 at 08:30:43AM -0500, Rob Herring wrote:
> On 09/27/2011 07:16 AM, Jamie Iles wrote:
[...]
> > +#ifdef CONFIG_OF
> > +static int
> > +vic_irq_domain_dt_translate(struct irq_domain *d, struct device_node *np,
> > + const u32 *intspec, unsigned int intsize,
> > + unsigned long *out_hwirq, unsigned int *out_type)
> > +{
> > + if (d->of_node != np)
> > + return -EINVAL;
> > + if (intsize < 1)
> > + return -EINVAL;
> > +
> > + *out_hwirq = intspec[0];
> > + *out_type = IRQ_TYPE_NONE;
> > +
> > + return 0;
> > +}
> > +
> > +static const struct irq_domain_ops vic_irq_domain_ops = {
> > + .dt_translate = vic_irq_domain_dt_translate,
> > +};
>
> You should be able to use the simple ops here. You'll need this patch if
> you don't already have it:
>
> https://lkml.org/lkml/2011/9/14/189
I didn't use the simple ops because I thought it would be better to only
accept one interrupt cell, but I got it wrong and should have had:
if (intsize != 1)
return -EINVAL;
The simple ops would work but I'm not sure what would be best. Any
preference?
> > +
> > +int __init vic_of_init(struct device_node *node, struct device_node *parent)
> > +{
> > + void __iomem *regs = of_iomap(node, 0);
> > + struct vic_device *vic;
> > + int irq_base;
> > +
> > + if (WARN_ON(!regs))
> > + return -EIO;
> > +
> > + irq_base = irq_alloc_descs(-1, 0, 32, numa_node_id());
> > + if (WARN_ON(irq_base < 0))
> > + goto out_unmap;
> > +
> > + vic = __vic_init(regs, irq_base, ~0, ~0);
> > + if (WARN_ON(!vic))
> > + goto out_unmap;
> > +
> > + vic->domain.irq_base = irq_base;
> > + vic->domain.nr_irq = 32;
> > + vic->domain.of_node = of_node_get(node);
> > + vic->domain.ops = &vic_irq_domain_ops;
> > + irq_domain_add(&vic->domain);
> > +
> > + return 0;
> > +
> > +out_unmap:
> > + iounmap(regs);
> > +
> > + return -EIO;
> > +}
> > +
> > +#endif /* CONFIG OF */
> > diff --git a/arch/arm/include/asm/hardware/vic.h b/arch/arm/include/asm/hardware/vic.h
> > index 5d72550..df1d895 100644
> > --- a/arch/arm/include/asm/hardware/vic.h
> > +++ b/arch/arm/include/asm/hardware/vic.h
> > @@ -41,7 +41,18 @@
> > #define VIC_PL192_VECT_ADDR 0xF00
> >
> > #ifndef __ASSEMBLY__
> > +struct device_node;
> > void vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources, u32 resume_sources);
> > -#endif
> > +
> > +#ifdef CONFIG_OF
> > +int vic_of_init(struct device_node *node, struct device_node *parent);
> > +#else /* CONFIG_OF */
> > +static inline int vic_of_init(struct device_node *node,
> > + struct device_node *parent)
> > +{
> > + return -ENOSYS;
>
> I'm doing ENODEV here for gic. We should be consistent. Which is right?
I see -ENOSYS for lots of these in include/linux, but I'm not sure it
matters a great deal. I'll change it to -ENODEV for the next version.
Jamie
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 1/2] ARM: vic: device tree binding
@ 2011-09-27 13:38 ` Jamie Iles
0 siblings, 0 replies; 16+ messages in thread
From: Jamie Iles @ 2011-09-27 13:38 UTC (permalink / raw)
To: linux-arm-kernel
Hi Rob,
On Tue, Sep 27, 2011 at 08:30:43AM -0500, Rob Herring wrote:
> On 09/27/2011 07:16 AM, Jamie Iles wrote:
[...]
> > +#ifdef CONFIG_OF
> > +static int
> > +vic_irq_domain_dt_translate(struct irq_domain *d, struct device_node *np,
> > + const u32 *intspec, unsigned int intsize,
> > + unsigned long *out_hwirq, unsigned int *out_type)
> > +{
> > + if (d->of_node != np)
> > + return -EINVAL;
> > + if (intsize < 1)
> > + return -EINVAL;
> > +
> > + *out_hwirq = intspec[0];
> > + *out_type = IRQ_TYPE_NONE;
> > +
> > + return 0;
> > +}
> > +
> > +static const struct irq_domain_ops vic_irq_domain_ops = {
> > + .dt_translate = vic_irq_domain_dt_translate,
> > +};
>
> You should be able to use the simple ops here. You'll need this patch if
> you don't already have it:
>
> https://lkml.org/lkml/2011/9/14/189
I didn't use the simple ops because I thought it would be better to only
accept one interrupt cell, but I got it wrong and should have had:
if (intsize != 1)
return -EINVAL;
The simple ops would work but I'm not sure what would be best. Any
preference?
> > +
> > +int __init vic_of_init(struct device_node *node, struct device_node *parent)
> > +{
> > + void __iomem *regs = of_iomap(node, 0);
> > + struct vic_device *vic;
> > + int irq_base;
> > +
> > + if (WARN_ON(!regs))
> > + return -EIO;
> > +
> > + irq_base = irq_alloc_descs(-1, 0, 32, numa_node_id());
> > + if (WARN_ON(irq_base < 0))
> > + goto out_unmap;
> > +
> > + vic = __vic_init(regs, irq_base, ~0, ~0);
> > + if (WARN_ON(!vic))
> > + goto out_unmap;
> > +
> > + vic->domain.irq_base = irq_base;
> > + vic->domain.nr_irq = 32;
> > + vic->domain.of_node = of_node_get(node);
> > + vic->domain.ops = &vic_irq_domain_ops;
> > + irq_domain_add(&vic->domain);
> > +
> > + return 0;
> > +
> > +out_unmap:
> > + iounmap(regs);
> > +
> > + return -EIO;
> > +}
> > +
> > +#endif /* CONFIG OF */
> > diff --git a/arch/arm/include/asm/hardware/vic.h b/arch/arm/include/asm/hardware/vic.h
> > index 5d72550..df1d895 100644
> > --- a/arch/arm/include/asm/hardware/vic.h
> > +++ b/arch/arm/include/asm/hardware/vic.h
> > @@ -41,7 +41,18 @@
> > #define VIC_PL192_VECT_ADDR 0xF00
> >
> > #ifndef __ASSEMBLY__
> > +struct device_node;
> > void vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources, u32 resume_sources);
> > -#endif
> > +
> > +#ifdef CONFIG_OF
> > +int vic_of_init(struct device_node *node, struct device_node *parent);
> > +#else /* CONFIG_OF */
> > +static inline int vic_of_init(struct device_node *node,
> > + struct device_node *parent)
> > +{
> > + return -ENOSYS;
>
> I'm doing ENODEV here for gic. We should be consistent. Which is right?
I see -ENOSYS for lots of these in include/linux, but I'm not sure it
matters a great deal. I'll change it to -ENODEV for the next version.
Jamie
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 2/2] ARM: vic: MULTI_IRQ_HANDLER handler
2011-09-27 13:25 ` Rob Herring
@ 2011-09-27 13:58 ` Jamie Iles
-1 siblings, 0 replies; 16+ messages in thread
From: Jamie Iles @ 2011-09-27 13:58 UTC (permalink / raw)
To: Rob Herring
Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
On Tue, Sep 27, 2011 at 08:25:30AM -0500, Rob Herring wrote:
> On 09/27/2011 07:16 AM, Jamie Iles wrote:
> > Add a handler for the VIC that is suitable for MULTI_IRQ_HANDLER
> > platforms. This only works for platforms with CONFIG_OF=y as we can
> > determine which controllers are the primary controllers (no parent).
>
> That's probably not an acceptable limitation. I guess this is hard-wired
> into entry-macro.S files currently? Perhaps adding an "is_root" flag to
> vic_init would fix it for non-DT.
OK. Looking at all of the other users of the common vic code, I can't
find an instance where the vic isn't the top level controller. So I
think that restriction can be removed and in the device tree probing
issue a WARN() if parent != NULL. Does that work for you?
Jamie
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 2/2] ARM: vic: MULTI_IRQ_HANDLER handler
@ 2011-09-27 13:58 ` Jamie Iles
0 siblings, 0 replies; 16+ messages in thread
From: Jamie Iles @ 2011-09-27 13:58 UTC (permalink / raw)
To: linux-arm-kernel
On Tue, Sep 27, 2011 at 08:25:30AM -0500, Rob Herring wrote:
> On 09/27/2011 07:16 AM, Jamie Iles wrote:
> > Add a handler for the VIC that is suitable for MULTI_IRQ_HANDLER
> > platforms. This only works for platforms with CONFIG_OF=y as we can
> > determine which controllers are the primary controllers (no parent).
>
> That's probably not an acceptable limitation. I guess this is hard-wired
> into entry-macro.S files currently? Perhaps adding an "is_root" flag to
> vic_init would fix it for non-DT.
OK. Looking at all of the other users of the common vic code, I can't
find an instance where the vic isn't the top level controller. So I
think that restriction can be removed and in the device tree probing
issue a WARN() if parent != NULL. Does that work for you?
Jamie
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 1/2] ARM: vic: device tree binding
2011-09-27 12:16 ` Jamie Iles
@ 2011-09-27 21:00 ` Grant Likely
-1 siblings, 0 replies; 16+ messages in thread
From: Grant Likely @ 2011-09-27 21:00 UTC (permalink / raw)
To: Jamie Iles
Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
On Tue, Sep 27, 2011 at 01:16:41PM +0100, Jamie Iles wrote:
> This adds a device tree binding for the VIC based on the of_irq_init()
> support.
>
> Cc: Rob Herring <robherring2-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> Signed-off-by: Jamie Iles <jamie-wmLquQDDieKakBO8gow8eQ@public.gmane.org>
> ---
> Documentation/devicetree/bindings/arm/vic.txt | 29 ++++++
> arch/arm/common/vic.c | 121 ++++++++++++++++++++-----
> arch/arm/include/asm/hardware/vic.h | 13 +++-
> 3 files changed, 137 insertions(+), 26 deletions(-)
> create mode 100644 Documentation/devicetree/bindings/arm/vic.txt
>
> diff --git a/Documentation/devicetree/bindings/arm/vic.txt b/Documentation/devicetree/bindings/arm/vic.txt
> new file mode 100644
> index 0000000..266716b
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/arm/vic.txt
> @@ -0,0 +1,29 @@
> +* ARM Vectored Interrupt Controller
> +
> +One or more Vectored Interrupt Controllers (VIC's) can be connected in an ARM
> +system for interrupt routing. For multiple controllers they can either be
> +nested or have the outputs wire-OR'd together.
> +
> +Required properties:
> +
> +- compatible : should be one of
> + "arm,pl190-vic"
> + "arm,pl192-vic"
> +- interrupt-controller : Identifies the node as an interrupt controller
> +- #interrupt-cells : The number of cells to define the interrupts. Must be 1 as
> + the VIC has no configuration options for interrupt sources. The cell is a u32
> + and defines the interrupt number.
> +- reg : The register bank for the VIC.
> +
> +Optional properties:
> +
> +- interrupts : Interrupt source for parent controllers if the VIC is nested.
> +
> +Example:
> +
> + vic0: interrupt-controller@60000 {
> + compatible = "arm,pl192-vic";
> + interrupt-controller;
> + #interrupt-cells = <1>;
> + reg = <0x60000 0x1000>;
> + };
> diff --git a/arch/arm/common/vic.c b/arch/arm/common/vic.c
> index 7aa4262..3658579 100644
> --- a/arch/arm/common/vic.c
> +++ b/arch/arm/common/vic.c
> @@ -22,6 +22,10 @@
> #include <linux/init.h>
> #include <linux/list.h>
> #include <linux/io.h>
> +#include <linux/irqdomain.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/of_irq.h>
> #include <linux/syscore_ops.h>
> #include <linux/device.h>
> #include <linux/amba/bus.h>
> @@ -29,7 +33,6 @@
> #include <asm/mach/irq.h>
> #include <asm/hardware/vic.h>
>
> -#ifdef CONFIG_PM
Interesting that this #ifdef is being removed, but no mention of it in
the commit text. It helps with review is some of the implementation
details are described.
> /**
> * struct vic_device - VIC PM device
> * @irq: The IRQ number for the base of the VIC.
> @@ -50,13 +53,15 @@ struct vic_device {
> u32 int_enable;
> u32 soft_int;
> u32 protect;
> +#ifdef CONFIG_IRQ_DOMAIN
> + struct irq_domain domain;
> +#endif /* CONFIG_IRQ_DOMAIN */
> };
>
> /* we cannot allocate memory when VICs are initially registered */
> static struct vic_device vic_devices[CONFIG_ARM_VIC_NR];
>
> static int vic_id;
> -#endif /* CONFIG_PM */
>
> /**
> * vic_init2 - common initialisation code
> @@ -156,9 +161,10 @@ static int __init vic_pm_init(void)
> return 0;
> }
> late_initcall(vic_pm_init);
> +#endif /* CONFIG_PM */
>
> /**
> - * vic_pm_register - Register a VIC for later power management control
> + * vic_register - Register a VIC.
Nit: kerneldoc format is:
/**
* function_name() - description
*
> * @base: The base address of the VIC.
> * @irq: The base IRQ for the VIC.
> * @resume_sources: bitmask of interrupts allowed for resume sources.
> @@ -166,24 +172,28 @@ late_initcall(vic_pm_init);
> * Register the VIC with the system device tree so that it can be notified
> * of suspend and resume requests and ensure that the correct actions are
> * taken to re-instate the settings on resume.
> + *
> + * We return the VIC so that it can be used for IRQ domain operations for
> + * device tree translation.
> */
> -static void __init vic_pm_register(void __iomem *base, unsigned int irq, u32 resume_sources)
> +static struct vic_device * __init
> +vic_register(void __iomem *base, unsigned int irq, u32 resume_sources)
Nit: Linebreaks should be restricted to the argument list. That way
grepping for the function name tells you both what the annotations &
return value is, and that there are more arguments than can be seen
because you don't see closing parentheses.
> {
> struct vic_device *v;
>
> - if (vic_id >= ARRAY_SIZE(vic_devices))
> + if (vic_id >= ARRAY_SIZE(vic_devices)) {
> printk(KERN_ERR "%s: too few VICs, increase CONFIG_ARM_VIC_NR\n", __func__);
> - else {
> - v = &vic_devices[vic_id];
> - v->base = base;
> - v->resume_sources = resume_sources;
> - v->irq = irq;
> - vic_id++;
> + return NULL;
> }
> +
> + v = &vic_devices[vic_id];
> + v->base = base;
> + v->resume_sources = resume_sources;
> + v->irq = irq;
> + vic_id++;
> +
> + return v;
> }
> -#else
> -static inline void vic_pm_register(void __iomem *base, unsigned int irq, u32 arg1) { }
> -#endif /* CONFIG_PM */
>
> static void vic_ack_irq(struct irq_data *d)
> {
> @@ -331,15 +341,9 @@ static void __init vic_init_st(void __iomem *base, unsigned int irq_start,
> vic_set_irq_sources(base, irq_start, vic_sources);
> }
>
> -/**
> - * vic_init - initialise a vectored interrupt controller
> - * @base: iomem base address
> - * @irq_start: starting interrupt number, must be muliple of 32
> - * @vic_sources: bitmask of interrupt sources to allow
> - * @resume_sources: bitmask of interrupt sources to allow for resume
> - */
> -void __init vic_init(void __iomem *base, unsigned int irq_start,
> - u32 vic_sources, u32 resume_sources)
> +static struct vic_device * __init
> +__vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources,
Ditto here.
> + u32 resume_sources)
> {
> unsigned int i;
> u32 cellid = 0;
> @@ -357,7 +361,7 @@ void __init vic_init(void __iomem *base, unsigned int irq_start,
> switch(vendor) {
> case AMBA_VENDOR_ST:
> vic_init_st(base, irq_start, vic_sources);
> - return;
> + return NULL;
> default:
> printk(KERN_WARNING "VIC: unknown vendor, continuing anyways\n");
> /* fall through */
> @@ -375,5 +379,72 @@ void __init vic_init(void __iomem *base, unsigned int irq_start,
>
> vic_set_irq_sources(base, irq_start, vic_sources);
>
> - vic_pm_register(base, irq_start, resume_sources);
> + return vic_register(base, irq_start, resume_sources);
> }
> +
> +/**
> + * vic_init - initialise a vectored interrupt controller
> + * @base: iomem base address
> + * @irq_start: starting interrupt number, must be muliple of 32
> + * @vic_sources: bitmask of interrupt sources to allow
> + * @resume_sources: bitmask of interrupt sources to allow for resume
> + */
> +void __init vic_init(void __iomem *base, unsigned int irq_start,
> + u32 vic_sources, u32 resume_sources)
> +{
> + __vic_init(base, irq_start, vic_sources, resume_sources);
> +}
> +
> +#ifdef CONFIG_OF
> +static int
> +vic_irq_domain_dt_translate(struct irq_domain *d, struct device_node *np,
> + const u32 *intspec, unsigned int intsize,
> + unsigned long *out_hwirq, unsigned int *out_type)
> +{
> + if (d->of_node != np)
> + return -EINVAL;
> + if (intsize < 1)
> + return -EINVAL;
> +
> + *out_hwirq = intspec[0];
> + *out_type = IRQ_TYPE_NONE;
> +
> + return 0;
> +}
It matches the simple binding. Just use
irq_domain_simple_dt_translate() directly.
> +
> +static const struct irq_domain_ops vic_irq_domain_ops = {
> + .dt_translate = vic_irq_domain_dt_translate,
> +};
> +
> +int __init vic_of_init(struct device_node *node, struct device_node *parent)
> +{
> + void __iomem *regs = of_iomap(node, 0);
> + struct vic_device *vic;
> + int irq_base;
> +
> + if (WARN_ON(!regs))
> + return -EIO;
> +
> + irq_base = irq_alloc_descs(-1, 0, 32, numa_node_id());
> + if (WARN_ON(irq_base < 0))
> + goto out_unmap;
> +
> + vic = __vic_init(regs, irq_base, ~0, ~0);
> + if (WARN_ON(!vic))
> + goto out_unmap;
> +
> + vic->domain.irq_base = irq_base;
> + vic->domain.nr_irq = 32;
> + vic->domain.of_node = of_node_get(node);
> + vic->domain.ops = &vic_irq_domain_ops;
> + irq_domain_add(&vic->domain);
> +
> + return 0;
> +
> +out_unmap:
Nit: putting a single space before the label makes 'diff' behave
better.
> + iounmap(regs);
> +
> + return -EIO;
> +}
> +
> +#endif /* CONFIG OF */
> diff --git a/arch/arm/include/asm/hardware/vic.h b/arch/arm/include/asm/hardware/vic.h
> index 5d72550..df1d895 100644
> --- a/arch/arm/include/asm/hardware/vic.h
> +++ b/arch/arm/include/asm/hardware/vic.h
> @@ -41,7 +41,18 @@
> #define VIC_PL192_VECT_ADDR 0xF00
>
> #ifndef __ASSEMBLY__
> +struct device_node;
> void vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources, u32 resume_sources);
> -#endif
> +
> +#ifdef CONFIG_OF
> +int vic_of_init(struct device_node *node, struct device_node *parent);
> +#else /* CONFIG_OF */
> +static inline int vic_of_init(struct device_node *node,
> + struct device_node *parent)
> +{
> + return -ENOSYS;
> +}
> +#endif /* CONFIG_OF */
Will this ever be referenced when !CONFIG_OF? It shouldn't be.
Otherwise looks good.
g.
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 1/2] ARM: vic: device tree binding
@ 2011-09-27 21:00 ` Grant Likely
0 siblings, 0 replies; 16+ messages in thread
From: Grant Likely @ 2011-09-27 21:00 UTC (permalink / raw)
To: linux-arm-kernel
On Tue, Sep 27, 2011 at 01:16:41PM +0100, Jamie Iles wrote:
> This adds a device tree binding for the VIC based on the of_irq_init()
> support.
>
> Cc: Rob Herring <robherring2@gmail.com>
> Signed-off-by: Jamie Iles <jamie@jamieiles.com>
> ---
> Documentation/devicetree/bindings/arm/vic.txt | 29 ++++++
> arch/arm/common/vic.c | 121 ++++++++++++++++++++-----
> arch/arm/include/asm/hardware/vic.h | 13 +++-
> 3 files changed, 137 insertions(+), 26 deletions(-)
> create mode 100644 Documentation/devicetree/bindings/arm/vic.txt
>
> diff --git a/Documentation/devicetree/bindings/arm/vic.txt b/Documentation/devicetree/bindings/arm/vic.txt
> new file mode 100644
> index 0000000..266716b
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/arm/vic.txt
> @@ -0,0 +1,29 @@
> +* ARM Vectored Interrupt Controller
> +
> +One or more Vectored Interrupt Controllers (VIC's) can be connected in an ARM
> +system for interrupt routing. For multiple controllers they can either be
> +nested or have the outputs wire-OR'd together.
> +
> +Required properties:
> +
> +- compatible : should be one of
> + "arm,pl190-vic"
> + "arm,pl192-vic"
> +- interrupt-controller : Identifies the node as an interrupt controller
> +- #interrupt-cells : The number of cells to define the interrupts. Must be 1 as
> + the VIC has no configuration options for interrupt sources. The cell is a u32
> + and defines the interrupt number.
> +- reg : The register bank for the VIC.
> +
> +Optional properties:
> +
> +- interrupts : Interrupt source for parent controllers if the VIC is nested.
> +
> +Example:
> +
> + vic0: interrupt-controller at 60000 {
> + compatible = "arm,pl192-vic";
> + interrupt-controller;
> + #interrupt-cells = <1>;
> + reg = <0x60000 0x1000>;
> + };
> diff --git a/arch/arm/common/vic.c b/arch/arm/common/vic.c
> index 7aa4262..3658579 100644
> --- a/arch/arm/common/vic.c
> +++ b/arch/arm/common/vic.c
> @@ -22,6 +22,10 @@
> #include <linux/init.h>
> #include <linux/list.h>
> #include <linux/io.h>
> +#include <linux/irqdomain.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/of_irq.h>
> #include <linux/syscore_ops.h>
> #include <linux/device.h>
> #include <linux/amba/bus.h>
> @@ -29,7 +33,6 @@
> #include <asm/mach/irq.h>
> #include <asm/hardware/vic.h>
>
> -#ifdef CONFIG_PM
Interesting that this #ifdef is being removed, but no mention of it in
the commit text. It helps with review is some of the implementation
details are described.
> /**
> * struct vic_device - VIC PM device
> * @irq: The IRQ number for the base of the VIC.
> @@ -50,13 +53,15 @@ struct vic_device {
> u32 int_enable;
> u32 soft_int;
> u32 protect;
> +#ifdef CONFIG_IRQ_DOMAIN
> + struct irq_domain domain;
> +#endif /* CONFIG_IRQ_DOMAIN */
> };
>
> /* we cannot allocate memory when VICs are initially registered */
> static struct vic_device vic_devices[CONFIG_ARM_VIC_NR];
>
> static int vic_id;
> -#endif /* CONFIG_PM */
>
> /**
> * vic_init2 - common initialisation code
> @@ -156,9 +161,10 @@ static int __init vic_pm_init(void)
> return 0;
> }
> late_initcall(vic_pm_init);
> +#endif /* CONFIG_PM */
>
> /**
> - * vic_pm_register - Register a VIC for later power management control
> + * vic_register - Register a VIC.
Nit: kerneldoc format is:
/**
* function_name() - description
*
> * @base: The base address of the VIC.
> * @irq: The base IRQ for the VIC.
> * @resume_sources: bitmask of interrupts allowed for resume sources.
> @@ -166,24 +172,28 @@ late_initcall(vic_pm_init);
> * Register the VIC with the system device tree so that it can be notified
> * of suspend and resume requests and ensure that the correct actions are
> * taken to re-instate the settings on resume.
> + *
> + * We return the VIC so that it can be used for IRQ domain operations for
> + * device tree translation.
> */
> -static void __init vic_pm_register(void __iomem *base, unsigned int irq, u32 resume_sources)
> +static struct vic_device * __init
> +vic_register(void __iomem *base, unsigned int irq, u32 resume_sources)
Nit: Linebreaks should be restricted to the argument list. That way
grepping for the function name tells you both what the annotations &
return value is, and that there are more arguments than can be seen
because you don't see closing parentheses.
> {
> struct vic_device *v;
>
> - if (vic_id >= ARRAY_SIZE(vic_devices))
> + if (vic_id >= ARRAY_SIZE(vic_devices)) {
> printk(KERN_ERR "%s: too few VICs, increase CONFIG_ARM_VIC_NR\n", __func__);
> - else {
> - v = &vic_devices[vic_id];
> - v->base = base;
> - v->resume_sources = resume_sources;
> - v->irq = irq;
> - vic_id++;
> + return NULL;
> }
> +
> + v = &vic_devices[vic_id];
> + v->base = base;
> + v->resume_sources = resume_sources;
> + v->irq = irq;
> + vic_id++;
> +
> + return v;
> }
> -#else
> -static inline void vic_pm_register(void __iomem *base, unsigned int irq, u32 arg1) { }
> -#endif /* CONFIG_PM */
>
> static void vic_ack_irq(struct irq_data *d)
> {
> @@ -331,15 +341,9 @@ static void __init vic_init_st(void __iomem *base, unsigned int irq_start,
> vic_set_irq_sources(base, irq_start, vic_sources);
> }
>
> -/**
> - * vic_init - initialise a vectored interrupt controller
> - * @base: iomem base address
> - * @irq_start: starting interrupt number, must be muliple of 32
> - * @vic_sources: bitmask of interrupt sources to allow
> - * @resume_sources: bitmask of interrupt sources to allow for resume
> - */
> -void __init vic_init(void __iomem *base, unsigned int irq_start,
> - u32 vic_sources, u32 resume_sources)
> +static struct vic_device * __init
> +__vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources,
Ditto here.
> + u32 resume_sources)
> {
> unsigned int i;
> u32 cellid = 0;
> @@ -357,7 +361,7 @@ void __init vic_init(void __iomem *base, unsigned int irq_start,
> switch(vendor) {
> case AMBA_VENDOR_ST:
> vic_init_st(base, irq_start, vic_sources);
> - return;
> + return NULL;
> default:
> printk(KERN_WARNING "VIC: unknown vendor, continuing anyways\n");
> /* fall through */
> @@ -375,5 +379,72 @@ void __init vic_init(void __iomem *base, unsigned int irq_start,
>
> vic_set_irq_sources(base, irq_start, vic_sources);
>
> - vic_pm_register(base, irq_start, resume_sources);
> + return vic_register(base, irq_start, resume_sources);
> }
> +
> +/**
> + * vic_init - initialise a vectored interrupt controller
> + * @base: iomem base address
> + * @irq_start: starting interrupt number, must be muliple of 32
> + * @vic_sources: bitmask of interrupt sources to allow
> + * @resume_sources: bitmask of interrupt sources to allow for resume
> + */
> +void __init vic_init(void __iomem *base, unsigned int irq_start,
> + u32 vic_sources, u32 resume_sources)
> +{
> + __vic_init(base, irq_start, vic_sources, resume_sources);
> +}
> +
> +#ifdef CONFIG_OF
> +static int
> +vic_irq_domain_dt_translate(struct irq_domain *d, struct device_node *np,
> + const u32 *intspec, unsigned int intsize,
> + unsigned long *out_hwirq, unsigned int *out_type)
> +{
> + if (d->of_node != np)
> + return -EINVAL;
> + if (intsize < 1)
> + return -EINVAL;
> +
> + *out_hwirq = intspec[0];
> + *out_type = IRQ_TYPE_NONE;
> +
> + return 0;
> +}
It matches the simple binding. Just use
irq_domain_simple_dt_translate() directly.
> +
> +static const struct irq_domain_ops vic_irq_domain_ops = {
> + .dt_translate = vic_irq_domain_dt_translate,
> +};
> +
> +int __init vic_of_init(struct device_node *node, struct device_node *parent)
> +{
> + void __iomem *regs = of_iomap(node, 0);
> + struct vic_device *vic;
> + int irq_base;
> +
> + if (WARN_ON(!regs))
> + return -EIO;
> +
> + irq_base = irq_alloc_descs(-1, 0, 32, numa_node_id());
> + if (WARN_ON(irq_base < 0))
> + goto out_unmap;
> +
> + vic = __vic_init(regs, irq_base, ~0, ~0);
> + if (WARN_ON(!vic))
> + goto out_unmap;
> +
> + vic->domain.irq_base = irq_base;
> + vic->domain.nr_irq = 32;
> + vic->domain.of_node = of_node_get(node);
> + vic->domain.ops = &vic_irq_domain_ops;
> + irq_domain_add(&vic->domain);
> +
> + return 0;
> +
> +out_unmap:
Nit: putting a single space before the label makes 'diff' behave
better.
> + iounmap(regs);
> +
> + return -EIO;
> +}
> +
> +#endif /* CONFIG OF */
> diff --git a/arch/arm/include/asm/hardware/vic.h b/arch/arm/include/asm/hardware/vic.h
> index 5d72550..df1d895 100644
> --- a/arch/arm/include/asm/hardware/vic.h
> +++ b/arch/arm/include/asm/hardware/vic.h
> @@ -41,7 +41,18 @@
> #define VIC_PL192_VECT_ADDR 0xF00
>
> #ifndef __ASSEMBLY__
> +struct device_node;
> void vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources, u32 resume_sources);
> -#endif
> +
> +#ifdef CONFIG_OF
> +int vic_of_init(struct device_node *node, struct device_node *parent);
> +#else /* CONFIG_OF */
> +static inline int vic_of_init(struct device_node *node,
> + struct device_node *parent)
> +{
> + return -ENOSYS;
> +}
> +#endif /* CONFIG_OF */
Will this ever be referenced when !CONFIG_OF? It shouldn't be.
Otherwise looks good.
g.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 2/2] ARM: vic: MULTI_IRQ_HANDLER handler
2011-09-27 12:16 ` Jamie Iles
@ 2011-09-27 21:05 ` Grant Likely
-1 siblings, 0 replies; 16+ messages in thread
From: Grant Likely @ 2011-09-27 21:05 UTC (permalink / raw)
To: Jamie Iles; +Cc: devicetree-discuss, linux-arm-kernel
On Tue, Sep 27, 2011 at 01:16:42PM +0100, Jamie Iles wrote:
> Add a handler for the VIC that is suitable for MULTI_IRQ_HANDLER
> platforms. This only works for platforms with CONFIG_OF=y as we can
> determine which controllers are the primary controllers (no parent).
>
> Signed-off-by: Jamie Iles <jamie@jamieiles.com>
> ---
> arch/arm/common/vic.c | 48 +++++++++++++++++++++++++++++++++++
> arch/arm/include/asm/hardware/vic.h | 1 +
> 2 files changed, 49 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/common/vic.c b/arch/arm/common/vic.c
> index 3658579..e9b72d3 100644
> --- a/arch/arm/common/vic.c
> +++ b/arch/arm/common/vic.c
> @@ -63,6 +63,22 @@ static struct vic_device vic_devices[CONFIG_ARM_VIC_NR];
>
> static int vic_id;
>
> +#if defined(CONFIG_OF) && defined(CONFIG_MULTI_IRQ_HANDLER)
> +/*
> + * The root VIC's. We keep track of these so that we can do the IRQ demuxing
> + * as we can have more than one root VIC.
> + */
> +static struct vic_device *vic_root_devices[CONFIG_ARM_VIC_NR];
> +static int nr_root_vics;
> +
> +static void vic_register_root_controller(struct vic_device *vic)
> +{
> + vic_root_devices[nr_root_vics++] = vic;
> +}
> +#else /* CONFIG_OF && CONFIG_MULTI_IRQ_HANDLER */
> +static inline void vic_register_root_controller(struct vic_device *vic) {}
> +#endif /* CONFIG_OF && CONFIG_MULTI_IRQ_HANDLER */
> +
> /**
> * vic_init2 - common initialisation code
> * @base: Base of the VIC.
> @@ -439,6 +455,9 @@ int __init vic_of_init(struct device_node *node, struct device_node *parent)
> vic->domain.ops = &vic_irq_domain_ops;
> irq_domain_add(&vic->domain);
>
> + if (!parent)
> + vic_register_root_controller(vic);
> +
> return 0;
>
> out_unmap:
> @@ -447,4 +466,33 @@ out_unmap:
> return -EIO;
> }
>
> +#ifdef CONFIG_MULTI_IRQ_HANDLER
> +static void vic_single_handle_irq(struct vic_device *vic, struct pt_regs *regs)
> +{
> + u32 stat, irq;
> + bool handled = false;
> +
> + while (!handled) {
> + stat = readl_relaxed(vic->base + VIC_IRQ_STATUS);
> + if (!stat)
> + break;
> +
> + while (stat) {
> + irq = fls(stat) - 1;
> + handle_IRQ(irq + vic->irq, regs);
This is the other reason for irq_domain. Should use
irq_domain_to_irq() here instead of irq + vic->irq. (similar to that,
this driver can also be converted to use (struct irq_data*)->hwirq
instead of the ((struct irq_data*)->irq & 32) that it currently uses.
hwirq was added when irq_domains were added.
> + stat &= ~(1 << irq);
> + handled = true;
> + }
> + }
> +}
> +
> +asmlinkage void __exception_irq_entry vic_handle_irq(struct pt_regs *regs)
> +{
> + int i;
> +
> + for (i = 0; i < nr_root_vics; ++i)
> + vic_single_handle_irq(vic_root_devices[i], regs);
> +}
> +#endif /* CONFIG_MULTI_IRQ_HANDLER */
> +
> #endif /* CONFIG OF */
> diff --git a/arch/arm/include/asm/hardware/vic.h b/arch/arm/include/asm/hardware/vic.h
> index df1d895..451788c 100644
> --- a/arch/arm/include/asm/hardware/vic.h
> +++ b/arch/arm/include/asm/hardware/vic.h
> @@ -53,6 +53,7 @@ static inline int vic_of_init(struct device_node *node,
> return -ENOSYS;
> }
> #endif /* CONFIG_OF */
> +void vic_handle_irq(struct pt_regs *regs);
> #endif /* __ASSEMBLY__ */
>
> #endif
> --
> 1.7.4.1
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 2/2] ARM: vic: MULTI_IRQ_HANDLER handler
@ 2011-09-27 21:05 ` Grant Likely
0 siblings, 0 replies; 16+ messages in thread
From: Grant Likely @ 2011-09-27 21:05 UTC (permalink / raw)
To: linux-arm-kernel
On Tue, Sep 27, 2011 at 01:16:42PM +0100, Jamie Iles wrote:
> Add a handler for the VIC that is suitable for MULTI_IRQ_HANDLER
> platforms. This only works for platforms with CONFIG_OF=y as we can
> determine which controllers are the primary controllers (no parent).
>
> Signed-off-by: Jamie Iles <jamie@jamieiles.com>
> ---
> arch/arm/common/vic.c | 48 +++++++++++++++++++++++++++++++++++
> arch/arm/include/asm/hardware/vic.h | 1 +
> 2 files changed, 49 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/common/vic.c b/arch/arm/common/vic.c
> index 3658579..e9b72d3 100644
> --- a/arch/arm/common/vic.c
> +++ b/arch/arm/common/vic.c
> @@ -63,6 +63,22 @@ static struct vic_device vic_devices[CONFIG_ARM_VIC_NR];
>
> static int vic_id;
>
> +#if defined(CONFIG_OF) && defined(CONFIG_MULTI_IRQ_HANDLER)
> +/*
> + * The root VIC's. We keep track of these so that we can do the IRQ demuxing
> + * as we can have more than one root VIC.
> + */
> +static struct vic_device *vic_root_devices[CONFIG_ARM_VIC_NR];
> +static int nr_root_vics;
> +
> +static void vic_register_root_controller(struct vic_device *vic)
> +{
> + vic_root_devices[nr_root_vics++] = vic;
> +}
> +#else /* CONFIG_OF && CONFIG_MULTI_IRQ_HANDLER */
> +static inline void vic_register_root_controller(struct vic_device *vic) {}
> +#endif /* CONFIG_OF && CONFIG_MULTI_IRQ_HANDLER */
> +
> /**
> * vic_init2 - common initialisation code
> * @base: Base of the VIC.
> @@ -439,6 +455,9 @@ int __init vic_of_init(struct device_node *node, struct device_node *parent)
> vic->domain.ops = &vic_irq_domain_ops;
> irq_domain_add(&vic->domain);
>
> + if (!parent)
> + vic_register_root_controller(vic);
> +
> return 0;
>
> out_unmap:
> @@ -447,4 +466,33 @@ out_unmap:
> return -EIO;
> }
>
> +#ifdef CONFIG_MULTI_IRQ_HANDLER
> +static void vic_single_handle_irq(struct vic_device *vic, struct pt_regs *regs)
> +{
> + u32 stat, irq;
> + bool handled = false;
> +
> + while (!handled) {
> + stat = readl_relaxed(vic->base + VIC_IRQ_STATUS);
> + if (!stat)
> + break;
> +
> + while (stat) {
> + irq = fls(stat) - 1;
> + handle_IRQ(irq + vic->irq, regs);
This is the other reason for irq_domain. Should use
irq_domain_to_irq() here instead of irq + vic->irq. (similar to that,
this driver can also be converted to use (struct irq_data*)->hwirq
instead of the ((struct irq_data*)->irq & 32) that it currently uses.
hwirq was added when irq_domains were added.
> + stat &= ~(1 << irq);
> + handled = true;
> + }
> + }
> +}
> +
> +asmlinkage void __exception_irq_entry vic_handle_irq(struct pt_regs *regs)
> +{
> + int i;
> +
> + for (i = 0; i < nr_root_vics; ++i)
> + vic_single_handle_irq(vic_root_devices[i], regs);
> +}
> +#endif /* CONFIG_MULTI_IRQ_HANDLER */
> +
> #endif /* CONFIG OF */
> diff --git a/arch/arm/include/asm/hardware/vic.h b/arch/arm/include/asm/hardware/vic.h
> index df1d895..451788c 100644
> --- a/arch/arm/include/asm/hardware/vic.h
> +++ b/arch/arm/include/asm/hardware/vic.h
> @@ -53,6 +53,7 @@ static inline int vic_of_init(struct device_node *node,
> return -ENOSYS;
> }
> #endif /* CONFIG_OF */
> +void vic_handle_irq(struct pt_regs *regs);
> #endif /* __ASSEMBLY__ */
>
> #endif
> --
> 1.7.4.1
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2011-09-27 21:05 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-09-27 12:16 [PATCH 1/2] ARM: vic: device tree binding Jamie Iles
2011-09-27 12:16 ` Jamie Iles
[not found] ` <1317125802-14386-1-git-send-email-jamie-wmLquQDDieKakBO8gow8eQ@public.gmane.org>
2011-09-27 12:16 ` [PATCH 2/2] ARM: vic: MULTI_IRQ_HANDLER handler Jamie Iles
2011-09-27 12:16 ` Jamie Iles
[not found] ` <1317125802-14386-2-git-send-email-jamie-wmLquQDDieKakBO8gow8eQ@public.gmane.org>
2011-09-27 13:25 ` Rob Herring
2011-09-27 13:25 ` Rob Herring
[not found] ` <4E81CECA.6050306-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2011-09-27 13:58 ` Jamie Iles
2011-09-27 13:58 ` Jamie Iles
2011-09-27 21:05 ` Grant Likely
2011-09-27 21:05 ` Grant Likely
2011-09-27 13:30 ` [PATCH 1/2] ARM: vic: device tree binding Rob Herring
2011-09-27 13:30 ` Rob Herring
[not found] ` <4E81D003.4040501-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2011-09-27 13:38 ` Jamie Iles
2011-09-27 13:38 ` Jamie Iles
2011-09-27 21:00 ` Grant Likely
2011-09-27 21:00 ` Grant Likely
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.