Skip to contentSkip to conversation

VIC DT binding and MULTI_IRQ_HANDLER

PATCH Superseded Jamie Iles 7 participants 37 messages Sep 28, 2011 – Nov 3, 2011

Subsystems (9)

v2 of 4 Superseded Latest is v4 →

lore
Share & tools
lore

Jamie Iles

author
#0 lore raw

v2 cover VIC DT binding and MULTI_IRQ_HANDLER

This patch series adds a device tree binding for the VIC and support for a generic VIC MULTI_IRQ_HANDLER. The MULTI_IRQ_HANDLER is a step towards a single image kernel, removing the need for mach specific entry handlers for platforms using the VIC as the primary interrupt controller.

This has dependencies on:

	- of/irq: introduce of_irq_init
	http://lists.infradead.org/pipermail/linux-arm-kernel/2011-September/066844.html

	- irq: add declaration of irq_domain_simple_ops to irqdomain.h
	https://lkml.org/lkml/2011/9/14/189

from Rob Herring, and

	- ARM: Make global handler and CONFIG_MULTI_IRQ_HANDLER mutually
	exclusive
	http://www.spinics.net/lists/arm-kernel/msg141948.html

from Marc Zyngier.

Tested on picoxcell and build tested for all defconfigs.

Jamie Iles (10):
ARM: vic: device tree binding
ARM: vic: MULTI_IRQ_HANDLER handler
ARM: ep93xx: convert to MULTI_IRQ_HANDLER
ARM: netx: convert to MULTI_IRQ_HANDLER
ARM: nomadik: convert to MULTI_IRQ_HANDLER
ARM: s3c64xx: convert to MULTI_IRQ_HANDLER
ARM: spear: convert to MULTI_IRQ_HANDLER
ARM: u300: convert to MULTI_IRQ_HANDLER
ARM: versatile: convert to MULTI_IRQ_HANDLER
ARM: samsung: convert to MULTI_IRQ_HANDLER

 Documentation/devicetree/bindings/arm/vic.txt      |   29 ++++
 arch/arm/Kconfig                                   |   10 ++
 arch/arm/common/Kconfig                            |    1 +
 arch/arm/common/vic.c                              |  135 ++++++++++++++++----
 arch/arm/include/asm/hardware/vic.h                |   14 ++-
 arch/arm/mach-ep93xx/adssphere.c                   |    2 +
 arch/arm/mach-ep93xx/edb93xx.c                     |    9 ++
 arch/arm/mach-ep93xx/gesbc9312.c                   |    2 +
 arch/arm/mach-ep93xx/include/mach/entry-macro.S    |   42 ------
 arch/arm/mach-ep93xx/micro9.c                      |    5 +
 arch/arm/mach-ep93xx/simone.c                      |    2 +
 arch/arm/mach-ep93xx/snappercl15.c                 |    2 +
 arch/arm/mach-ep93xx/ts72xx.c                      |    2 +
 arch/arm/mach-netx/include/mach/entry-macro.S      |   13 --
 arch/arm/mach-netx/nxdb500.c                       |    2 +
 arch/arm/mach-netx/nxdkn.c                         |    2 +
 arch/arm/mach-netx/nxeb500hmi.c                    |    2 +
 arch/arm/mach-nomadik/board-nhk8815.c              |    2 +
 arch/arm/mach-nomadik/include/mach/entry-macro.S   |   30 -----
 arch/arm/mach-s3c64xx/include/mach/entry-macro.S   |    7 +-
 arch/arm/mach-s3c64xx/mach-anw6410.c               |    2 +
 arch/arm/mach-s3c64xx/mach-crag6410.c              |    2 +
 arch/arm/mach-s3c64xx/mach-hmt.c                   |    2 +
 arch/arm/mach-s3c64xx/mach-mini6410.c              |    2 +
 arch/arm/mach-s3c64xx/mach-ncp.c                   |    2 +
 arch/arm/mach-s3c64xx/mach-real6410.c              |    2 +
 arch/arm/mach-s3c64xx/mach-smartq5.c               |    2 +
 arch/arm/mach-s3c64xx/mach-smartq7.c               |    2 +
 arch/arm/mach-s3c64xx/mach-smdk6400.c              |    2 +
 arch/arm/mach-s3c64xx/mach-smdk6410.c              |    2 +
 arch/arm/mach-s5p64x0/include/mach/entry-macro.S   |    7 +-
 arch/arm/mach-s5p64x0/mach-smdk6440.c              |    2 +
 arch/arm/mach-s5p64x0/mach-smdk6450.c              |    2 +
 arch/arm/mach-s5pc100/include/mach/entry-macro.S   |   25 ----
 arch/arm/mach-s5pc100/mach-smdkc100.c              |    2 +
 arch/arm/mach-s5pv210/include/mach/entry-macro.S   |   37 ------
 arch/arm/mach-s5pv210/mach-aquila.c                |    2 +
 arch/arm/mach-s5pv210/mach-goni.c                  |    2 +
 arch/arm/mach-s5pv210/mach-smdkc110.c              |    2 +
 arch/arm/mach-s5pv210/mach-smdkv210.c              |    2 +
 arch/arm/mach-s5pv210/mach-torbreck.c              |    2 +
 arch/arm/mach-spear3xx/include/mach/entry-macro.S  |   27 ----
 arch/arm/mach-spear3xx/spear300_evb.c              |    2 +
 arch/arm/mach-spear3xx/spear310_evb.c              |    2 +
 arch/arm/mach-spear3xx/spear320_evb.c              |    2 +
 arch/arm/mach-spear6xx/include/mach/entry-macro.S  |   36 -----
 arch/arm/mach-spear6xx/spear600_evb.c              |    2 +
 arch/arm/mach-u300/include/mach/entry-macro.S      |   24 ----
 arch/arm/mach-u300/u300.c                          |    2 +
 arch/arm/mach-versatile/include/mach/entry-macro.S |   30 -----
 arch/arm/mach-versatile/versatile_ab.c             |    2 +
 arch/arm/mach-versatile/versatile_dt.c             |    2 +
 arch/arm/mach-versatile/versatile_pb.c             |    2 +
 53 files changed, 252 insertions(+), 299 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arm/vic.txt
Signature · 1 line
1.7.4.1
author
#1 lore raw

PATCH v2 1/10 ARM: vic: device tree binding

This adds a device tree binding for the VIC based on the of_irq_init() support. This adds an irqdomain to the vic and always registers all vics in the static vic array rather than for pm only to keep track of the irq domain. struct irq_data::hwirq is used where appropriate rather than runtime masking.

v2: - use irq_domain_simple_ops
- remove stub implementation of vic_of_init for !CONFIG_OF
- Make VIC select IRQ_DOMAIN

Cc Rob Herring <[email protected]>
Cc Grant Likely <[email protected]>
---
 Documentation/devicetree/bindings/arm/vic.txt |   29 +++++++
 arch/arm/common/Kconfig                       |    1 +
 arch/arm/common/vic.c                         |  106 ++++++++++++++++++-------
 arch/arm/include/asm/hardware/vic.h           |   10 ++-
 4 files changed, 117 insertions(+), 29 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arm/vic.txt
Documentation/devicetree/bindings/arm/vic.txt new file +29 -0
new file mode 100644
index 0000000..266716b
@@ -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>;
+	};
arch/arm/common/Kconfig +1 -0
index 4b71766..43e9d1a 100644
@@ -2,6 +2,7 @@ config ARM_GIC
 	bool
 
 config ARM_VIC
+	select IRQ_DOMAIN
 	bool
 
 config ARM_VIC_NR
arch/arm/common/vic.c +78 -28

190 lines not on this page · raw message

arch/arm/include/asm/hardware/vic.h +9 -1
index 5d72550..0135215 100644
@@ -41,7 +41,15 @@
 #define VIC_PL192_VECT_ADDR		0xF00
 
 #ifndef __ASSEMBLY__
+#include <linux/compiler.h>
+#include <linux/types.h>
+
+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);
+#endif /* CONFIG_OF */
+
+#endif /* __ASSEMBLY__ */
 #endif
Signature · 1 line
1.7.4.1
#2 lore raw

PATCH v2 1/10 ARM: vic: device tree binding

Quoted 9 lines · Jamie Iles

This adds a device tree binding for the VIC based on the of_irq_init() support. This adds an irqdomain to the vic and always registers all vics in the static vic array rather than for pm only to keep track of the irq domain. struct irq_data::hwirq is used where appropriate rather than runtime masking.

v2: - use irq_domain_simple_ops
- remove stub implementation of vic_of_init for !CONFIG_OF
- Make VIC select IRQ_DOMAIN

Looks right to me.

Quoted 286 lines
Cc Rob Herring <[email protected]>
Cc Grant Likely <[email protected]>
---
 Documentation/devicetree/bindings/arm/vic.txt |   29 +++++++
 arch/arm/common/Kconfig                       |    1 +
 arch/arm/common/vic.c                         |  106 ++++++++++++++++++-------
 arch/arm/include/asm/hardware/vic.h           |   10 ++-
 4 files changed, 117 insertions(+), 29 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arm/vic.txt
Documentation/devicetree/bindings/arm/vic.txt new file +29 -0
new file mode 100644
index 0000000..266716b
@@ -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>;
+	};
arch/arm/common/Kconfig +1 -0
index 4b71766..43e9d1a 100644
@@ -2,6 +2,7 @@ config ARM_GIC
 	bool
 
 config ARM_VIC
+	select IRQ_DOMAIN
 	bool
 
 config ARM_VIC_NR
arch/arm/common/vic.c +78 -28
index 7aa4262..3f9c8f2 100644
@@ -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.
@@ -40,6 +43,7 @@
  * @int_enable: Save for VIC_INT_ENABLE.
  * @soft_int: Save for VIC_INT_SOFT.
  * @protect: Save for VIC_PROTECT.
+ * @domain: The IRQ domain for the VIC.
  */
 struct vic_device {
 	void __iomem	*base;
@@ -50,13 +54,13 @@ struct vic_device {
 	u32		int_enable;
 	u32		soft_int;
 	u32		protect;
+	struct irq_domain 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,39 +160,50 @@ 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.
+ * @node: The device tree node associated with the VIC.
  *
  * 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.
+ *
+ * This also configures the IRQ domain for the VIC.
  */
-static void __init vic_pm_register(void __iomem *base, unsigned int irq, u32 resume_sources)
+static void __init vic_register(void __iomem *base, unsigned int irq,
+				u32 resume_sources, struct device_node *node)
 {
 	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;
 	}
+
+	v = &vic_devices[vic_id];
+	v->base = base;
+	v->resume_sources = resume_sources;
+	v->irq = irq;
+	vic_id++;
+
+	v->domain.irq_base = irq;
+	v->domain.nr_irq = 32;
+#ifdef CONFIG_OF_IRQ
+	v->domain.of_node = of_node_get(node);
+	v->domain.ops = &irq_domain_simple_ops;
+#endif /* CONFIG_OF */
+	irq_domain_add(&v->domain);
 }
-#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)
 {
 	void __iomem *base = irq_data_get_irq_chip_data(d);
-	unsigned int irq = d->irq & 31;
+	unsigned int irq = d->hwirq;
 	writel(1 << irq, base + VIC_INT_ENABLE_CLEAR);
 	/* moreover, clear the soft-triggered, in case it was the reason */
 	writel(1 << irq, base + VIC_INT_SOFT_CLEAR);
@@ -197,14 +212,14 @@ static void vic_ack_irq(struct irq_data *d)
 static void vic_mask_irq(struct irq_data *d)
 {
 	void __iomem *base = irq_data_get_irq_chip_data(d);
-	unsigned int irq = d->irq & 31;
+	unsigned int irq = d->hwirq;
 	writel(1 << irq, base + VIC_INT_ENABLE_CLEAR);
 }
 
 static void vic_unmask_irq(struct irq_data *d)
 {
 	void __iomem *base = irq_data_get_irq_chip_data(d);
-	unsigned int irq = d->irq & 31;
+	unsigned int irq = d->hwirq;
 	writel(1 << irq, base + VIC_INT_ENABLE);
 }
 
@@ -226,7 +241,7 @@ static struct vic_device *vic_from_irq(unsigned int irq)
 static int vic_set_wake(struct irq_data *d, unsigned int on)
 {
 	struct vic_device *v = vic_from_irq(d->irq);
-	unsigned int off = d->irq & 31;
+	unsigned int off = d->hwirq;
 	u32 bit = 1 << off;
 
 	if (!v)
@@ -331,15 +346,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 void __init __vic_init(void __iomem *base, unsigned int irq_start,
+			      u32 vic_sources, u32 resume_sources,
+			      struct device_node *node)
 {
 	unsigned int i;
 	u32 cellid = 0;
@@ -375,5 +384,46 @@ 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);
+	vic_register(base, irq_start, resume_sources, node);
+}
+
+/**
+ * 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, NULL);
+}
+
+#ifdef CONFIG_OF
+int __init vic_of_init(struct device_node *node, struct device_node *parent)
+{
+	void __iomem *regs;
+	int irq_base;
+
+	if (WARN(parent, "non-root VICs are not supported"))
+		return -EINVAL;
+
+	regs = of_iomap(node, 0);
+	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_init(regs, irq_base, ~0, ~0, node);
+
+	return 0;
+
+ out_unmap:
+	iounmap(regs);
+
+	return -EIO;
 }
+#endif /* CONFIG OF */
arch/arm/include/asm/hardware/vic.h +9 -1
index 5d72550..0135215 100644
@@ -41,7 +41,15 @@
 #define VIC_PL192_VECT_ADDR		0xF00
 
 #ifndef __ASSEMBLY__
+#include <linux/compiler.h>
+#include <linux/types.h>
+
+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);
+#endif /* CONFIG_OF */
+
+#endif /* __ASSEMBLY__ */
 #endif
Signature · 1 line
1.7.4.1
#3 lore raw

PATCH v2 1/10 ARM: vic: device tree binding

In reply to Jamie Iles
Quoted 6 lines · Jamie Iles

This adds a device tree binding for the VIC based on the of_irq_init() support. This adds an irqdomain to the vic and always registers all vics in the static vic array rather than for pm only to keep track of the irq domain. struct irq_data::hwirq is used where appropriate rather than runtime masking.

Quoted 7 lines

v2: - use irq_domain_simple_ops
- remove stub implementation of vic_of_init for !CONFIG_OF
- Make VIC select IRQ_DOMAIN

Cc Rob Herring <[email protected]>
Cc Grant Likely <[email protected]>

Looks good. One minor comment below, but otherwise:

Quoted 266 lines
---
 Documentation/devicetree/bindings/arm/vic.txt |   29 +++++++
 arch/arm/common/Kconfig                       |    1 +
 arch/arm/common/vic.c                         |  106 ++++++++++++++++++-------
 arch/arm/include/asm/hardware/vic.h           |   10 ++-
 4 files changed, 117 insertions(+), 29 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arm/vic.txt
Documentation/devicetree/bindings/arm/vic.txt new file +29 -0
new file mode 100644
index 0000000..266716b
@@ -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>;
+	};
arch/arm/common/Kconfig +1 -0
index 4b71766..43e9d1a 100644
@@ -2,6 +2,7 @@ config ARM_GIC
 	bool
 
 config ARM_VIC
+	select IRQ_DOMAIN
 	bool
 
 config ARM_VIC_NR
arch/arm/common/vic.c +78 -28
index 7aa4262..3f9c8f2 100644
@@ -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.
@@ -40,6 +43,7 @@
  * @int_enable: Save for VIC_INT_ENABLE.
  * @soft_int: Save for VIC_INT_SOFT.
  * @protect: Save for VIC_PROTECT.
+ * @domain: The IRQ domain for the VIC.
  */
 struct vic_device {
 	void __iomem	*base;
@@ -50,13 +54,13 @@ struct vic_device {
 	u32		int_enable;
 	u32		soft_int;
 	u32		protect;
+	struct irq_domain 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,39 +160,50 @@ 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.
+ * @node: The device tree node associated with the VIC.
  *
  * 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.
+ *
+ * This also configures the IRQ domain for the VIC.
  */
-static void __init vic_pm_register(void __iomem *base, unsigned int irq, u32 resume_sources)
+static void __init vic_register(void __iomem *base, unsigned int irq,
+				u32 resume_sources, struct device_node *node)
 {
 	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;
 	}
+
+	v = &vic_devices[vic_id];
+	v->base = base;
+	v->resume_sources = resume_sources;
+	v->irq = irq;
+	vic_id++;
+
+	v->domain.irq_base = irq;
+	v->domain.nr_irq = 32;
+#ifdef CONFIG_OF_IRQ
+	v->domain.of_node = of_node_get(node);
+	v->domain.ops = &irq_domain_simple_ops;
+#endif /* CONFIG_OF */
+	irq_domain_add(&v->domain);
 }
-#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)
 {
 	void __iomem *base = irq_data_get_irq_chip_data(d);
-	unsigned int irq = d->irq & 31;
+	unsigned int irq = d->hwirq;
 	writel(1 << irq, base + VIC_INT_ENABLE_CLEAR);
 	/* moreover, clear the soft-triggered, in case it was the reason */
 	writel(1 << irq, base + VIC_INT_SOFT_CLEAR);
@@ -197,14 +212,14 @@ static void vic_ack_irq(struct irq_data *d)
 static void vic_mask_irq(struct irq_data *d)
 {
 	void __iomem *base = irq_data_get_irq_chip_data(d);
-	unsigned int irq = d->irq & 31;
+	unsigned int irq = d->hwirq;
 	writel(1 << irq, base + VIC_INT_ENABLE_CLEAR);
 }
 
 static void vic_unmask_irq(struct irq_data *d)
 {
 	void __iomem *base = irq_data_get_irq_chip_data(d);
-	unsigned int irq = d->irq & 31;
+	unsigned int irq = d->hwirq;
 	writel(1 << irq, base + VIC_INT_ENABLE);
 }
 
@@ -226,7 +241,7 @@ static struct vic_device *vic_from_irq(unsigned int irq)
 static int vic_set_wake(struct irq_data *d, unsigned int on)
 {
 	struct vic_device *v = vic_from_irq(d->irq);
-	unsigned int off = d->irq & 31;
+	unsigned int off = d->hwirq;
 	u32 bit = 1 << off;
 
 	if (!v)
@@ -331,15 +346,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 void __init __vic_init(void __iomem *base, unsigned int irq_start,
+			      u32 vic_sources, u32 resume_sources,
+			      struct device_node *node)
 {
 	unsigned int i;
 	u32 cellid = 0;
@@ -375,5 +384,46 @@ 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);
+	vic_register(base, irq_start, resume_sources, node);
+}
+
+/**
+ * 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, NULL);
+}
+
+#ifdef CONFIG_OF
+int __init vic_of_init(struct device_node *node, struct device_node *parent)
+{
+	void __iomem *regs;
+	int irq_base;
+
+	if (WARN(parent, "non-root VICs are not supported"))
+		return -EINVAL;
+
+	regs = of_iomap(node, 0);
+	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_init(regs, irq_base, ~0, ~0, node);
+
+	return 0;
+
+ out_unmap:
+	iounmap(regs);
+
+	return -EIO;
 }
+#endif /* CONFIG OF */
arch/arm/include/asm/hardware/vic.h +0 -0
index 5d72550..0135215 100644
@@ -41,7 +41,15 @@
 #define VIC_PL192_VECT_ADDR		0xF00
 
 #ifndef __ASSEMBLY__

arch/arm/include/asm/hardware/vic.h line 52

Quoted 10 lines
arch/arm/include/asm/hardware/vic.h +7 -1
+#include <linux/compiler.h>
+#include <linux/types.h>
+
+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);
+#endif /* CONFIG_OF */

You don't need an ifdef around this.

Rob

author
#4 lore raw

PATCH v2 2/10 ARM: vic: MULTI_IRQ_HANDLER handler

In reply to Jamie Iles

Add a handler for the VIC that is suitable for MULTI_IRQ_HANDLER platforms. This can replace the ASM entry macros for platforms that use the VIC.

v2: - allow the handler be used for !CONFIG_OF
- use irq_domain_to_irq()

Cc Rob Herring <[email protected]>
Cc Grant Likely <[email protected]>
---
 arch/arm/common/vic.c               |   29 +++++++++++++++++++++++++++++
 arch/arm/include/asm/hardware/vic.h |    4 ++++
 2 files changed, 33 insertions(+), 0 deletions(-)
arch/arm/common/vic.c +29 -0
index 3f9c8f2..71adced 100644
@@ -427,3 +427,32 @@ int __init vic_of_init(struct device_node *node, struct device_node *parent)
 	return -EIO;
 }
 #endif /* CONFIG OF */
+
+#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_domain_to_irq(&vic->domain, 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 < vic_id; ++i)
+		vic_single_handle_irq(&vic_devices[i], regs);
+}
+#endif /* CONFIG_MULTI_IRQ_HANDLER */
arch/arm/include/asm/hardware/vic.h +4 -0
index 0135215..c02fd6f 100644
@@ -45,11 +45,15 @@
 #include <linux/types.h>
 
 struct device_node;
+struct pt_regs;
+
 void vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources, u32 resume_sources);
 
 #ifdef CONFIG_OF
 int vic_of_init(struct device_node *node, struct device_node *parent);
 #endif /* CONFIG_OF */
 
+void vic_handle_irq(struct pt_regs *regs);
+
 #endif /* __ASSEMBLY__ */
 #endif
Signature · 1 line
1.7.4.1
#5 lore raw

PATCH v2 2/10 ARM: vic: MULTI_IRQ_HANDLER handler

Review

Quoted 12 lines · Jamie Iles
(quoted diff) +12 -0
+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;

Isn't fls "find last set"?

That means IRQs with higher numbers will be handled first will it not?

For U300 IRQs with lower numbers will be handled first by iteratively testing bit 0 and shifting right:

-1002:  tst     \irqstat, #1
-       bne     1003f
-       add     \irqnr, \irqnr, #1
-       movs    \irqstat, \irqstat, lsr #1
-       bne     1002b

So I would use ffs() for this to work the same way as before in U300.

Since this can have some performance impact, if the platforms differ in whether they handle IRQs from low to high or from high to low might need to be a flag passed in to vic_init() or so...

Yours,
Linus Walleij

author
#6 lore raw

PATCH v2 2/10 ARM: vic: MULTI_IRQ_HANDLER handler

Hi Linus,

Quoted 28 lines · Linus Walleij

Review

Quoted 12 lines · Jamie Iles
(quoted diff) +12 -0
+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;

Isn't fls "find last set"?

That means IRQs with higher numbers will be handled first will it not?

For U300 IRQs with lower numbers will be handled first by iteratively testing bit 0 and shifting right:

-1002: tst \irqstat, #1

(quoted diff) +0 -4
-       bne     1003f
-       add     \irqnr, \irqnr, #1
-       movs    \irqstat, \irqstat, lsr #1
-       bne     1002b
Quoted 6 lines

So I would use ffs() for this to work the same way as before in U300.

Since this can have some performance impact, if the platforms differ in whether they handle IRQs from low to high or from high to low might need to be a flag passed in to vic_init() or so...

I don't know how important the ordering is, but if it is important then we could have vic_handle_irq_msb_first() and vic_handle_irq_lsb_first() as the handlers so there isn't any additional indirection/selection in the interrupt hot-path.

Jamie

#7 lore raw

PATCH v2 2/10 ARM: vic: MULTI_IRQ_HANDLER handler

In reply to Jamie Iles
Quoted 32 lines · Jamie Iles

Add a handler for the VIC that is suitable for MULTI_IRQ_HANDLER platforms. This can replace the ASM entry macros for platforms that use the VIC.

v2: - allow the handler be used for !CONFIG_OF
- use irq_domain_to_irq()

Cc Rob Herring <[email protected]>
Cc Grant Likely <[email protected]>
---
 arch/arm/common/vic.c               |   29 +++++++++++++++++++++++++++++
 arch/arm/include/asm/hardware/vic.h |    4 ++++
 2 files changed, 33 insertions(+), 0 deletions(-)
arch/arm/common/vic.c +9 -0
index 3f9c8f2..71adced 100644
@@ -427,3 +427,32 @@ int __init vic_of_init(struct device_node *node, struct device_node *parent)
 	return -EIO;
 }
 #endif /* CONFIG OF */
+
+#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);

arch/arm/common/vic.c int __init vic_of_init(struct device_node *node, struct device_node *parent) · line 448

Quoted 10 lines
arch/arm/common/vic.c +10 -0
+		if (!stat)
+			break;
+
+		while (stat) {
+			irq = fls(stat) - 1;
+			handle_IRQ(irq_domain_to_irq(&vic->domain, irq), regs);
+			stat &= ~(1 << irq);
+			handled = true;
+		}
+	}

I don't follow why this is written this way. The way I see it, there are two conditions:
1) first read will show no irqs pending (!stat), which will break out of the outer while() loop.

2) or there will be irqs pending, it will enter the second while() loop, which unconditionally sets the handled flag, and causes the outer loop to exit immediately after the inner loop exits.

Why isn't it simply written this way:

	stat = readl_relaxed(vic->base + VIC_IRQ_STATUS);
	while (stat) {
		irq = fls(stat) - 1;
		handle_IRQ(irq_domain_to_irq(&vic->domain, irq), regs);
		stat &= ~(1 << irq);
	}

g.

#8 lore raw

PATCH v2 2/10 ARM: vic: MULTI_IRQ_HANDLER handler

Quoted 8 lines · Grant Likely

Why isn't it simply written this way:

? ? ? ?stat = readl_relaxed(vic->base + VIC_IRQ_STATUS);
? ? ? ?while (stat) {
? ? ? ? ? ? ? ?irq = fls(stat) - 1;
? ? ? ? ? ? ? ?handle_IRQ(irq_domain_to_irq(&vic->domain, irq), regs); ? ? ? ? ? ? ? ?stat &= ~(1 << irq);
? ? ? ?}

That is indeed closer to the assembly loop most platforms have implemented.

Jamie can you test this approach? And also use ffs() insteadof fls()...

Thanks,
Linus Walleij

author
#9 lore raw

PATCH v2 2/10 ARM: vic: MULTI_IRQ_HANDLER handler

Quoted 12 lines · Linus Walleij
Quoted 8 lines · Grant Likely

Why isn't it simply written this way:

? ? ? ?stat = readl_relaxed(vic->base + VIC_IRQ_STATUS);
? ? ? ?while (stat) {
? ? ? ? ? ? ? ?irq = fls(stat) - 1;
? ? ? ? ? ? ? ?handle_IRQ(irq_domain_to_irq(&vic->domain, irq), regs); ? ? ? ? ? ? ? ?stat &= ~(1 << irq);
? ? ? ?}

Quoted 5 lines

That is indeed closer to the assembly loop most platforms have implemented.

Jamie can you test this approach? And also use ffs() insteadof fls()...

OK, here it is (and it works)! That does make it a lot simpler, thanks guys! I've updated the vic-dt branch in my repo too.

Jamie

8<------
From: Jamie Iles <[email protected]>
Subject: [PATCHv3] ARM: vic: MULTI_IRQ_HANDLER handler

Add a handler for the VIC that is suitable for MULTI_IRQ_HANDLER platforms. This can replace the ASM entry macros for platforms that use the VIC.

v3: - simplify irq handling loop as suggested by Grant
- service interrupts from msb->lsb order
v2: - allow the handler be used for !CONFIG_OF
- use irq_domain_to_irq()

Cc Rob Herring <[email protected]>
Cc Grant Likely <[email protected]>
---
 arch/arm/common/vic.c               |   22 ++++++++++++++++++++++
 arch/arm/include/asm/hardware/vic.h |    4 ++++
 2 files changed, 26 insertions(+), 0 deletions(-)
arch/arm/common/vic.c +22 -0
index 3f9c8f2..b22b83d 100644
@@ -427,3 +427,25 @@ int __init vic_of_init(struct device_node *node, struct device_node *parent)
 	return -EIO;
 }
 #endif /* CONFIG OF */
+
+#ifdef CONFIG_MULTI_IRQ_HANDLER
+static void vic_single_handle_irq(struct vic_device *vic, struct pt_regs *regs)
+{
+	u32 stat, irq;
+
+	stat = readl_relaxed(vic->base + VIC_IRQ_STATUS);
+	while (stat) {
+		irq = ffs(stat) - 1;
+		handle_IRQ(irq_domain_to_irq(&vic->domain, irq), regs);
+		stat &= ~(1 << irq);
+	}
+}
+
+asmlinkage void __exception_irq_entry vic_handle_irq(struct pt_regs *regs)
+{
+	int i;
+
+	for (i = 0; i < vic_id; ++i)
+		vic_single_handle_irq(&vic_devices[i], regs);
+}
+#endif /* CONFIG_MULTI_IRQ_HANDLER */
arch/arm/include/asm/hardware/vic.h +4 -0
index 0135215..c02fd6f 100644
@@ -45,11 +45,15 @@
 #include <linux/types.h>
 
 struct device_node;
+struct pt_regs;
+
 void vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources, u32 resume_sources);
 
 #ifdef CONFIG_OF
 int vic_of_init(struct device_node *node, struct device_node *parent);
 #endif /* CONFIG_OF */
 
+void vic_handle_irq(struct pt_regs *regs);
+
 #endif /* __ASSEMBLY__ */
 #endif
Signature · 1 line
1.7.4.1
#10 lore raw

PATCH v2 2/10 ARM: vic: MULTI_IRQ_HANDLER handler

Quoted 32 lines · Jamie Iles
Quoted 12 lines · Linus Walleij
Quoted 8 lines · Grant Likely

Why isn't it simply written this way:

? ? ? ?stat = readl_relaxed(vic->base + VIC_IRQ_STATUS);
? ? ? ?while (stat) {
? ? ? ? ? ? ? ?irq = fls(stat) - 1;
? ? ? ? ? ? ? ?handle_IRQ(irq_domain_to_irq(&vic->domain, irq), regs); ? ? ? ? ? ? ? ?stat &= ~(1 << irq);
? ? ? ?}

Quoted 5 lines

That is indeed closer to the assembly loop most platforms have implemented.

Jamie can you test this approach? And also use ffs() insteadof fls()...

OK, here it is (and it works)! That does make it a lot simpler, thanks guys! I've updated the vic-dt branch in my repo too.

Jamie

8<------
From: Jamie Iles <[email protected]>
Subject: [PATCHv3] ARM: vic: MULTI_IRQ_HANDLER handler

Add a handler for the VIC that is suitable for MULTI_IRQ_HANDLER platforms. This can replace the ASM entry macros for platforms that use the VIC.

Quoted 8 lines

v3: - simplify irq handling loop as suggested by Grant
- service interrupts from msb->lsb order
v2: - allow the handler be used for !CONFIG_OF
- use irq_domain_to_irq()

Cc Rob Herring <[email protected]>
Cc Grant Likely <[email protected]>
Quoted 58 lines
---
 arch/arm/common/vic.c               |   22 ++++++++++++++++++++++
 arch/arm/include/asm/hardware/vic.h |    4 ++++
 2 files changed, 26 insertions(+), 0 deletions(-)
arch/arm/common/vic.c +22 -0
index 3f9c8f2..b22b83d 100644
@@ -427,3 +427,25 @@ int __init vic_of_init(struct device_node *node, struct device_node *parent)
 	return -EIO;
 }
 #endif /* CONFIG OF */
+
+#ifdef CONFIG_MULTI_IRQ_HANDLER
+static void vic_single_handle_irq(struct vic_device *vic, struct pt_regs *regs)
+{
+	u32 stat, irq;
+
+	stat = readl_relaxed(vic->base + VIC_IRQ_STATUS);
+	while (stat) {
+		irq = ffs(stat) - 1;
+		handle_IRQ(irq_domain_to_irq(&vic->domain, irq), regs);
+		stat &= ~(1 << irq);
+	}
+}
+
+asmlinkage void __exception_irq_entry vic_handle_irq(struct pt_regs *regs)
+{
+	int i;
+
+	for (i = 0; i < vic_id; ++i)
+		vic_single_handle_irq(&vic_devices[i], regs);
+}
+#endif /* CONFIG_MULTI_IRQ_HANDLER */
arch/arm/include/asm/hardware/vic.h +4 -0
index 0135215..c02fd6f 100644
@@ -45,11 +45,15 @@
 #include <linux/types.h>
 
 struct device_node;
+struct pt_regs;
+
 void vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources, u32 resume_sources);
 
 #ifdef CONFIG_OF
 int vic_of_init(struct device_node *node, struct device_node *parent);
 #endif /* CONFIG_OF */
 
+void vic_handle_irq(struct pt_regs *regs);
+
 #endif /* __ASSEMBLY__ */
 #endif
Signature · 1 line
1.7.4.1
#11 lore raw

PATCH v2 2/10 ARM: vic: MULTI_IRQ_HANDLER handler

In reply to Jamie Iles
Quoted 10 lines · Jamie Iles
arch/arm/common/vic.c +10 -0
+#ifdef CONFIG_MULTI_IRQ_HANDLER
+static void vic_single_handle_irq(struct vic_device *vic, struct pt_regs *regs)
+{
+	u32 stat, irq;
+
+	stat = readl_relaxed(vic->base + VIC_IRQ_STATUS);
+	while (stat) {
+		irq = ffs(stat) - 1;
+		handle_IRQ(irq_domain_to_irq(&vic->domain, irq), regs);
+		stat &= ~(1 << irq);

arch/arm/common/vic.c int __init vic_of_init(struct device_node *node, struct device_node *parent) · line 450

Quoted 10 lines
arch/arm/common/vic.c +10 -0
+	}
+}
+
+asmlinkage void __exception_irq_entry vic_handle_irq(struct pt_regs *regs)
+{
+	int i;
+
+	for (i = 0; i < vic_id; ++i)
+		vic_single_handle_irq(&vic_devices[i], regs);
+}

And if we receive another interrupt after the read of the register, we'll have to exit all the way back (possibly to userspace) before re-entering the IRQ handling paths back to this point to process it.

Is there any particular reason folk are destroying the built-in efficiency of the IRQ handling which is common-place in the existing assembly approach?

author
#12 lore raw

PATCH v2 2/10 ARM: vic: MULTI_IRQ_HANDLER handler

Quoted 17 lines · Russell King - ARM Linux
Quoted 16 lines · Jamie Iles
arch/arm/common/vic.c +16 -0
+#ifdef CONFIG_MULTI_IRQ_HANDLER
+static void vic_single_handle_irq(struct vic_device *vic, struct pt_regs *regs)
+{
+	u32 stat, irq;
+
+	stat = readl_relaxed(vic->base + VIC_IRQ_STATUS);
+	while (stat) {
+		irq = ffs(stat) - 1;
+		handle_IRQ(irq_domain_to_irq(&vic->domain, irq), regs);
+		stat &= ~(1 << irq);
+	}
+}
+
+asmlinkage void __exception_irq_entry vic_handle_irq(struct pt_regs *regs)
+{
+	int i;
Quoted 8 lines

arch/arm/common/vic.c int __init vic_of_init(struct device_node *node, struct device_node *parent) · line 450

Quoted 4 lines
arch/arm/common/vic.c +4 -0
+
+	for (i = 0; i < vic_id; ++i)
+		vic_single_handle_irq(&vic_devices[i], regs);
+}

And if we receive another interrupt after the read of the register, we'll have to exit all the way back (possibly to userspace) before re-entering the IRQ handling paths back to this point to process it.

OK, so how about something like this instead:

static int vic_single_handle_irq(struct vic_device *vic,
struct pt_regs *regs)

{
	u32 stat, irq;
	int handled = 0;

	stat = readl_relaxed(vic->base + VIC_IRQ_STATUS);
	while (stat) {
		irq = ffs(stat) - 1;
		handle_IRQ(irq_domain_to_irq(&vic->domain, irq), regs);
		stat &= ~(1 << irq);
		handled = 1;
	}

	return handled;
}

asmlinkage void __exception_irq_entry vic_handle_irq(struct pt_regs *regs)

{
	int i, handled;

	do {
		handled = 0;
		for (i = 0; i < vic_id; ++i)
			if (vic_single_handle_irq(&vic_devices[i], regs))
				handled = 1;
	} while (handled);
}

which I think should keep handling IRQ's until no VIC has them pending (or as best can be determined).

Quoted 3 lines

Is there any particular reason folk are destroying the built-in efficiency of the IRQ handling which is common-place in the existing assembly approach?

Well this approach makes a single image kernel a bit easier. The other thing is that it plays a lot nicer with dynamic irq_desc assignment. Grant's IRQ domain patches make this quite easy here, but I can't see an obvious way to do that with the assembly method.

Jamie

#13 lore raw

PATCH v2 2/10 ARM: vic: MULTI_IRQ_HANDLER handler

Quoted 10 lines · Jamie Iles
Quoted 4 lines · Russell King - ARM Linux

And if we receive another interrupt after the read of the register, we'll have to exit all the way back (possibly to userspace) before re-entering the IRQ handling paths back to this point to process it.

OK, so how about something like this instead:

static int vic_single_handle_irq(struct vic_device *vic, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? struct pt_regs *regs)

Is it single really? This handles all active IRQs on the VIC instance. Can it be renamed vic_handle_irq()?

Quoted 12 lines

{
? ? ? ?u32 stat, irq;
? ? ? ?int handled = 0;

? ? ? ?stat = readl_relaxed(vic->base + VIC_IRQ_STATUS);
? ? ? ?while (stat) {
? ? ? ? ? ? ? ?irq = ffs(stat) - 1;
? ? ? ? ? ? ? ?handle_IRQ(irq_domain_to_irq(&vic->domain, irq), regs); ? ? ? ? ? ? ? ?stat &= ~(1 << irq);
? ? ? ? ? ? ? ?handled = 1;
? ? ? ?}

Quoted 2 lines

? ? ? ?return handled;
}

No, if we receive another IRQ *after* the read of the register was the question, right?

Just replace

stat &= ~(1 << irq);

with a second

stat = readl_relaxed(vic->base + VIC_IRQ_STATUS);

It'll work just fine, the IRQ line should be low when you read it the second time, else it is probably fully proper to call the IRQ handler again anyway.

Just my ?0.01..
Linus Walleij

#14 lore raw

PATCH v2 2/10 ARM: vic: MULTI_IRQ_HANDLER handler

Quoted 7 lines · Linus Walleij

No, if we receive another IRQ *after* the read of the register was the question, right?

Just replace

stat &= ~(1 << irq);

Quoted 7 lines

with a second

stat = readl_relaxed(vic->base + VIC_IRQ_STATUS);

It'll work just fine, the IRQ line should be low when you read it the second time, else it is probably fully proper to call the IRQ handler again anyway.

It depends on what kind of behaviour you want. There are two solutions:

	stat = readl_relaxed(vic->base + VIC_IRQ_STATUS);
	while (stat) {
		irq = ffs(stat) - 1;
		handle_irq(irq);
		stat = readl_relaxed(vic->base + VIC_IRQ_STATUS);
	}

This gives priority to the lowest numbered interrupts; if these get stuck then they can exclude higher numbered interrupts. This is what we implement in the assembly code versions, and as far as I know, no one has ever complained about that behaviour.

	stat = readl_relaxed(vic->base + VIC_IRQ_STATUS);
	while (stat) {
		while (stat) {
			irq = ffs(stat) - 1;
			stat &= ~(1 << irq);
			handle_irq(irq);
		}
		stat = readl_relaxed(vic->base + VIC_IRQ_STATUS);
	}

This ensures that we process all interrupts found pending before we re-check for any new interrupts pending. Arguably this is a much fairer implementation (and may mean if things get irrevokably stuck, things like sysrq via the console uart may still work.)

#15 lore raw

PATCH v2 2/10 ARM: vic: MULTI_IRQ_HANDLER handler

Quoted 10 lines · Russell King - ARM Linux

? ? ? ?stat = readl_relaxed(vic->base + VIC_IRQ_STATUS); ? ? ? ?while (stat) {
? ? ? ? ? ? ? ?while (stat) {
? ? ? ? ? ? ? ? ? ? ? ?irq = ffs(stat) - 1;
? ? ? ? ? ? ? ? ? ? ? ?stat &= ~(1 << irq);
? ? ? ? ? ? ? ? ? ? ? ?handle_irq(irq);
? ? ? ? ? ? ? ?}
? ? ? ? ? ? ? ?stat = readl_relaxed(vic->base + VIC_IRQ_STATUS); ? ? ? ?}

Quoted 4 lines

This ensures that we process all interrupts found pending before we re-check for any new interrupts pending. ?Arguably this is a much fairer implementation (and may mean if things get irrevokably stuck, things like sysrq via the console uart may still work.)

I really like the looks of this, Jamie can you do it like that?

Maybe some smallish comment about what's going on can be good for future generations reading that code...

Yours,
Linus Walleij

author
#16 lore raw

PATCH v2 2/10 ARM: vic: MULTI_IRQ_HANDLER handler

Quoted 13 lines · Linus Walleij
Quoted 10 lines · Russell King - ARM Linux

? ? ? ?stat = readl_relaxed(vic->base + VIC_IRQ_STATUS); ? ? ? ?while (stat) {
? ? ? ? ? ? ? ?while (stat) {
? ? ? ? ? ? ? ? ? ? ? ?irq = ffs(stat) - 1;
? ? ? ? ? ? ? ? ? ? ? ?stat &= ~(1 << irq);
? ? ? ? ? ? ? ? ? ? ? ?handle_irq(irq);
? ? ? ? ? ? ? ?}
? ? ? ? ? ? ? ?stat = readl_relaxed(vic->base + VIC_IRQ_STATUS); ? ? ? ?}

Quoted 6 lines
Quoted 4 lines

This ensures that we process all interrupts found pending before we re-check for any new interrupts pending. ?Arguably this is a much fairer implementation (and may mean if things get irrevokably stuck, things like sysrq via the console uart may still work.)

I really like the looks of this, Jamie can you do it like that?

Yup, I'll respin either tonight or tomorrow night and rebase ontop of the asm/exception.h patch. Do we also want the behaviour so that it keeps looping over all VIC's until there are no pending interrupts? I think that's probably worth it.

Quoted 2 lines

Maybe some smallish comment about what's going on can be good for future generations reading that code...

OK, will do.

Thanks Linus and Russell!

Jamie

#17 lore raw

PATCH v2 2/10 ARM: vic: MULTI_IRQ_HANDLER handler

In reply to Linus Walleij
Quoted 18 lines · Linus Walleij
Quoted 10 lines · Russell King - ARM Linux

? ? ? ?stat = readl_relaxed(vic->base + VIC_IRQ_STATUS); ? ? ? ?while (stat) {
? ? ? ? ? ? ? ?while (stat) {
? ? ? ? ? ? ? ? ? ? ? ?irq = ffs(stat) - 1;
? ? ? ? ? ? ? ? ? ? ? ?stat &= ~(1 << irq);
? ? ? ? ? ? ? ? ? ? ? ?handle_irq(irq);
? ? ? ? ? ? ? ?}
? ? ? ? ? ? ? ?stat = readl_relaxed(vic->base + VIC_IRQ_STATUS); ? ? ? ?}

Quoted 4 lines

This ensures that we process all interrupts found pending before we re-check for any new interrupts pending. ?Arguably this is a much fairer implementation (and may mean if things get irrevokably stuck, things like sysrq via the console uart may still work.)

Quoted 4 lines

I really like the looks of this, Jamie can you do it like that?

Maybe some smallish comment about what's going on can be good for future generations reading that code...

Bear in mind that it gets a little more complex when you have more than one VIC, because the outer loop should be across all VICs.

author
#18 lore raw

PATCH v2 2/10 ARM: vic: MULTI_IRQ_HANDLER handler

Quoted 19 lines · Russell King - ARM Linux
Quoted 18 lines · Linus Walleij
Quoted 14 lines · Russell King - ARM Linux

? ? ? ?stat = readl_relaxed(vic->base + VIC_IRQ_STATUS); ? ? ? ?while (stat) {
? ? ? ? ? ? ? ?while (stat) {
? ? ? ? ? ? ? ? ? ? ? ?irq = ffs(stat) - 1;
? ? ? ? ? ? ? ? ? ? ? ?stat &= ~(1 << irq);
? ? ? ? ? ? ? ? ? ? ? ?handle_irq(irq);
? ? ? ? ? ? ? ?}
? ? ? ? ? ? ? ?stat = readl_relaxed(vic->base + VIC_IRQ_STATUS); ? ? ? ?}

This ensures that we process all interrupts found pending before we re-check for any new interrupts pending. ?Arguably this is a much fairer implementation (and may mean if things get irrevokably stuck, things like sysrq via the console uart may still work.)

Quoted 7 lines
Quoted 4 lines

I really like the looks of this, Jamie can you do it like that?

Maybe some smallish comment about what's going on can be good for future generations reading that code...

Bear in mind that it gets a little more complex when you have more than one VIC, because the outer loop should be across all VICs.

OK, so I think what I posted yesterday does that (updated for slightly better naming) and with a description. In the spirit of fairness iterating over the VIC's this way seemed right to me.

/*
* Handle each interrupt in a single VIC. Returns non-zero if we've
* handled at least one interrupt. This does a single read of the
* status register and handles all interrupts in order from LSB first. */
static int handle_one_vic(struct vic_device *vic,
struct pt_regs *regs)

{
	u32 stat, irq;
	int handled = 0;

	stat = readl_relaxed(vic->base + VIC_IRQ_STATUS);
	while (stat) {
		irq = ffs(stat) - 1;
		handle_IRQ(irq_domain_to_irq(&vic->domain, irq), regs);
		stat &= ~(1 << irq);
		handled = 1;
	}

	return handled;
}

/*
* Keep iterating over all registered VIC's until there are no pending
* interrupts.
*/
asmlinkage void __exception_irq_entry vic_handle_irq(struct pt_regs *regs)

{
	int i, handled;

	do {
		for (i = 0, handled = 0; i < vic_id; ++i)
			handled |= vic_single_handle_irq(&vic_devices[i],
							 regs))
	} while (handled);
}

Jamie

#19 lore raw

PATCH v2 2/10 ARM: vic: MULTI_IRQ_HANDLER handler

Quoted 25 lines · Jamie Iles
Quoted 24 lines · Russell King - ARM Linux
Quoted 22 lines · Linus Walleij
Quoted 10 lines · Russell King - ARM Linux

? ? ? ?stat = readl_relaxed(vic->base + VIC_IRQ_STATUS); ? ? ? ?while (stat) {
? ? ? ? ? ? ? ?while (stat) {
? ? ? ? ? ? ? ? ? ? ? ?irq = ffs(stat) - 1;
? ? ? ? ? ? ? ? ? ? ? ?stat &= ~(1 << irq);
? ? ? ? ? ? ? ? ? ? ? ?handle_irq(irq);
? ? ? ? ? ? ? ?}
? ? ? ? ? ? ? ?stat = readl_relaxed(vic->base + VIC_IRQ_STATUS); ? ? ? ?}

Quoted 4 lines

This ensures that we process all interrupts found pending before we re-check for any new interrupts pending. ?Arguably this is a much fairer implementation (and may mean if things get irrevokably stuck, things like sysrq via the console uart may still work.)

I really like the looks of this, Jamie can you do it like that?

Maybe some smallish comment about what's going on can be good for future generations reading that code...

Quoted 6 lines
Quoted 2 lines

Bear in mind that it gets a little more complex when you have more than one VIC, because the outer loop should be across all VICs.

OK, so I think what I posted yesterday does that (updated for slightly better naming) and with a description. In the spirit of fairness iterating over the VIC's this way seemed right to me.

Yes.

#20 lore raw

PATCH v2 2/10 ARM: vic: MULTI_IRQ_HANDLER handler

In reply to Russell King - ARM Linux
Quoted 9 lines · Russell King - ARM Linux
	stat = readl_relaxed(vic->base + VIC_IRQ_STATUS);
	while (stat) {
		while (stat) {
			irq = ffs(stat) - 1;
			stat &= ~(1 << irq);
			handle_irq(irq);
		}
		stat = readl_relaxed(vic->base + VIC_IRQ_STATUS);
	}

The inner loop could be a do { } while() construct to avoid evaluating stat twice on each outer loop itteration. Maybe gcc is smart enough to notice though, maybe not.

Nicolas

#21 lore raw

PATCH v2 2/10 ARM: vic: MULTI_IRQ_HANDLER handler

In reply to Jamie Iles

2011/9/28 Jamie Iles <[email protected]>:

Quoted 19 lines

Add a handler for the VIC that is suitable for MULTI_IRQ_HANDLER platforms. ?This can replace the ASM entry macros for platforms that use the VIC.

v2: ? ? - allow the handler be used for !CONFIG_OF ? ? ? ?- use irq_domain_to_irq()

Cc Rob Herring <[email protected]>
Cc Grant Likely <[email protected]>

---
?arch/arm/common/vic.c ? ? ? ? ? ? ? | ? 29 +++++++++++++++++++++++++++++ ?arch/arm/include/asm/hardware/vic.h | ? ?4 ++++
?2 files changed, 33 insertions(+), 0 deletions(-)

arch/arm/common/vic.c +0 -0
index 3f9c8f2..71adced 100644

arch/arm/common/vic.c int __init vic_of_init(struct device_node *node, struct device_node *parent) · line 458

Quoted 9 lines
arch/arm/common/vic.c +8 -0
 
+asmlinkage void __exception_irq_entry vic_handle_irq(struct pt_regs *regs)
+{
+ ? ? ? int i;
+
+ ? ? ? for (i = 0; i < vic_id; ++i)
+ ? ? ? ? ? ? ? vic_single_handle_irq(&vic_devices[i], regs);
+}
+#endif /* CONFIG_MULTI_IRQ_HANDLER */

__exception_irq_entry doesn't compile with CONFIG_FUNCTION_GRAPH_TRACER enabled. Either this file, or arch/arm/include/asm/system.h needs an #include <linux/ftrace.h>

Cheers,
Zoltan

author
#22 lore raw

PATCH v2 2/10 ARM: vic: MULTI_IRQ_HANDLER handler

Quoted 21 lines · Zoltan Devai

2011/9/28 Jamie Iles <[email protected]>:

Quoted 19 lines

Add a handler for the VIC that is suitable for MULTI_IRQ_HANDLER platforms. ?This can replace the ASM entry macros for platforms that use the VIC.

v2: ? ? - allow the handler be used for !CONFIG_OF ? ? ? ?- use irq_domain_to_irq()

Cc Rob Herring <[email protected]>
Cc Grant Likely <[email protected]>

---
?arch/arm/common/vic.c ? ? ? ? ? ? ? | ? 29 +++++++++++++++++++++++++++++ ?arch/arm/include/asm/hardware/vic.h | ? ?4 ++++
?2 files changed, 33 insertions(+), 0 deletions(-)

arch/arm/common/vic.c +0 -0
index 3f9c8f2..71adced 100644
Quoted 12 lines

arch/arm/common/vic.c int __init vic_of_init(struct device_node *node, struct device_node *parent) · line 458

Quoted 8 lines
arch/arm/common/vic.c +8 -0
+asmlinkage void __exception_irq_entry vic_handle_irq(struct pt_regs *regs)
+{
+ ? ? ? int i;
+
+ ? ? ? for (i = 0; i < vic_id; ++i)
+ ? ? ? ? ? ? ? vic_single_handle_irq(&vic_devices[i], regs);
+}
+#endif /* CONFIG_MULTI_IRQ_HANDLER */

__exception_irq_entry doesn't compile with CONFIG_FUNCTION_GRAPH_TRACER enabled. Either this file, or arch/arm/include/asm/system.h needs an #include <linux/ftrace.h>

Thanks Zoltan, I'm just sending a patch now!

Jamie

author
#23 lore raw

PATCH v2 3/10 ARM: ep93xx: convert to MULTI_IRQ_HANDLER

In reply to Jamie Iles

Now that there is a generic IRQ handler for multiple VIC devices use it for ep93xx to help building multi platform kernels.

Cc Hartley Sweeten <[email protected]>
Cc Ryan Mallon <[email protected]>
---
 arch/arm/Kconfig                                |    1 +
 arch/arm/mach-ep93xx/adssphere.c                |    2 +
 arch/arm/mach-ep93xx/edb93xx.c                  |    9 +++++
 arch/arm/mach-ep93xx/gesbc9312.c                |    2 +
 arch/arm/mach-ep93xx/include/mach/entry-macro.S |   42 -----------------------
 arch/arm/mach-ep93xx/micro9.c                   |    5 +++
 arch/arm/mach-ep93xx/simone.c                   |    2 +
 arch/arm/mach-ep93xx/snappercl15.c              |    2 +
 arch/arm/mach-ep93xx/ts72xx.c                   |    2 +
 9 files changed, 25 insertions(+), 42 deletions(-)
arch/arm/Kconfig +1 -0
index 5ebc5d9..7facb7c 100644
@@ -377,6 +377,7 @@ config ARCH_EP93XX
 	select ARCH_REQUIRE_GPIOLIB
 	select ARCH_HAS_HOLES_MEMORYMODEL
 	select ARCH_USES_GETTIMEOFFSET
+	select MULTI_IRQ_HANDLER
 	help
 	  This enables support for the Cirrus EP93xx series of CPUs.
 
arch/arm/mach-ep93xx/adssphere.c +2 -0
index 61b98ce..1c09d24 100644
@@ -16,6 +16,7 @@
 
 #include <mach/hardware.h>
 
+#include <asm/hardware/vic.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
@@ -36,6 +37,7 @@ MACHINE_START(ADSSPHERE, "ADS Sphere board")
 	.boot_params	= EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100,
 	.map_io		= ep93xx_map_io,
 	.init_irq	= ep93xx_init_irq,
+	.handle_irq	= vic_handle_irq,
 	.timer		= &ep93xx_timer,
 	.init_machine	= adssphere_init_machine,
 MACHINE_END
arch/arm/mach-ep93xx/edb93xx.c +9 -0
index 9969bb1..d2f0609 100644
@@ -38,6 +38,7 @@
 #include <mach/fb.h>
 #include <mach/ep93xx_spi.h>
 
+#include <asm/hardware/vic.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
@@ -243,6 +244,7 @@ MACHINE_START(EDB9301, "Cirrus Logic EDB9301 Evaluation Board")
 	.boot_params	= EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100,
 	.map_io		= ep93xx_map_io,
 	.init_irq	= ep93xx_init_irq,
+	.handle_irq	= vic_handle_irq,
 	.timer		= &ep93xx_timer,
 	.init_machine	= edb93xx_init_machine,
 MACHINE_END
@@ -254,6 +256,7 @@ MACHINE_START(EDB9302, "Cirrus Logic EDB9302 Evaluation Board")
 	.boot_params	= EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100,
 	.map_io		= ep93xx_map_io,
 	.init_irq	= ep93xx_init_irq,
+	.handle_irq	= vic_handle_irq,
 	.timer		= &ep93xx_timer,
 	.init_machine	= edb93xx_init_machine,
 MACHINE_END
@@ -265,6 +268,7 @@ MACHINE_START(EDB9302A, "Cirrus Logic EDB9302A Evaluation Board")
 	.boot_params	= EP93XX_SDCE0_PHYS_BASE + 0x100,
 	.map_io		= ep93xx_map_io,
 	.init_irq	= ep93xx_init_irq,
+	.handle_irq	= vic_handle_irq,
 	.timer		= &ep93xx_timer,
 	.init_machine	= edb93xx_init_machine,
 MACHINE_END
@@ -276,6 +280,7 @@ MACHINE_START(EDB9307, "Cirrus Logic EDB9307 Evaluation Board")
 	.boot_params	= EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100,
 	.map_io		= ep93xx_map_io,
 	.init_irq	= ep93xx_init_irq,
+	.handle_irq	= vic_handle_irq,
 	.timer		= &ep93xx_timer,
 	.init_machine	= edb93xx_init_machine,
 MACHINE_END
@@ -287,6 +292,7 @@ MACHINE_START(EDB9307A, "Cirrus Logic EDB9307A Evaluation Board")
 	.boot_params	= EP93XX_SDCE0_PHYS_BASE + 0x100,
 	.map_io		= ep93xx_map_io,
 	.init_irq	= ep93xx_init_irq,
+	.handle_irq	= vic_handle_irq,
 	.timer		= &ep93xx_timer,
 	.init_machine	= edb93xx_init_machine,
 MACHINE_END
@@ -298,6 +304,7 @@ MACHINE_START(EDB9312, "Cirrus Logic EDB9312 Evaluation Board")
 	.boot_params	= EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100,
 	.map_io		= ep93xx_map_io,
 	.init_irq	= ep93xx_init_irq,
+	.handle_irq	= vic_handle_irq,
 	.timer		= &ep93xx_timer,
 	.init_machine	= edb93xx_init_machine,
 MACHINE_END
@@ -309,6 +316,7 @@ MACHINE_START(EDB9315, "Cirrus Logic EDB9315 Evaluation Board")
 	.boot_params	= EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100,
 	.map_io		= ep93xx_map_io,
 	.init_irq	= ep93xx_init_irq,
+	.handle_irq	= vic_handle_irq,
 	.timer		= &ep93xx_timer,
 	.init_machine	= edb93xx_init_machine,
 MACHINE_END
@@ -320,6 +328,7 @@ MACHINE_START(EDB9315A, "Cirrus Logic EDB9315A Evaluation Board")
 	.boot_params	= EP93XX_SDCE0_PHYS_BASE + 0x100,
 	.map_io		= ep93xx_map_io,
 	.init_irq	= ep93xx_init_irq,
+	.handle_irq	= vic_handle_irq,
 	.timer		= &ep93xx_timer,
 	.init_machine	= edb93xx_init_machine,
 MACHINE_END
arch/arm/mach-ep93xx/gesbc9312.c +2 -0
index 9bd3152..5e646b9 100644
@@ -16,6 +16,7 @@
 
 #include <mach/hardware.h>
 
+#include <asm/hardware/vic.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
@@ -36,6 +37,7 @@ MACHINE_START(GESBC9312, "Glomation GESBC-9312-sx")
 	.boot_params	= EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100,
 	.map_io		= ep93xx_map_io,
 	.init_irq	= ep93xx_init_irq,
+	.handle_irq	= vic_handle_irq,
 	.timer		= &ep93xx_timer,
 	.init_machine	= gesbc9312_init_machine,
 MACHINE_END
arch/arm/mach-ep93xx/include/mach/entry-macro.S +0 -42

51 lines not on this page · raw message

arch/arm/mach-ep93xx/micro9.c +5 -0
index 7adea62..5b882b4 100644
@@ -18,6 +18,7 @@
 
 #include <mach/hardware.h>
 
+#include <asm/hardware/vic.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
@@ -80,6 +81,7 @@ MACHINE_START(MICRO9, "Contec Micro9-High")
 	.boot_params	= EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100,
 	.map_io		= ep93xx_map_io,
 	.init_irq	= ep93xx_init_irq,
+	.handle_irq	= vic_handle_irq,
 	.timer		= &ep93xx_timer,
 	.init_machine	= micro9_init_machine,
 MACHINE_END
@@ -91,6 +93,7 @@ MACHINE_START(MICRO9M, "Contec Micro9-Mid")
 	.boot_params	= EP93XX_SDCE3_PHYS_BASE_ASYNC + 0x100,
 	.map_io		= ep93xx_map_io,
 	.init_irq	= ep93xx_init_irq,
+	.handle_irq	= vic_handle_irq,
 	.timer		= &ep93xx_timer,
 	.init_machine	= micro9_init_machine,
 MACHINE_END
@@ -102,6 +105,7 @@ MACHINE_START(MICRO9L, "Contec Micro9-Lite")
 	.boot_params	= EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100,
 	.map_io		= ep93xx_map_io,
 	.init_irq	= ep93xx_init_irq,
+	.handle_irq	= vic_handle_irq,
 	.timer		= &ep93xx_timer,
 	.init_machine	= micro9_init_machine,
 MACHINE_END
@@ -113,6 +117,7 @@ MACHINE_START(MICRO9S, "Contec Micro9-Slim")
 	.boot_params	= EP93XX_SDCE3_PHYS_BASE_ASYNC + 0x100,
 	.map_io		= ep93xx_map_io,
 	.init_irq	= ep93xx_init_irq,
+	.handle_irq	= vic_handle_irq,
 	.timer		= &ep93xx_timer,
 	.init_machine	= micro9_init_machine,
 MACHINE_END
arch/arm/mach-ep93xx/simone.c +2 -0
index 8392e95..cd5a263 100644
@@ -25,6 +25,7 @@
 #include <mach/hardware.h>
 #include <mach/fb.h>
 
+#include <asm/hardware/vic.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
@@ -69,6 +70,7 @@ MACHINE_START(SIM_ONE, "Simplemachines Sim.One Board")
 	.boot_params	= EP93XX_SDCE0_PHYS_BASE + 0x100,
 	.map_io		= ep93xx_map_io,
 	.init_irq	= ep93xx_init_irq,
+	.handle_irq	= vic_handle_irq,
 	.timer		= &ep93xx_timer,
 	.init_machine	= simone_init_machine,
 MACHINE_END
arch/arm/mach-ep93xx/snappercl15.c +2 -0
index 2e9c614..8959764 100644
@@ -31,6 +31,7 @@
 #include <mach/hardware.h>
 #include <mach/fb.h>
 
+#include <asm/hardware/vic.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
@@ -166,6 +167,7 @@ MACHINE_START(SNAPPER_CL15, "Bluewater Systems Snapper CL15")
 	.boot_params	= EP93XX_SDCE0_PHYS_BASE + 0x100,
 	.map_io		= ep93xx_map_io,
 	.init_irq	= ep93xx_init_irq,
+	.handle_irq	= vic_handle_irq,
 	.timer 		= &ep93xx_timer,
 	.init_machine	= snappercl15_init_machine,
 MACHINE_END
arch/arm/mach-ep93xx/ts72xx.c +2 -0
index c2d2cf4..75e1249 100644
@@ -23,6 +23,7 @@
 #include <mach/hardware.h>
 #include <mach/ts72xx.h>
 
+#include <asm/hardware/vic.h>
 #include <asm/mach-types.h>
 #include <asm/mach/map.h>
 #include <asm/mach/arch.h>
@@ -260,6 +261,7 @@ MACHINE_START(TS72XX, "Technologic Systems TS-72xx SBC")
 	.boot_params	= EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100,
 	.map_io		= ts72xx_map_io,
 	.init_irq	= ep93xx_init_irq,
+	.handle_irq	= vic_handle_irq,
 	.timer		= &ep93xx_timer,
 	.init_machine	= ts72xx_init_machine,
 MACHINE_END
Signature · 1 line
1.7.4.1
#24 lore raw

PATCH v2 3/10 ARM: ep93xx: convert to MULTI_IRQ_HANDLER

Quoted 5 lines · Jamie Iles

- ? ? ? ? ? ? ? .macro ?get_irqnr_and_base, irqnr, irqstat, base, tmp
- ? ? ? ? ? ? ? ldr ? ? \base, =(EP93XX_AHB_VIRT_BASE)
- ? ? ? ? ? ? ? orr ? ? \base, \base, #0x000b0000
- ? ? ? ? ? ? ? mov ? ? \irqnr, #0
- ? ? ? ? ? ? ? ldr ? ? \irqstat, [\base] ? ? ? ? ? ? ? @ lower 32 interrupts

Quoted 8 lines

- ? ? ? ? ? ? ? cmp ? ? \irqstat, #0
- ? ? ? ? ? ? ? bne ? ? 1001f
-
- ? ? ? ? ? ? ? eor ? ? \base, \base, #0x00070000
- ? ? ? ? ? ? ? ldr ? ? \irqstat, [\base] ? ? ? ? ? ? ? @ upper 32 interrupts
- ? ? ? ? ? ? ? cmp ? ? \irqstat, #0
- ? ? ? ? ? ? ? beq ? ? 1002f
- ? ? ? ? ? ? ? mov ? ? \irqnr, #0x20

Two VIC instances again...

Yours,
Linus Walleij

author
#25 lore raw

PATCH v2 4/10 ARM: netx: convert to MULTI_IRQ_HANDLER

In reply to Jamie Iles

Now that there is a generic IRQ handler for multiple VIC devices use it for netx to help building multi platform kernels.

---
 arch/arm/Kconfig                              |    1 +
 arch/arm/mach-netx/include/mach/entry-macro.S |   13 -------------
 arch/arm/mach-netx/nxdb500.c                  |    2 ++
 arch/arm/mach-netx/nxdkn.c                    |    2 ++
 arch/arm/mach-netx/nxeb500hmi.c               |    2 ++
 5 files changed, 7 insertions(+), 13 deletions(-)
arch/arm/Kconfig +1 -0
index 7facb7c..b7cab06 100644
@@ -416,6 +416,7 @@ config ARCH_NETX
 	select CPU_ARM926T
 	select ARM_VIC
 	select GENERIC_CLOCKEVENTS
+	select MULTI_IRQ_HANDLER
 	help
 	  This enables support for systems based on the Hilscher NetX Soc
 
arch/arm/mach-netx/include/mach/entry-macro.S +0 -13
index 844f1f9..6e9f1cb 100644
@@ -18,22 +18,9 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
-#include <mach/hardware.h>
 
 		.macro  disable_fiq
 		.endm
 
-		.macro  get_irqnr_preamble, base, tmp
-		ldr	\base, =io_p2v(0x001ff000)
-		.endm
-
 		.macro  arch_ret_to_user, tmp1, tmp2
 		.endm
-
-		.macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
-		ldr	\irqstat, [\base, #0]
-		clz	\irqnr, \irqstat
-		rsb     \irqnr, \irqnr, #31
-		cmp	\irqstat, #0
-		.endm
-
arch/arm/mach-netx/nxdb500.c +2 -0
index ca8b203..e86aea8 100644
@@ -28,6 +28,7 @@
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
+#include <asm/hardware/vic.h>
 #include <mach/netx-regs.h>
 #include <mach/eth.h>
 
@@ -203,6 +204,7 @@ MACHINE_START(NXDB500, "Hilscher nxdb500")
 	.boot_params	= 0x80000100,
 	.map_io		= netx_map_io,
 	.init_irq	= netx_init_irq,
+	.handle_irq	= vic_handle_irq,
 	.timer		= &netx_timer,
 	.init_machine	= nxdb500_init,
 MACHINE_END
arch/arm/mach-netx/nxdkn.c +2 -0
index d775cbe..b3170da 100644
@@ -28,6 +28,7 @@
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
+#include <asm/hardware/vic.h>
 #include <mach/netx-regs.h>
 #include <mach/eth.h>
 
@@ -96,6 +97,7 @@ MACHINE_START(NXDKN, "Hilscher nxdkn")
 	.boot_params	= 0x80000100,
 	.map_io		= netx_map_io,
 	.init_irq	= netx_init_irq,
+	.handle_irq	= vic_handle_irq,
 	.timer		= &netx_timer,
 	.init_machine	= nxdkn_init,
 MACHINE_END
arch/arm/mach-netx/nxeb500hmi.c +2 -0
index de369cd..dc6fa77 100644
@@ -28,6 +28,7 @@
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
+#include <asm/hardware/vic.h>
 #include <mach/netx-regs.h>
 #include <mach/eth.h>
 
@@ -180,6 +181,7 @@ MACHINE_START(NXEB500HMI, "Hilscher nxeb500hmi")
 	.boot_params	= 0x80000100,
 	.map_io		= netx_map_io,
 	.init_irq	= netx_init_irq,
+	.handle_irq	= vic_handle_irq,
 	.timer		= &netx_timer,
 	.init_machine	= nxeb500hmi_init,
 MACHINE_END
Signature · 1 line
1.7.4.1
author
#26 lore raw

PATCH v2 5/10 ARM: nomadik: convert to MULTI_IRQ_HANDLER

In reply to Jamie Iles

Now that there is a generic IRQ handler for multiple VIC devices use it for nomadik to help building multi platform kernels.

Cc Alessandro Rubini <[email protected]>
Cc Linus Walleij <[email protected]>
Cc STEricsson <[email protected]>
---
 arch/arm/Kconfig                                 |    1 +
 arch/arm/mach-nomadik/board-nhk8815.c            |    2 +
 arch/arm/mach-nomadik/include/mach/entry-macro.S |   30 ----------------------
 3 files changed, 3 insertions(+), 30 deletions(-)
arch/arm/Kconfig +1 -0
index b7cab06..8d131a2 100644
@@ -859,6 +859,7 @@ config ARCH_NOMADIK
 	select CLKDEV_LOOKUP
 	select GENERIC_CLOCKEVENTS
 	select ARCH_REQUIRE_GPIOLIB
+	select MULTI_IRQ_HANDLER
 	help
 	  Support for the Nomadik platform by ST-Ericsson
 
arch/arm/mach-nomadik/board-nhk8815.c +2 -0
index 1399303..46d9dce 100644
@@ -21,6 +21,7 @@
 #include <linux/mtd/onenand.h>
 #include <linux/mtd/partitions.h>
 #include <linux/io.h>
+#include <asm/hardware/vic.h>
 #include <asm/sizes.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -279,6 +280,7 @@ MACHINE_START(NOMADIK, "NHK8815")
 	.boot_params	= 0x100,
 	.map_io		= cpu8815_map_io,
 	.init_irq	= cpu8815_init_irq,
+	.handle_irq	= vic_handle_irq,
 	.timer		= &nomadik_timer,
 	.init_machine	= nhk8815_platform_init,
 MACHINE_END
arch/arm/mach-nomadik/include/mach/entry-macro.S +0 -30
index 49f1aa3..98ea1c1 100644
@@ -6,38 +6,8 @@
  * warranty of any kind, whether express or implied.
  */
 
-#include <mach/hardware.h>
-#include <mach/irqs.h>
-
 	.macro	disable_fiq
 	.endm
 
-	.macro	get_irqnr_preamble, base, tmp
-	ldr	\base, =IO_ADDRESS(NOMADIK_IC_BASE)
-	.endm
-
 	.macro	arch_ret_to_user, tmp1, tmp2
 	.endm
-
-	.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
-
-	/* This stanza gets the irq mask from one of two status registers */
-	mov	\irqnr, #0
-	ldr	\irqstat, [\base, #VIC_REG_IRQSR0]	@ get masked status
-	cmp	\irqstat, #0
-	bne	1001f
-	add	\irqnr, \irqnr, #32
-	ldr	\irqstat, [\base, #VIC_REG_IRQSR1]	@ get masked status
-
-1001:	tst	\irqstat, #15
-	bne	1002f
-	add	\irqnr, \irqnr, #4
-	movs	\irqstat, \irqstat, lsr #4
-	bne	1001b
-1002:	tst	\irqstat, #1
-	bne	1003f
-	add	\irqnr, \irqnr, #1
-	movs	\irqstat, \irqstat, lsr #1
-	bne	1002b
-1003:	/* EQ will be set if no irqs pending */
-	.endm
Signature · 1 line
1.7.4.1
#27 lore raw

PATCH v2 5/10 ARM: nomadik: convert to MULTI_IRQ_HANDLER

Quoted 7 lines · Jamie Iles

- ? ? ? /* This stanza gets the irq mask from one of two status registers */
- ? ? ? mov ? ? \irqnr, #0
- ? ? ? ldr ? ? \irqstat, [\base, #VIC_REG_IRQSR0] ? ? ?@ get masked status
- ? ? ? cmp ? ? \irqstat, #0
- ? ? ? bne ? ? 1001f
- ? ? ? add ? ? \irqnr, \irqnr, #32
- ? ? ? ldr ? ? \irqstat, [\base, #VIC_REG_IRQSR1] ? ? ?@ get masked status

As you can see the Nomadik also has two daisy-chained VICs, just like the U300, so this also breaks.

Yours,
Linus Walleij

author
#28 lore raw

PATCH v2 6/10 ARM: s3c64xx: convert to MULTI_IRQ_HANDLER

In reply to Jamie Iles

Now that there is a generic IRQ handler for multiple VIC devices use it for s3c64xx to help building multi platform kernels.

---
 arch/arm/Kconfig                                 |    1 +
 arch/arm/mach-s3c64xx/include/mach/entry-macro.S |    7 ++++---
 arch/arm/mach-s3c64xx/mach-anw6410.c             |    2 ++
 arch/arm/mach-s3c64xx/mach-crag6410.c            |    2 ++
 arch/arm/mach-s3c64xx/mach-hmt.c                 |    2 ++
 arch/arm/mach-s3c64xx/mach-mini6410.c            |    2 ++
 arch/arm/mach-s3c64xx/mach-ncp.c                 |    2 ++
 arch/arm/mach-s3c64xx/mach-real6410.c            |    2 ++
 arch/arm/mach-s3c64xx/mach-smartq5.c             |    2 ++
 arch/arm/mach-s3c64xx/mach-smartq7.c             |    2 ++
 arch/arm/mach-s3c64xx/mach-smdk6400.c            |    2 ++
 arch/arm/mach-s3c64xx/mach-smdk6410.c            |    2 ++
 12 files changed, 25 insertions(+), 3 deletions(-)
arch/arm/Kconfig +1 -0
index 8d131a2..0b9a984 100644
@@ -734,6 +734,7 @@ config ARCH_S3C64XX
 	select SAMSUNG_GPIOLIB_4BIT
 	select HAVE_S3C2410_I2C if I2C
 	select HAVE_S3C2410_WATCHDOG if WATCHDOG
+	select MULTI_IRQ_HANDLER
 	help
 	  Samsung S3C64XX series based systems
 
arch/arm/mach-s3c64xx/include/mach/entry-macro.S +4 -3
index dd36260..dc2bc15 100644
@@ -12,7 +12,8 @@
  * warranty of any kind, whether express or implied.
 */
 
-#include <mach/map.h>
-#include <mach/irqs.h>
+		.macro  disable_fiq
+		.endm
 
-#include <asm/entry-macro-vic2.S>
+		.macro  arch_ret_to_user, tmp1, tmp2
+		.endm
arch/arm/mach-s3c64xx/mach-anw6410.c +2 -0
index cb88643..714a8cc 100644
@@ -30,6 +30,7 @@
 
 #include <video/platform_lcd.h>
 
+#include <asm/hardware/vic.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
@@ -236,6 +237,7 @@ MACHINE_START(ANW6410, "A&W6410")
 	.boot_params	= S3C64XX_PA_SDRAM + 0x100,
 
 	.init_irq	= s3c6410_init_irq,
+	.handle_irq	= vic_handle_irq,
 	.map_io		= anw6410_map_io,
 	.init_machine	= anw6410_machine_init,
 	.timer		= &s3c24xx_timer,
arch/arm/mach-s3c64xx/mach-crag6410.c +2 -0
index af0c2fe..ae74fe1 100644
@@ -37,6 +37,7 @@
 #include <linux/mfd/wm831x/irq.h>
 #include <linux/mfd/wm831x/gpio.h>
 
+#include <asm/hardware/vic.h>
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
 
@@ -768,6 +769,7 @@ MACHINE_START(WLF_CRAGG_6410, "Wolfson Cragganmore 6410")
 	/* Maintainer: Mark Brown <[email protected]> */
 	.boot_params	= S3C64XX_PA_SDRAM + 0x100,
 	.init_irq	= s3c6410_init_irq,
+	.handle_irq	= vic_handle_irq,
 	.map_io		= crag6410_map_io,
 	.init_machine	= crag6410_machine_init,
 	.timer		= &s3c24xx_timer,
arch/arm/mach-s3c64xx/mach-hmt.c +2 -0
index b3d93cc..6b60f50 100644
@@ -29,6 +29,7 @@
 #include <mach/hardware.h>
 #include <mach/map.h>
 
+#include <asm/hardware/vic.h>
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
@@ -267,6 +268,7 @@ MACHINE_START(HMT, "Airgoo-HMT")
 	/* Maintainer: Peter Korsgaard <[email protected]> */
 	.boot_params	= S3C64XX_PA_SDRAM + 0x100,
 	.init_irq	= s3c6410_init_irq,
+	.handle_irq	= vic_handle_irq,
 	.map_io		= hmt_map_io,
 	.init_machine	= hmt_machine_init,
 	.timer		= &s3c24xx_timer,
arch/arm/mach-s3c64xx/mach-mini6410.c +2 -0
index 527f49b..f23ff04 100644
@@ -24,6 +24,7 @@
 #include <linux/serial_core.h>
 #include <linux/types.h>
 
+#include <asm/hardware/vic.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -351,6 +352,7 @@ MACHINE_START(MINI6410, "MINI6410")
 	/* Maintainer: Darius Augulis <[email protected]> */
 	.boot_params	= S3C64XX_PA_SDRAM + 0x100,
 	.init_irq	= s3c6410_init_irq,
+	.handle_irq	= vic_handle_irq,
 	.map_io		= mini6410_map_io,
 	.init_machine	= mini6410_machine_init,
 	.timer		= &s3c24xx_timer,
arch/arm/mach-s3c64xx/mach-ncp.c +2 -0
index 01c6857..8190cd2 100644
@@ -25,6 +25,7 @@
 
 #include <video/platform_lcd.h>
 
+#include <asm/hardware/vic.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
@@ -99,6 +100,7 @@ MACHINE_START(NCP, "NCP")
 	/* Maintainer: Samsung Electronics */
 	.boot_params	= S3C64XX_PA_SDRAM + 0x100,
 	.init_irq	= s3c6410_init_irq,
+	.handle_irq	= vic_handle_irq,
 	.map_io		= ncp_map_io,
 	.init_machine	= ncp_machine_init,
 	.timer		= &s3c24xx_timer,
arch/arm/mach-s3c64xx/mach-real6410.c +2 -0
index 95b04b1..79bbf3c 100644
@@ -25,6 +25,7 @@
 #include <linux/serial_core.h>
 #include <linux/types.h>
 
+#include <asm/hardware/vic.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -332,6 +333,7 @@ MACHINE_START(REAL6410, "REAL6410")
 	.boot_params	= S3C64XX_PA_SDRAM + 0x100,
 
 	.init_irq	= s3c6410_init_irq,
+	.handle_irq	= vic_handle_irq,
 	.map_io		= real6410_map_io,
 	.init_machine	= real6410_machine_init,
 	.timer		= &s3c24xx_timer,
arch/arm/mach-s3c64xx/mach-smartq5.c +2 -0
index 342e8df..6ea050a 100644
@@ -17,6 +17,7 @@
 #include <linux/leds.h>
 #include <linux/platform_device.h>
 
+#include <asm/hardware/vic.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
@@ -148,6 +149,7 @@ MACHINE_START(SMARTQ5, "SmartQ 5")
 	/* Maintainer: Maurus Cuelenaere <mcuelenaere AT gmail DOT com> */
 	.boot_params	= S3C64XX_PA_SDRAM + 0x100,
 	.init_irq	= s3c6410_init_irq,
+	.handle_irq	= vic_handle_irq,
 	.map_io		= smartq_map_io,
 	.init_machine	= smartq5_machine_init,
 	.timer		= &s3c24xx_timer,
arch/arm/mach-s3c64xx/mach-smartq7.c +2 -0
index 5796397..bd3168c 100644
@@ -17,6 +17,7 @@
 #include <linux/leds.h>
 #include <linux/platform_device.h>
 
+#include <asm/hardware/vic.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
@@ -164,6 +165,7 @@ MACHINE_START(SMARTQ7, "SmartQ 7")
 	/* Maintainer: Maurus Cuelenaere <mcuelenaere AT gmail DOT com> */
 	.boot_params	= S3C64XX_PA_SDRAM + 0x100,
 	.init_irq	= s3c6410_init_irq,
+	.handle_irq	= vic_handle_irq,
 	.map_io		= smartq_map_io,
 	.init_machine	= smartq7_machine_init,
 	.timer		= &s3c24xx_timer,
arch/arm/mach-s3c64xx/mach-smdk6400.c +2 -0
index 3cca642..64560b2 100644
@@ -22,6 +22,7 @@
 
 #include <asm/mach-types.h>
 
+#include <asm/hardware/vic.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
@@ -88,6 +89,7 @@ MACHINE_START(SMDK6400, "SMDK6400")
 	.boot_params	= S3C64XX_PA_SDRAM + 0x100,
 
 	.init_irq	= s3c6400_init_irq,
+	.handle_irq	= vic_handle_irq,
 	.map_io		= smdk6400_map_io,
 	.init_machine	= smdk6400_machine_init,
 	.timer		= &s3c24xx_timer,
arch/arm/mach-s3c64xx/mach-smdk6410.c +2 -0
index ecbea92..47a835b 100644
@@ -43,6 +43,7 @@
 
 #include <video/platform_lcd.h>
 
+#include <asm/hardware/vic.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
@@ -745,6 +746,7 @@ MACHINE_START(SMDK6410, "SMDK6410")
 	.boot_params	= S3C64XX_PA_SDRAM + 0x100,
 
 	.init_irq	= s3c6410_init_irq,
+	.handle_irq	= vic_handle_irq,
 	.map_io		= smdk6410_map_io,
 	.init_machine	= smdk6410_machine_init,
 	.timer		= &s3c24xx_timer,
Signature · 1 line
1.7.4.1
author
#29 lore raw

PATCH v2 7/10 ARM: spear: convert to MULTI_IRQ_HANDLER

In reply to Jamie Iles

Now that there is a generic IRQ handler for multiple VIC devices use it for spear to help building multi platform kernels.

Cc Viresh Kumar <[email protected]>
Cc Rajeev Kumar <[email protected]>
---
 arch/arm/Kconfig                                  |    1 +
 arch/arm/mach-spear3xx/include/mach/entry-macro.S |   27 ---------------
 arch/arm/mach-spear3xx/spear300_evb.c             |    2 +
 arch/arm/mach-spear3xx/spear310_evb.c             |    2 +
 arch/arm/mach-spear3xx/spear320_evb.c             |    2 +
 arch/arm/mach-spear6xx/include/mach/entry-macro.S |   36 ---------------------
 arch/arm/mach-spear6xx/spear600_evb.c             |    2 +
 7 files changed, 9 insertions(+), 63 deletions(-)
arch/arm/Kconfig +1 -0
index 0b9a984..eb23c6e 100644
@@ -897,6 +897,7 @@ config PLAT_SPEAR
 	select CLKSRC_MMIO
 	select GENERIC_CLOCKEVENTS
 	select HAVE_CLK
+	select MULTI_IRQ_HANDLER
 	help
 	  Support for ST's SPEAr platform (SPEAr3xx, SPEAr6xx and SPEAr13xx).
 
arch/arm/mach-spear3xx/include/mach/entry-macro.S +0 -27
index 53da422..de3bb41 100644
@@ -11,35 +11,8 @@
  * warranty of any kind, whether express or implied.
  */
 
-#include <asm/hardware/vic.h>
-#include <mach/hardware.h>
-
 		.macro	disable_fiq
 		.endm
 
-		.macro	get_irqnr_preamble, base, tmp
-		.endm
-
 		.macro	arch_ret_to_user, tmp1, tmp2
 		.endm
-
-		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
-		ldr	\base, =VA_SPEAR3XX_ML1_VIC_BASE
-		ldr	\irqstat, [\base, #VIC_IRQ_STATUS]	@ get status
-		teq	\irqstat, #0
-		beq	1001f				@ this will set/reset
-							@ zero register
-		/*
-		 * Following code will find bit position of least significang
-		 * bit set in irqstat, using following equation
-		 * least significant bit set in n = (n & ~(n-1))
-		 */
-		sub	\tmp, \irqstat, #1		@ tmp = irqstat - 1
-		mvn	\tmp, \tmp			@ tmp = ~tmp
-		and	\irqstat, \irqstat, \tmp	@ irqstat &= tmp
-		/* Now, irqstat is = bit no. of 1st bit set in vic irq status */
-		clz	\tmp, \irqstat			@ tmp = leading zeros
-		rsb	\irqnr, \tmp, #0x1F		@ irqnr = 32 - tmp - 1
-
-1001:		/* EQ will be set if no irqs pending */
-		.endm
arch/arm/mach-spear3xx/spear300_evb.c +2 -0
index 69006f6..f013659 100644
@@ -11,6 +11,7 @@
  * warranty of any kind, whether express or implied.
  */
 
+#include <asm/hardware/vic.h>
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
 #include <mach/generic.h>
@@ -67,6 +68,7 @@ MACHINE_START(SPEAR300, "ST-SPEAR300-EVB")
 	.boot_params	=	0x00000100,
 	.map_io		=	spear3xx_map_io,
 	.init_irq	=	spear3xx_init_irq,
+	.handle_irq	=	vic_handle_irq,
 	.timer		=	&spear3xx_timer,
 	.init_machine	=	spear300_evb_init,
 MACHINE_END
arch/arm/mach-spear3xx/spear310_evb.c +2 -0
index c8684ce..4e1b4e3 100644
@@ -11,6 +11,7 @@
  * warranty of any kind, whether express or implied.
  */
 
+#include <asm/hardware/vic.h>
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
 #include <mach/generic.h>
@@ -73,6 +74,7 @@ MACHINE_START(SPEAR310, "ST-SPEAR310-EVB")
 	.boot_params	=	0x00000100,
 	.map_io		=	spear3xx_map_io,
 	.init_irq	=	spear3xx_init_irq,
+	.handle_irq	=	vic_handle_irq,
 	.timer		=	&spear3xx_timer,
 	.init_machine	=	spear310_evb_init,
 MACHINE_END
arch/arm/mach-spear3xx/spear320_evb.c +2 -0
index a12b353..197ed44 100644
@@ -11,6 +11,7 @@
  * warranty of any kind, whether express or implied.
  */
 
+#include <asm/hardware/vic.h>
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
 #include <mach/generic.h>
@@ -71,6 +72,7 @@ MACHINE_START(SPEAR320, "ST-SPEAR320-EVB")
 	.boot_params	=	0x00000100,
 	.map_io		=	spear3xx_map_io,
 	.init_irq	=	spear3xx_init_irq,
+	.handle_irq	=	vic_handle_irq,
 	.timer		=	&spear3xx_timer,
 	.init_machine	=	spear320_evb_init,
 MACHINE_END
arch/arm/mach-spear6xx/include/mach/entry-macro.S +0 -36
index 8a0b0ed..d490a91 100644
@@ -11,44 +11,8 @@
  * warranty of any kind, whether express or implied.
  */
 
-#include <asm/hardware/vic.h>
-#include <mach/hardware.h>
-
 		.macro	disable_fiq
 		.endm
 
-		.macro	get_irqnr_preamble, base, tmp
-		.endm
-
 		.macro	arch_ret_to_user, tmp1, tmp2
 		.endm
-
-		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
-		ldr	\base, =VA_SPEAR6XX_CPU_VIC_PRI_BASE
-		ldr	\irqstat, [\base, #VIC_IRQ_STATUS]	@ get status
-		mov	\irqnr, #0
-		teq	\irqstat, #0
-		bne	1001f
-		ldr	\base, =VA_SPEAR6XX_CPU_VIC_SEC_BASE
-		ldr	\irqstat, [\base, #VIC_IRQ_STATUS]	@ get status
-		teq	\irqstat, #0
-		beq	1002f				@ this will set/reset
-							@ zero register
-		mov	\irqnr, #32
-1001:
-		/*
-		 * Following code will find bit position of least significang
-		 * bit set in irqstat, using following equation
-		 * least significant bit set in n = (n & ~(n-1))
-		 */
-		sub	\tmp, \irqstat, #1		@ tmp = irqstat - 1
-		mvn	\tmp, \tmp			@ tmp = ~tmp
-		and	\irqstat, \irqstat, \tmp	@ irqstat &= tmp
-		/* Now, irqstat is = bit no. of 1st bit set in vic irq status */
-		clz	\tmp, \irqstat			@ tmp = leading zeros
-
-		rsb	\tmp, \tmp, #0x1F		@ tmp = 32 - tmp - 1
-		add	\irqnr, \irqnr, \tmp
-
-1002:		/* EQ will be set if no irqs pending */
-		.endm
arch/arm/mach-spear6xx/spear600_evb.c +2 -0
index f19cefe..ec986cb 100644
@@ -11,6 +11,7 @@
  * warranty of any kind, whether express or implied.
  */
 
+#include <asm/hardware/vic.h>
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
 #include <mach/generic.h>
@@ -46,6 +47,7 @@ MACHINE_START(SPEAR600, "ST-SPEAR600-EVB")
 	.boot_params	=	0x00000100,
 	.map_io		=	spear6xx_map_io,
 	.init_irq	=	spear6xx_init_irq,
+	.handle_irq	=	vic_handle_irq,
 	.timer		=	&spear6xx_timer,
 	.init_machine	=	spear600_evb_init,
 MACHINE_END
Signature · 1 line
1.7.4.1
author
#30 lore raw

PATCH v2 8/10 ARM: u300: convert to MULTI_IRQ_HANDLER

In reply to Jamie Iles

Now that there is a generic IRQ handler for multiple VIC devices use it for u300 to help building multi platform kernels.

Cc Linus Walleij <[email protected]>
---
 arch/arm/Kconfig                              |    1 +
 arch/arm/mach-u300/include/mach/entry-macro.S |   24 ------------------------
 arch/arm/mach-u300/u300.c                     |    2 ++
 3 files changed, 3 insertions(+), 24 deletions(-)
arch/arm/Kconfig +1 -0
index eb23c6e..6587e20 100644
@@ -838,6 +838,7 @@ config ARCH_U300
 	select CLKDEV_LOOKUP
 	select HAVE_MACH_CLKDEV
 	select GENERIC_GPIO
+	select MULTI_IRQ_HANDLER
 	help
 	  Support for ST-Ericsson U300 series mobile platforms.
 
arch/arm/mach-u300/include/mach/entry-macro.S +0 -24
index 20731ae..7181d6a 100644
@@ -8,33 +8,9 @@
  * Low-level IRQ helper macros for ST-Ericsson U300
  * Author: Linus Walleij <[email protected]>
  */
-#include <mach/hardware.h>
-#include <asm/hardware/vic.h>
 
 	.macro	disable_fiq
 	.endm
 
-	.macro  get_irqnr_preamble, base, tmp
-	.endm
-
 	.macro  arch_ret_to_user, tmp1, tmp2
 	.endm
-
-	.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
-	ldr	\base, = U300_AHB_PER_VIRT_BASE-U300_AHB_PER_PHYS_BASE+U300_INTCON0_BASE
-	ldr	\irqstat, [\base, #VIC_IRQ_STATUS] @ get masked status
-	mov	\irqnr, #0
-	teq	\irqstat, #0
-	bne	1002f
-1001:	ldr	\base, = U300_AHB_PER_VIRT_BASE-U300_AHB_PER_PHYS_BASE+U300_INTCON1_BASE
-	ldr	\irqstat, [\base, #VIC_IRQ_STATUS] @ get masked status
-	mov	\irqnr, #32
-	teq	\irqstat, #0
-	beq	1003f
-1002:	tst	\irqstat, #1
-	bne	1003f
-	add	\irqnr, \irqnr, #1
-	movs	\irqstat, \irqstat, lsr #1
-	bne	1002b
-1003:		/* EQ will be set if no irqs pending */
-	.endm
arch/arm/mach-u300/u300.c +2 -0
index 48b3b7f..6292920 100644
@@ -19,6 +19,7 @@
 #include <linux/io.h>
 #include <mach/hardware.h>
 #include <mach/platform.h>
+#include <asm/hardware/vic.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/memory.h>
@@ -65,6 +66,7 @@ MACHINE_START(U300, MACH_U300_STRING)
 	.map_io		= u300_map_io,
 	.reserve	= u300_reserve,
 	.init_irq	= u300_init_irq,
+	.handle_irq	= vic_handle_irq,
 	.timer		= &u300_timer,
 	.init_machine	= u300_init_machine,
 MACHINE_END
Signature · 1 line
1.7.4.1
#31 lore raw

PATCH v2 8/10 ARM: u300: convert to MULTI_IRQ_HANDLER

Hold your horses:

Quoted 30 lines · Jamie Iles
arch/arm/mach-u300/include/mach/entry-macro.S +0 -0
index 20731ae..7181d6a 100644
@@ -8,33 +8,9 @@

?* Low-level IRQ helper macros for ST-Ericsson U300 ?* Author: Linus Walleij <[email protected]> ?*/

arch/arm/mach-u300/include/mach/entry-macro.S +0 -2
-#include <mach/hardware.h>
-#include <asm/hardware/vic.h>

? ? ? ?.macro ?disable_fiq
? ? ? ?.endm

- ? ? ? .macro ?get_irqnr_preamble, base, tmp
- ? ? ? .endm
-
? ? ? ?.macro ?arch_ret_to_user, tmp1, tmp2
? ? ? ?.endm
-
- ? ? ? .macro ?get_irqnr_and_base, irqnr, irqstat, base, tmp
- ? ? ? ldr ? ? \base, = U300_AHB_PER_VIRT_BASE-U300_AHB_PER_PHYS_BASE+U300_INTCON0_BASE
- ? ? ? ldr ? ? \irqstat, [\base, #VIC_IRQ_STATUS] @ get masked status
- ? ? ? mov ? ? \irqnr, #0
- ? ? ? teq ? ? \irqstat, #0
- ? ? ? bne ? ? 1002f
-1001: ?ldr ? ? \base, = U300_AHB_PER_VIRT_BASE-U300_AHB_PER_PHYS_BASE+U300_INTCON1_BASE
- ? ? ? ldr ? ? \irqstat, [\base, #VIC_IRQ_STATUS] @ get masked status
- ? ? ? mov ? ? \irqnr, #32
- ? ? ? teq ? ? \irqstat, #0

Quoted 8 lines

- ? ? ? beq ? ? 1003f
-1002: ?tst ? ? \irqstat, #1
- ? ? ? bne ? ? 1003f
- ? ? ? add ? ? \irqnr, \irqnr, #1
- ? ? ? movs ? ?\irqstat, \irqstat, lsr #1
- ? ? ? bne ? ? 1002b
-1003: ? ? ? ? ?/* EQ will be set if no irqs pending */
- ? ? ? .endm

When I inspect patch 2 in this series I get the feeling that it assumes that there is one and only one VIC bank with 32 interrupts involved. This is not the case in the U300, it has 64 possible IRQ sources by OR:in the output IRQ signal from two VIC:s and feeding the resulting IRQ line into the CPU.

So in the code above we first check the 32 bits at the first VIC instance, and if that is zero we go on to check the other 32 bits.

vic_single_handle_irq() needs to be modified to handle several ranges or atleast two.

Note that in mach-u300/core.c we initialize each VIC like this:
vic_init((void __iomem *) U300_INTCON0_VBASE, 0, mask[0], mask[0]); vic_init((void __iomem *) U300_INTCON1_VBASE, 32, mask[1], mask[1]);

So I think the easiest may be to let vic_init() add registered VIC ranges to a list or array, and increas some num_vics variable to that vic_single_handle_irq() can traverse both ranges in order.

Yours,
Linus Walleij

author
#32 lore raw

PATCH v2 8/10 ARM: u300: convert to MULTI_IRQ_HANDLER

Hi Linus,

Quoted 40 lines · Linus Walleij

Hold your horses:

Quoted 36 lines · Jamie Iles
arch/arm/mach-u300/include/mach/entry-macro.S +0 -0
index 20731ae..7181d6a 100644
@@ -8,33 +8,9 @@

?* Low-level IRQ helper macros for ST-Ericsson U300 ?* Author: Linus Walleij <[email protected]> ?*/

arch/arm/mach-u300/include/mach/entry-macro.S +0 -2
-#include <mach/hardware.h>
-#include <asm/hardware/vic.h>

? ? ? ?.macro ?disable_fiq
? ? ? ?.endm

- ? ? ? .macro ?get_irqnr_preamble, base, tmp
- ? ? ? .endm
-
? ? ? ?.macro ?arch_ret_to_user, tmp1, tmp2
? ? ? ?.endm
-
- ? ? ? .macro ?get_irqnr_and_base, irqnr, irqstat, base, tmp
- ? ? ? ldr ? ? \base, = U300_AHB_PER_VIRT_BASE-U300_AHB_PER_PHYS_BASE+U300_INTCON0_BASE
- ? ? ? ldr ? ? \irqstat, [\base, #VIC_IRQ_STATUS] @ get masked status
- ? ? ? mov ? ? \irqnr, #0
- ? ? ? teq ? ? \irqstat, #0
- ? ? ? bne ? ? 1002f
-1001: ?ldr ? ? \base, = U300_AHB_PER_VIRT_BASE-U300_AHB_PER_PHYS_BASE+U300_INTCON1_BASE
- ? ? ? ldr ? ? \irqstat, [\base, #VIC_IRQ_STATUS] @ get masked status
- ? ? ? mov ? ? \irqnr, #32
- ? ? ? teq ? ? \irqstat, #0
- ? ? ? beq ? ? 1003f
-1002: ?tst ? ? \irqstat, #1
- ? ? ? bne ? ? 1003f
- ? ? ? add ? ? \irqnr, \irqnr, #1
- ? ? ? movs ? ?\irqstat, \irqstat, lsr #1
- ? ? ? bne ? ? 1002b

Quoted 8 lines
Quoted 2 lines

-1003: ? ? ? ? ?/* EQ will be set if no irqs pending */
- ? ? ? .endm

When I inspect patch 2 in this series I get the feeling that it assumes that there is one and only one VIC bank with 32 interrupts involved. This is not the case in the U300, it has 64 possible IRQ sources by OR:in the output IRQ signal from two VIC:s and feeding the resulting IRQ line into the CPU.

No, it will handle more than one vic, and it will check them in the order the vic_init() is called. I've tested this on picoxcell that has 2 vic's in the same configuration as this.

Quoted 5 lines

So in the code above we first check the 32 bits at the first VIC instance, and if that is zero we go on to check the other 32 bits.

vic_single_handle_irq() needs to be modified to handle several ranges or atleast two.

The platform IRQ handler is actually vic_handle_irq() that internally calls vic_single_handle_irq() for each registered vic (in the order of registration).

Quoted 8 lines

Note that in mach-u300/core.c we initialize each VIC like this:
vic_init((void __iomem *) U300_INTCON0_VBASE, 0, mask[0], mask[0]); vic_init((void __iomem *) U300_INTCON1_VBASE, 32, mask[1], mask[1]);

So I think the easiest may be to let vic_init() add registered VIC ranges to a list or array, and increas some num_vics variable to that vic_single_handle_irq() can traverse both ranges in order.

Jamie

#33 lore raw

PATCH v2 8/10 ARM: u300: convert to MULTI_IRQ_HANDLER

Quoted 6 lines · Jamie Iles
Quoted 2 lines

vic_single_handle_irq() needs to be modified to handle several ranges or atleast two.

The platform IRQ handler is actually vic_handle_irq() that internally calls vic_single_handle_irq() for each registered vic (in the order of registration).

Ah I get it I'm dead wrong as usual :-)

I tried to apply them to test but Iget into dependency trouble with the referenced required patches, do you have some handy git branch with all stuff applied in order that I can pull in and test off?

Yours,
Linus Walleij

author
#34 lore raw

PATCH v2 8/10 ARM: u300: convert to MULTI_IRQ_HANDLER

Quoted 9 lines · Linus Walleij
Quoted 6 lines · Jamie Iles
Quoted 2 lines

vic_single_handle_irq() needs to be modified to handle several ranges or atleast two.

The platform IRQ handler is actually vic_handle_irq() that internally calls vic_single_handle_irq() for each registered vic (in the order of registration).

Quoted 6 lines

Ah I get it I'm dead wrong as usual :-)

I tried to apply them to test but Iget into dependency trouble with the referenced required patches, do you have some handy git branch with all stuff applied in order that I can pull in and test off?

Sure,

	git://github.com/jamieiles/linux-2.6-ji.git vic-dt

has all of the dependencies in there too. Thanks for taking a look at the patches Linus!

Jamie

author
#35 lore raw

PATCH v2 9/10 ARM: versatile: convert to MULTI_IRQ_HANDLER

In reply to Jamie Iles

Now that there is a generic IRQ handler for multiple VIC devices use it for versatile to help building multi platform kernels.

---
 arch/arm/Kconfig                                   |    1 +
 arch/arm/mach-versatile/include/mach/entry-macro.S |   30 --------------------
 arch/arm/mach-versatile/versatile_ab.c             |    2 +
 arch/arm/mach-versatile/versatile_dt.c             |    2 +
 arch/arm/mach-versatile/versatile_pb.c             |    2 +
 5 files changed, 7 insertions(+), 30 deletions(-)
arch/arm/Kconfig +1 -0
index 6587e20..5e6c744 100644
@@ -277,6 +277,7 @@ config ARCH_VERSATILE
 	select PLAT_VERSATILE_CLCD
 	select PLAT_VERSATILE_FPGA_IRQ
 	select ARM_TIMER_SP804
+	select MULTI_IRQ_HANDLER
 	help
 	  This enables support for ARM Ltd Versatile board.
 
arch/arm/mach-versatile/include/mach/entry-macro.S +0 -30
index e6f7c16..b6f0dbf 100644
@@ -7,39 +7,9 @@
  * License version 2. This program is licensed "as is" without any
  * warranty of any kind, whether express or implied.
  */
-#include <mach/hardware.h>
-#include <mach/platform.h>
-#include <asm/hardware/vic.h>
 
 		.macro	disable_fiq
 		.endm
 
-		.macro  get_irqnr_preamble, base, tmp
-		ldr	\base, =IO_ADDRESS(VERSATILE_VIC_BASE)
-		.endm
-
 		.macro  arch_ret_to_user, tmp1, tmp2
 		.endm
-
-		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
-		ldr	\irqstat, [\base, #VIC_IRQ_STATUS]	@ get masked status
-		mov	\irqnr, #0
-		teq	\irqstat, #0
-		beq	1003f
-
-1001:		tst	\irqstat, #15
-		bne	1002f
-		add	\irqnr, \irqnr, #4
-		movs	\irqstat, \irqstat, lsr #4
-		bne	1001b
-1002:		tst	\irqstat, #1
-		bne	1003f
-		add	\irqnr, \irqnr, #1
-		movs	\irqstat, \irqstat, lsr #1
-		bne	1002b
-1003:		/* EQ will be set if no irqs pending */
-
-@		clz	\irqnr, \irqstat
- at 1003:		/* EQ will be set if we reach MAXIRQNUM */
-		.endm
-
arch/arm/mach-versatile/versatile_ab.c +2 -0
index f8ae64b..29b1f34 100644
@@ -27,6 +27,7 @@
 
 #include <mach/hardware.h>
 #include <asm/irq.h>
+#include <asm/hardware/vic.h>
 #include <asm/mach-types.h>
 
 #include <asm/mach/arch.h>
@@ -39,6 +40,7 @@ MACHINE_START(VERSATILE_AB, "ARM-Versatile AB")
 	.map_io		= versatile_map_io,
 	.init_early	= versatile_init_early,
 	.init_irq	= versatile_init_irq,
+	.handle_irq	= vic_handle_irq,
 	.timer		= &versatile_timer,
 	.init_machine	= versatile_init,
 MACHINE_END
arch/arm/mach-versatile/versatile_dt.c +2 -0
index 54e037c..f4d1e0f 100644
@@ -24,6 +24,7 @@
 #include <linux/init.h>
 #include <linux/of_irq.h>
 #include <linux/of_platform.h>
+#include <asm/hardware/vic.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
@@ -45,6 +46,7 @@ DT_MACHINE_START(VERSATILE_PB, "ARM-Versatile (Device Tree Support)")
 	.map_io		= versatile_map_io,
 	.init_early	= versatile_init_early,
 	.init_irq	= versatile_init_irq,
+	.handle_irq	= vic_handle_irq,
 	.timer		= &versatile_timer,
 	.init_machine	= versatile_dt_init,
 	.dt_compat	= versatile_dt_match,
arch/arm/mach-versatile/versatile_pb.c +2 -0
index 37c23df..229d0a3b 100644
@@ -28,6 +28,7 @@
 #include <linux/io.h>
 
 #include <mach/hardware.h>
+#include <asm/hardware/vic.h>
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
@@ -107,6 +108,7 @@ MACHINE_START(VERSATILE_PB, "ARM-Versatile PB")
 	.map_io		= versatile_map_io,
 	.init_early	= versatile_init_early,
 	.init_irq	= versatile_init_irq,
+	.handle_irq	= vic_handle_irq,
 	.timer		= &versatile_timer,
 	.init_machine	= versatile_pb_init,
 MACHINE_END
Signature · 1 line
1.7.4.1
author
#36 lore raw

PATCH v2 10/10 ARM: samsung: convert to MULTI_IRQ_HANDLER

In reply to Jamie Iles

Now that there is a generic IRQ handler for multiple VIC devices use it for samsung to help building multi platform kernels.

---
 arch/arm/Kconfig                                 |    3 ++
 arch/arm/mach-s5p64x0/include/mach/entry-macro.S |    7 ++--
 arch/arm/mach-s5p64x0/mach-smdk6440.c            |    2 +
 arch/arm/mach-s5p64x0/mach-smdk6450.c            |    2 +
 arch/arm/mach-s5pc100/include/mach/entry-macro.S |   25 ---------------
 arch/arm/mach-s5pc100/mach-smdkc100.c            |    2 +
 arch/arm/mach-s5pv210/include/mach/entry-macro.S |   37 ----------------------
 arch/arm/mach-s5pv210/mach-aquila.c              |    2 +
 arch/arm/mach-s5pv210/mach-goni.c                |    2 +
 arch/arm/mach-s5pv210/mach-smdkc110.c            |    2 +
 arch/arm/mach-s5pv210/mach-smdkv210.c            |    2 +
 arch/arm/mach-s5pv210/mach-torbreck.c            |    2 +
 12 files changed, 23 insertions(+), 65 deletions(-)
arch/arm/Kconfig +3 -0
index 5e6c744..5d9b70f 100644
@@ -751,6 +751,7 @@ config ARCH_S5P64X0
 	select HAVE_SCHED_CLOCK
 	select HAVE_S3C2410_I2C if I2C
 	select HAVE_S3C_RTC if RTC_CLASS
+	select MULTI_IRQ_HANDLER
 	help
 	  Samsung S5P64X0 CPU based systems, such as the Samsung SMDK6440,
 	  SMDK6450.
@@ -766,6 +767,7 @@ config ARCH_S5PC100
 	select HAVE_S3C2410_I2C if I2C
 	select HAVE_S3C_RTC if RTC_CLASS
 	select HAVE_S3C2410_WATCHDOG if WATCHDOG
+	select MULTI_IRQ_HANDLER
 	help
 	  Samsung S5PC100 series based systems
 
@@ -785,6 +787,7 @@ config ARCH_S5PV210
 	select HAVE_S3C2410_I2C if I2C
 	select HAVE_S3C_RTC if RTC_CLASS
 	select HAVE_S3C2410_WATCHDOG if WATCHDOG
+	select MULTI_IRQ_HANDLER
 	help
 	  Samsung S5PV210/S5PC110 series based systems
 
arch/arm/mach-s5p64x0/include/mach/entry-macro.S +4 -3
index 10b62b4..fbb246d 100644
@@ -10,7 +10,8 @@
  * published by the Free Software Foundation.
 */
 
-#include <mach/map.h>
-#include <plat/irqs.h>
+		.macro  disable_fiq
+		.endm
 
-#include <asm/entry-macro-vic2.S>
+		.macro  arch_ret_to_user, tmp1, tmp2
+		.endm
arch/arm/mach-s5p64x0/mach-smdk6440.c +2 -0
index 346f8df..5d482c3 100644
@@ -24,6 +24,7 @@
 #include <linux/gpio.h>
 #include <linux/pwm_backlight.h>
 
+#include <asm/hardware/vic.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/irq.h>
@@ -174,6 +175,7 @@ MACHINE_START(SMDK6440, "SMDK6440")
 	.boot_params	= S5P64X0_PA_SDRAM + 0x100,
 
 	.init_irq	= s5p6440_init_irq,
+	.handle_irq	= vic_handle_irq,
 	.map_io		= smdk6440_map_io,
 	.init_machine	= smdk6440_machine_init,
 	.timer		= &s5p_timer,
arch/arm/mach-s5p64x0/mach-smdk6450.c +2 -0
index 33f2adf..805f2a9 100644
@@ -24,6 +24,7 @@
 #include <linux/gpio.h>
 #include <linux/pwm_backlight.h>
 
+#include <asm/hardware/vic.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/irq.h>
@@ -193,6 +194,7 @@ MACHINE_START(SMDK6450, "SMDK6450")
 	.boot_params	= S5P64X0_PA_SDRAM + 0x100,
 
 	.init_irq	= s5p6450_init_irq,
+	.handle_irq	= vic_handle_irq,
 	.map_io		= smdk6450_map_io,
 	.init_machine	= smdk6450_machine_init,
 	.timer		= &s5p_timer,
arch/arm/mach-s5pc100/include/mach/entry-macro.S +0 -25
index ba76af0..b8c242e 100644
@@ -12,39 +12,14 @@
  * warranty of any kind, whether express or implied.
 */
 
-#include <asm/hardware/vic.h>
-#include <mach/map.h>
-#include <plat/irqs.h>
-
 	.macro	disable_fiq
 	.endm
 
 	.macro	get_irqnr_preamble, base, tmp
-	ldr	\base, =VA_VIC0
 	.endm
 
 	.macro	arch_ret_to_user, tmp1, tmp2
 	.endm
 
 	.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
-
-	@ check the vic0
-	mov	\irqnr, # S5P_IRQ_OFFSET + 31
-	ldr	\irqstat, [ \base, # VIC_IRQ_STATUS ]
-	teq	\irqstat, #0
-
-	@ otherwise try vic1
-	addeq	\tmp, \base, #(VA_VIC1 - VA_VIC0)
-	addeq	\irqnr, \irqnr, #32
-	ldreq	\irqstat, [ \tmp, # VIC_IRQ_STATUS ]
-	teqeq	\irqstat, #0
-
-	@ otherwise try vic2
-	addeq	\tmp, \base, #(VA_VIC2 - VA_VIC0)
-	addeq	\irqnr, \irqnr, #32
-	ldreq	\irqstat, [ \tmp, # VIC_IRQ_STATUS ]
-	teqeq	\irqstat, #0
-
-	clzne	\irqstat, \irqstat
-	subne	\irqnr, \irqnr, \irqstat
 	.endm
arch/arm/mach-s5pc100/mach-smdkc100.c +2 -0
index 227d890..49c0b51 100644
@@ -25,6 +25,7 @@
 #include <linux/input.h>
 #include <linux/pwm_backlight.h>
 
+#include <asm/hardware/vic.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
@@ -256,6 +257,7 @@ MACHINE_START(SMDKC100, "SMDKC100")
 	/* Maintainer: Byungho Min <[email protected]> */
 	.boot_params	= S5P_PA_SDRAM + 0x100,
 	.init_irq	= s5pc100_init_irq,
+	.handle_irq	= vic_handle_irq,
 	.map_io		= smdkc100_map_io,
 	.init_machine	= smdkc100_machine_init,
 	.timer		= &s3c24xx_timer,
arch/arm/mach-s5pv210/include/mach/entry-macro.S +0 -37
index 3aa41ac..bebca1b 100644
@@ -10,45 +10,8 @@
  * published by the Free Software Foundation.
 */
 
-#include <asm/hardware/vic.h>
-#include <mach/map.h>
-#include <plat/irqs.h>
-
 	.macro	disable_fiq
 	.endm
 
-	.macro	get_irqnr_preamble, base, tmp
-	ldr	\base, =VA_VIC0
-	.endm
-
 	.macro	arch_ret_to_user, tmp1, tmp2
 	.endm
-
-	.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
-
-	@ check the vic0
-	mov	\irqnr, # S5P_IRQ_OFFSET + 31
-	ldr	\irqstat, [ \base, # VIC_IRQ_STATUS ]
-	teq	\irqstat, #0
-
-	@ otherwise try vic1
-	addeq	\tmp, \base, #(VA_VIC1 - VA_VIC0)
-	addeq	\irqnr, \irqnr, #32
-	ldreq	\irqstat, [ \tmp, # VIC_IRQ_STATUS ]
-	teqeq	\irqstat, #0
-
-	@ otherwise try vic2
-	addeq	\tmp, \base, #(VA_VIC2 - VA_VIC0)
-	addeq	\irqnr, \irqnr, #32
-	ldreq	\irqstat, [ \tmp, # VIC_IRQ_STATUS ]
-	teqeq	\irqstat, #0
-
-	@ otherwise try vic3
-	addeq	\tmp, \base, #(VA_VIC3 - VA_VIC0)
-	addeq	\irqnr, \irqnr, #32
-	ldreq	\irqstat, [ \tmp, # VIC_IRQ_STATUS ]
-	teqeq	\irqstat, #0
-
-	clzne	\irqstat, \irqstat
-	subne	\irqnr, \irqnr, \irqstat
-	.endm
arch/arm/mach-s5pv210/mach-aquila.c +2 -0
index 509627f..858aa0f 100644
@@ -22,6 +22,7 @@
 #include <linux/input.h>
 #include <linux/gpio.h>
 
+#include <asm/hardware/vic.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/setup.h>
@@ -680,6 +681,7 @@ MACHINE_START(AQUILA, "Aquila")
 	   Kyungmin Park <[email protected]> */
 	.boot_params	= S5P_PA_SDRAM + 0x100,
 	.init_irq	= s5pv210_init_irq,
+	.handle_irq	= vic_handle_irq,
 	.map_io		= aquila_map_io,
 	.init_machine	= aquila_machine_init,
 	.timer		= &s5p_timer,
arch/arm/mach-s5pv210/mach-goni.c +2 -0
index 85c2d51..cb1277b 100644
@@ -27,6 +27,7 @@
 #include <linux/gpio.h>
 #include <linux/interrupt.h>
 
+#include <asm/hardware/vic.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/setup.h>
@@ -899,6 +900,7 @@ MACHINE_START(GONI, "GONI")
 	/* Maintainers: Kyungmin Park <[email protected]> */
 	.boot_params	= S5P_PA_SDRAM + 0x100,
 	.init_irq	= s5pv210_init_irq,
+	.handle_irq	= vic_handle_irq,
 	.map_io		= goni_map_io,
 	.init_machine	= goni_machine_init,
 	.timer		= &s5p_timer,
arch/arm/mach-s5pv210/mach-smdkc110.c +2 -0
index 6c412c8..f1f7f9a 100644
@@ -15,6 +15,7 @@
 #include <linux/i2c.h>
 #include <linux/sysdev.h>
 
+#include <asm/hardware/vic.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/setup.h>
@@ -138,6 +139,7 @@ MACHINE_START(SMDKC110, "SMDKC110")
 	/* Maintainer: Kukjin Kim <[email protected]> */
 	.boot_params	= S5P_PA_SDRAM + 0x100,
 	.init_irq	= s5pv210_init_irq,
+	.handle_irq	= vic_handle_irq,
 	.map_io		= smdkc110_map_io,
 	.init_machine	= smdkc110_machine_init,
 	.timer		= &s5p_timer,
arch/arm/mach-s5pv210/mach-smdkv210.c +2 -0
index 5e011fc..3d0211f 100644
@@ -20,6 +20,7 @@
 #include <linux/delay.h>
 #include <linux/pwm_backlight.h>
 
+#include <asm/hardware/vic.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/setup.h>
@@ -321,6 +322,7 @@ MACHINE_START(SMDKV210, "SMDKV210")
 	/* Maintainer: Kukjin Kim <[email protected]> */
 	.boot_params	= S5P_PA_SDRAM + 0x100,
 	.init_irq	= s5pv210_init_irq,
+	.handle_irq	= vic_handle_irq,
 	.map_io		= smdkv210_map_io,
 	.init_machine	= smdkv210_machine_init,
 	.timer		= &s5p_timer,
arch/arm/mach-s5pv210/mach-torbreck.c +2 -0
index 925fc0d..53623e8 100644
@@ -14,6 +14,7 @@
 #include <linux/init.h>
 #include <linux/serial_core.h>
 
+#include <asm/hardware/vic.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/setup.h>
@@ -127,6 +128,7 @@ MACHINE_START(TORBRECK, "TORBRECK")
 	/* Maintainer: Hyunchul Ko <[email protected]> */
 	.boot_params	= S5P_PA_SDRAM + 0x100,
 	.init_irq	= s5pv210_init_irq,
+	.handle_irq	= vic_handle_irq,
 	.map_io		= torbreck_map_io,
 	.init_machine	= torbreck_machine_init,
 	.timer		= &s5p_timer,
Signature · 1 line
1.7.4.1