All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/10] ARM: S3C24XX: rework irq handling for a later dt usage
@ 2012-11-18  0:51 ` Heiko Stübner
  0 siblings, 0 replies; 24+ messages in thread
From: Heiko Stübner @ 2012-11-18  0:51 UTC (permalink / raw)
  To: Kukjin Kim
  Cc: Ben Dooks, linux-arm-kernel, linux-samsung-soc, Heiko Stübner

All S3C24XX arches share the same interrupt registers and basic handling
principles but the individual interrupts differ quite a lot between all
the arches.

This series therefore tries to unify this a bit by abstracting the irq
handling and enabling the arches to simply provide a structure describing
its individual interrupts.

With this declarative approach it should also be (hopefully) easy to
move this to devicetree later.

For the initial transformation (in patch 1) I gave up on trying to do
this in individual steps, so the patch might be a bit bumpy to read,
but the new irq code does provide the exactly same interrupts and
handlers as the old code. This also means that the unconverted arches
shouldn't feel any difference at all.

I've only included the s3c2416 and s3c2443 interrupts for now, as the
s3c2416 is my main development platform and the s3c2443 is so very
similar. But the other arches use the same mechanics so conversion
should be quite easy later.

As it seems to be the policy for drivers/irqchip that drivers there
should not contain platform-hooks or pollute the namespace with custom
init functons, the irq code stays in plat-s3c24xx for now.

Heiko Stuebner (10):
  ARM: S3C24XX: transform irq handling into a declarative form
  ARM: S3C24XX: move irq-pm code into main irq file
  ARM: S3C24XX: cleanup irq-pm integration
  ARM: S3C24XX: move s3c2416 irq init to common irq code
  ARM: S3C24XX: modify s3c2416 irq init to initialize all irqs
  ARM: S3C24XX: assimilate s3c2416 subirqs into new structure
  ARM: S3C24XX: assimilate second s3c2416 interrupt into new structure
  ARM: S3C24XX: move s3c2443 irq code to irq.c
  ARM: S3C24XX: modify s3c2443 irq init to initialize all irqs
  ARM: S3C24XX: assimilate s3c2443 subirqs into new structure

 arch/arm/mach-s3c24xx/Makefile               |    6 +-
 arch/arm/mach-s3c24xx/common.h               |    2 +
 arch/arm/mach-s3c24xx/irq-pm.c               |   95 ---
 arch/arm/mach-s3c24xx/irq-s3c2416.c          |  348 --------
 arch/arm/mach-s3c24xx/irq-s3c2443.c          |  281 -------
 arch/arm/mach-s3c24xx/mach-smdk2416.c        |    2 +-
 arch/arm/mach-s3c24xx/mach-smdk2443.c        |    2 +-
 arch/arm/mach-s3c24xx/s3c2410.c              |    4 +-
 arch/arm/mach-s3c24xx/s3c2412.c              |    4 +-
 arch/arm/mach-s3c24xx/s3c2416.c              |    4 +-
 arch/arm/mach-s3c24xx/s3c2440.c              |    4 +-
 arch/arm/mach-s3c24xx/s3c2442.c              |    4 +-
 arch/arm/plat-s3c24xx/Kconfig                |    1 +
 arch/arm/plat-s3c24xx/irq.c                  | 1140 ++++++++++++++++----------
 arch/arm/plat-samsung/include/plat/pm.h      |    6 -
 arch/arm/plat-samsung/include/plat/s3c2416.h |    1 +
 arch/arm/plat-samsung/include/plat/s3c2443.h |    2 +
 17 files changed, 737 insertions(+), 1169 deletions(-)
 delete mode 100644 arch/arm/mach-s3c24xx/irq-pm.c
 delete mode 100644 arch/arm/mach-s3c24xx/irq-s3c2416.c
 delete mode 100644 arch/arm/mach-s3c24xx/irq-s3c2443.c

-- 
1.7.2.3

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH 00/10] ARM: S3C24XX: rework irq handling for a later dt usage
@ 2012-11-18  0:51 ` Heiko Stübner
  0 siblings, 0 replies; 24+ messages in thread
From: Heiko Stübner @ 2012-11-18  0:51 UTC (permalink / raw)
  To: linux-arm-kernel

All S3C24XX arches share the same interrupt registers and basic handling
principles but the individual interrupts differ quite a lot between all
the arches.

This series therefore tries to unify this a bit by abstracting the irq
handling and enabling the arches to simply provide a structure describing
its individual interrupts.

With this declarative approach it should also be (hopefully) easy to
move this to devicetree later.

For the initial transformation (in patch 1) I gave up on trying to do
this in individual steps, so the patch might be a bit bumpy to read,
but the new irq code does provide the exactly same interrupts and
handlers as the old code. This also means that the unconverted arches
shouldn't feel any difference at all.

I've only included the s3c2416 and s3c2443 interrupts for now, as the
s3c2416 is my main development platform and the s3c2443 is so very
similar. But the other arches use the same mechanics so conversion
should be quite easy later.

As it seems to be the policy for drivers/irqchip that drivers there
should not contain platform-hooks or pollute the namespace with custom
init functons, the irq code stays in plat-s3c24xx for now.

Heiko Stuebner (10):
  ARM: S3C24XX: transform irq handling into a declarative form
  ARM: S3C24XX: move irq-pm code into main irq file
  ARM: S3C24XX: cleanup irq-pm integration
  ARM: S3C24XX: move s3c2416 irq init to common irq code
  ARM: S3C24XX: modify s3c2416 irq init to initialize all irqs
  ARM: S3C24XX: assimilate s3c2416 subirqs into new structure
  ARM: S3C24XX: assimilate second s3c2416 interrupt into new structure
  ARM: S3C24XX: move s3c2443 irq code to irq.c
  ARM: S3C24XX: modify s3c2443 irq init to initialize all irqs
  ARM: S3C24XX: assimilate s3c2443 subirqs into new structure

 arch/arm/mach-s3c24xx/Makefile               |    6 +-
 arch/arm/mach-s3c24xx/common.h               |    2 +
 arch/arm/mach-s3c24xx/irq-pm.c               |   95 ---
 arch/arm/mach-s3c24xx/irq-s3c2416.c          |  348 --------
 arch/arm/mach-s3c24xx/irq-s3c2443.c          |  281 -------
 arch/arm/mach-s3c24xx/mach-smdk2416.c        |    2 +-
 arch/arm/mach-s3c24xx/mach-smdk2443.c        |    2 +-
 arch/arm/mach-s3c24xx/s3c2410.c              |    4 +-
 arch/arm/mach-s3c24xx/s3c2412.c              |    4 +-
 arch/arm/mach-s3c24xx/s3c2416.c              |    4 +-
 arch/arm/mach-s3c24xx/s3c2440.c              |    4 +-
 arch/arm/mach-s3c24xx/s3c2442.c              |    4 +-
 arch/arm/plat-s3c24xx/Kconfig                |    1 +
 arch/arm/plat-s3c24xx/irq.c                  | 1140 ++++++++++++++++----------
 arch/arm/plat-samsung/include/plat/pm.h      |    6 -
 arch/arm/plat-samsung/include/plat/s3c2416.h |    1 +
 arch/arm/plat-samsung/include/plat/s3c2443.h |    2 +
 17 files changed, 737 insertions(+), 1169 deletions(-)
 delete mode 100644 arch/arm/mach-s3c24xx/irq-pm.c
 delete mode 100644 arch/arm/mach-s3c24xx/irq-s3c2416.c
 delete mode 100644 arch/arm/mach-s3c24xx/irq-s3c2443.c

-- 
1.7.2.3

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH 01/10] ARM: S3C24XX: transform irq handling into a declarative form
  2012-11-18  0:51 ` Heiko Stübner
@ 2012-11-18  0:52   ` Heiko Stübner
  -1 siblings, 0 replies; 24+ messages in thread
From: Heiko Stübner @ 2012-11-18  0:52 UTC (permalink / raw)
  To: Kukjin Kim; +Cc: Ben Dooks, linux-arm-kernel, linux-samsung-soc

The irqs available on the machine and even the bit settings in the
irq registers differ a lot through all the s3c24xx subarchitectures.
This results in each subarch having its own irq init which adds its
specific irqs to the base ones created in plat-s3c24xx/irq.c.

This of course makes a future move to devicetree hard to implement.

Therefore this patch transforms the base irq handling to a declarative
style, where the irq types as well as its parent/child relationship
gets read from a predefined datastructure, which later on can hopefully
be easily represented in devicetree too.

It should also be easy to include the subarch specific irqs here
in later patches, reducing code size and duplication.

It should not affect anything outside of the file, as the original
irq numbers and their handling are preserved (hopefully) correctly.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
 arch/arm/plat-s3c24xx/Kconfig |    1 +
 arch/arm/plat-s3c24xx/irq.c   |  899 +++++++++++++++++++++--------------------
 2 files changed, 456 insertions(+), 444 deletions(-)

diff --git a/arch/arm/plat-s3c24xx/Kconfig b/arch/arm/plat-s3c24xx/Kconfig
index eef3b6a..3bb5c8f 100644
--- a/arch/arm/plat-s3c24xx/Kconfig
+++ b/arch/arm/plat-s3c24xx/Kconfig
@@ -9,6 +9,7 @@ config PLAT_S3C24XX
 	select ARCH_REQUIRE_GPIOLIB
 	select NO_IOPORT
 	select S3C_DEV_NAND
+	select IRQ_DOMAIN
 	help
 	  Base platform code for any Samsung S3C24XX device
 
diff --git a/arch/arm/plat-s3c24xx/irq.c b/arch/arm/plat-s3c24xx/irq.c
index fe57bbb..2706816 100644
--- a/arch/arm/plat-s3c24xx/irq.c
+++ b/arch/arm/plat-s3c24xx/irq.c
@@ -1,7 +1,9 @@
-/* linux/arch/arm/plat-s3c24xx/irq.c
+/*
+ * S3C24XX IRQ handling
  *
  * Copyright (c) 2003-2004 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
+ * Copyright (c) 2012 Heiko Stuebner <heiko@sntech.de>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -12,10 +14,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
 
 #include <linux/init.h>
@@ -25,6 +23,8 @@
 #include <linux/device.h>
 #include <linux/syscore_ops.h>
 
+#include <linux/irqdomain.h>
+
 #include <asm/irq.h>
 #include <asm/mach/irq.h>
 
@@ -34,54 +34,88 @@
 #include <plat/pm.h>
 #include <plat/irq.h>
 
-static void
-s3c_irq_mask(struct irq_data *data)
-{
-	unsigned int irqno = data->irq - IRQ_EINT0;
-	unsigned long mask;
+#define S3C_IRQTYPE_NONE	0
 
-	mask = __raw_readl(S3C2410_INTMSK);
-	mask |= 1UL << irqno;
-	__raw_writel(mask, S3C2410_INTMSK);
-}
+/* s3c_irq_eint0t4 chip + edge handler */
+#define S3C_IRQTYPE_EINT0T4	1
 
-static inline void
-s3c_irq_ack(struct irq_data *data)
-{
-	unsigned long bitval = 1UL << (data->irq - IRQ_EINT0);
+/* s3c_irq_chip + edge handler */
+#define S3C_IRQTYPE_EDGE	2
 
-	__raw_writel(bitval, S3C2410_SRCPND);
-	__raw_writel(bitval, S3C2410_INTPND);
-}
+/* s3c_irq_level_chip + level handler + without valid flag */
+#define S3C_IRQTYPE_PARENT	3
+
+/* s3c_irqsub_level + level handler */
+#define S3C_IRQTYPE_SUBLEVEL	4
+
+/* s3c_irqsub_edge + edge handler */
+#define S3C_IRQTYPE_SUBEDGE	5
+
+/* s3c_irqext_chip + edge handler */
+#define S3C_IRQTYPE_SUBEINT	6
+
+struct s3c_irq_data {
+	unsigned int type;
+	unsigned long parent_irq;
+
+	/* data gets filled during init */
+	struct s3c_irq_intc *intc;
+	unsigned long sub_bits;
+	struct s3c_irq_intc *sub_intc;
+};
+
+/*
+ * Sructure holding the controller data
+ * @reg_pending		register holding pending irqs
+ * @reg_intpnd		special register intpnd in main intc
+ * @reg_mask		mask register
+ * @domain		irq_domain of the controller
+ * @parent		parent controller for ext and sub irqs
+ * @irqs		irq-data, always s3c_irq_data[32]
+ */
+struct s3c_irq_intc {
+	void __iomem		*reg_pending;
+	void __iomem		*reg_intpnd;
+	void __iomem		*reg_mask;
+	struct irq_domain	*domain;
+	struct s3c_irq_intc	*parent;
+	struct s3c_irq_data	*irqs;
+};
 
-static inline void
-s3c_irq_maskack(struct irq_data *data)
+static inline void s3c_irq_mask(struct irq_data *data)
 {
-	unsigned long bitval = 1UL << (data->irq - IRQ_EINT0);
+	struct s3c_irq_intc *intc = data->domain->host_data;
 	unsigned long mask;
 
-	mask = __raw_readl(S3C2410_INTMSK);
-	__raw_writel(mask|bitval, S3C2410_INTMSK);
-
-	__raw_writel(bitval, S3C2410_SRCPND);
-	__raw_writel(bitval, S3C2410_INTPND);
+	mask = __raw_readl(intc->reg_mask);
+	mask |= 1UL << data->hwirq;
+	__raw_writel(mask, intc->reg_mask);
 }
 
-
-static void
-s3c_irq_unmask(struct irq_data *data)
+static inline void s3c_irq_unmask(struct irq_data *data)
 {
-	unsigned int irqno = data->irq;
+	struct s3c_irq_intc *intc = data->domain->host_data;
 	unsigned long mask;
 
-	if (irqno != IRQ_TIMER4 && irqno != IRQ_EINT8t23)
-		irqdbf2("s3c_irq_unmask %d\n", irqno);
+	mask = __raw_readl(intc->reg_mask);
+	mask &= ~(1UL << data->hwirq);
+	__raw_writel(mask, intc->reg_mask);
+}
+
+static inline void s3c_irq_ack(struct irq_data *data)
+{
+	struct s3c_irq_intc *intc = data->domain->host_data;
+	unsigned long bitval = 1UL << data->hwirq;
 
-	irqno -= IRQ_EINT0;
+	__raw_writel(bitval, intc->reg_pending);
+	if (intc->reg_intpnd)
+		__raw_writel(bitval, intc->reg_intpnd);
+}
 
-	mask = __raw_readl(S3C2410_INTMSK);
-	mask &= ~(1UL << irqno);
-	__raw_writel(mask, S3C2410_INTMSK);
+static inline void s3c_irq_maskack(struct irq_data *data)
+{
+	s3c_irq_mask(data);
+	s3c_irq_ack(data);
 }
 
 struct irq_chip s3c_irq_level_chip = {
@@ -100,87 +134,42 @@ struct irq_chip s3c_irq_chip = {
 	.irq_set_wake	= s3c_irq_wake
 };
 
-static void
-s3c_irqext_mask(struct irq_data *data)
-{
-	unsigned int irqno = data->irq - EXTINT_OFF;
-	unsigned long mask;
-
-	mask = __raw_readl(S3C24XX_EINTMASK);
-	mask |= ( 1UL << irqno);
-	__raw_writel(mask, S3C24XX_EINTMASK);
-}
-
-static void
-s3c_irqext_ack(struct irq_data *data)
+static void s3c_irqext_ack(struct irq_data *data)
 {
+	struct s3c_irq_intc *intc = data->domain->host_data;
+	struct s3c_irq_intc *parent_intc = intc->parent;
+	struct s3c_irq_data *irq_data = &intc->irqs[data->hwirq];
+	struct s3c_irq_data *parent_data;
 	unsigned long req;
-	unsigned long bit;
 	unsigned long mask;
+	unsigned int irqno;
 
-	bit = 1UL << (data->irq - EXTINT_OFF);
+	parent_data = &parent_intc->irqs[irq_data->parent_irq];
 
-	mask = __raw_readl(S3C24XX_EINTMASK);
+	mask = __raw_readl(intc->reg_mask);
 
-	__raw_writel(bit, S3C24XX_EINTPEND);
+	__raw_writel(1UL << data->hwirq, intc->reg_pending);
 
-	req = __raw_readl(S3C24XX_EINTPEND);
+	req = __raw_readl(intc->reg_pending);
 	req &= ~mask;
 
 	/* not sure if we should be acking the parent irq... */
 
-	if (data->irq <= IRQ_EINT7) {
-		if ((req & 0xf0) == 0)
-			s3c_irq_ack(irq_get_irq_data(IRQ_EINT4t7));
-	} else {
-		if ((req >> 8) == 0)
-			s3c_irq_ack(irq_get_irq_data(IRQ_EINT8t23));
+	if ((req & parent_data->sub_bits) == 0) {
+		irqno = irq_find_mapping(parent_intc->domain,
+					 irq_data->parent_irq);
+		s3c_irq_ack(irq_get_irq_data(irqno));
 	}
 }
 
-static void
-s3c_irqext_unmask(struct irq_data *data)
+static int s3c_irqext_type_set(void __iomem *gpcon_reg,
+			       void __iomem *extint_reg,
+			       unsigned long gpcon_offset,
+			       unsigned long extint_offset,
+			       unsigned int type)
 {
-	unsigned int irqno = data->irq - EXTINT_OFF;
-	unsigned long mask;
-
-	mask = __raw_readl(S3C24XX_EINTMASK);
-	mask &= ~(1UL << irqno);
-	__raw_writel(mask, S3C24XX_EINTMASK);
-}
-
-int
-s3c_irqext_type(struct irq_data *data, unsigned int type)
-{
-	void __iomem *extint_reg;
-	void __iomem *gpcon_reg;
-	unsigned long gpcon_offset, extint_offset;
 	unsigned long newvalue = 0, value;
 
-	if ((data->irq >= IRQ_EINT0) && (data->irq <= IRQ_EINT3)) {
-		gpcon_reg = S3C2410_GPFCON;
-		extint_reg = S3C24XX_EXTINT0;
-		gpcon_offset = (data->irq - IRQ_EINT0) * 2;
-		extint_offset = (data->irq - IRQ_EINT0) * 4;
-	} else if ((data->irq >= IRQ_EINT4) && (data->irq <= IRQ_EINT7)) {
-		gpcon_reg = S3C2410_GPFCON;
-		extint_reg = S3C24XX_EXTINT0;
-		gpcon_offset = (data->irq - (EXTINT_OFF)) * 2;
-		extint_offset = (data->irq - (EXTINT_OFF)) * 4;
-	} else if ((data->irq >= IRQ_EINT8) && (data->irq <= IRQ_EINT15)) {
-		gpcon_reg = S3C2410_GPGCON;
-		extint_reg = S3C24XX_EXTINT1;
-		gpcon_offset = (data->irq - IRQ_EINT8) * 2;
-		extint_offset = (data->irq - IRQ_EINT8) * 4;
-	} else if ((data->irq >= IRQ_EINT16) && (data->irq <= IRQ_EINT23)) {
-		gpcon_reg = S3C2410_GPGCON;
-		extint_reg = S3C24XX_EXTINT2;
-		gpcon_offset = (data->irq - IRQ_EINT8) * 2;
-		extint_offset = (data->irq - IRQ_EINT16) * 4;
-	} else {
-		return -1;
-	}
-
 	/* Set the GPIO to external interrupt mode */
 	value = __raw_readl(gpcon_reg);
 	value = (value & ~(3 << gpcon_offset)) | (0x02 << gpcon_offset);
@@ -190,7 +179,7 @@ s3c_irqext_type(struct irq_data *data, unsigned int type)
 	switch (type)
 	{
 		case IRQ_TYPE_NONE:
-			printk(KERN_WARNING "No edge setting!\n");
+			pr_warn("No edge setting!\n");
 			break;
 
 		case IRQ_TYPE_EDGE_RISING:
@@ -214,8 +203,8 @@ s3c_irqext_type(struct irq_data *data, unsigned int type)
 			break;
 
 		default:
-			printk(KERN_ERR "No such irq type %d", type);
-			return -1;
+			pr_err("No such irq type %d", type);
+			return -EINVAL;
 	}
 
 	value = __raw_readl(extint_reg);
@@ -225,10 +214,63 @@ s3c_irqext_type(struct irq_data *data, unsigned int type)
 	return 0;
 }
 
+/* FIXME: make static when it's out of plat-samsung/irq.h */
+int s3c_irqext_type(struct irq_data *data, unsigned int type)
+{
+	void __iomem *extint_reg;
+	void __iomem *gpcon_reg;
+	unsigned long gpcon_offset, extint_offset;
+
+	if ((data->hwirq >= 4) && (data->hwirq <= 7)) {
+		gpcon_reg = S3C2410_GPFCON;
+		extint_reg = S3C24XX_EXTINT0;
+		gpcon_offset = (data->hwirq) * 2;
+		extint_offset = (data->hwirq) * 4;
+	} else if ((data->hwirq >= 8) && (data->hwirq <= 15)) {
+		gpcon_reg = S3C2410_GPGCON;
+		extint_reg = S3C24XX_EXTINT1;
+		gpcon_offset = (data->hwirq - 8) * 2;
+		extint_offset = (data->hwirq - 8) * 4;
+	} else if ((data->hwirq >= 16) && (data->hwirq <= 23)) {
+		gpcon_reg = S3C2410_GPGCON;
+		extint_reg = S3C24XX_EXTINT2;
+		gpcon_offset = (data->hwirq - 8) * 2;
+		extint_offset = (data->hwirq - 16) * 4;
+	} else {
+		return -EINVAL;
+	}
+
+	return s3c_irqext_type_set(gpcon_reg, extint_reg, gpcon_offset,
+				   extint_offset, type);
+}
+
+static int s3c_irqext0_type(struct irq_data *data, unsigned int type)
+{
+	void __iomem *extint_reg;
+	void __iomem *gpcon_reg;
+	unsigned long gpcon_offset, extint_offset;
+
+	if ((data->hwirq >= 0) && (data->hwirq <= 3)) {
+		gpcon_reg = S3C2410_GPFCON;
+		extint_reg = S3C24XX_EXTINT0;
+		gpcon_offset = (data->hwirq) * 2;
+		extint_offset = (data->hwirq) * 4;
+	} else {
+		return -EINVAL;
+	}
+
+	return s3c_irqext_type_set(gpcon_reg, extint_reg, gpcon_offset,
+				   extint_offset, type);
+}
+
+/* FIXME: what is the correct behaviour for mask and unmask?
+ * The previous s3c_irqext_mask/unmask functions only set the EINTMASK
+ * register, while the other subirqs also mask the parent irq
+ */
 static struct irq_chip s3c_irqext_chip = {
 	.name		= "s3c-ext",
-	.irq_mask	= s3c_irqext_mask,
-	.irq_unmask	= s3c_irqext_unmask,
+	.irq_mask	= s3c_irq_mask,
+	.irq_unmask	= s3c_irq_unmask,
 	.irq_ack	= s3c_irqext_ack,
 	.irq_set_type	= s3c_irqext_type,
 	.irq_set_wake	= s3c_irqext_wake
@@ -240,249 +282,115 @@ static struct irq_chip s3c_irq_eint0t4 = {
 	.irq_mask	= s3c_irq_mask,
 	.irq_unmask	= s3c_irq_unmask,
 	.irq_set_wake	= s3c_irq_wake,
-	.irq_set_type	= s3c_irqext_type,
+	.irq_set_type	= s3c_irqext0_type,
 };
 
-/* mask values for the parent registers for each of the interrupt types */
-
-#define INTMSK_UART0	 (1UL << (IRQ_UART0 - IRQ_EINT0))
-#define INTMSK_UART1	 (1UL << (IRQ_UART1 - IRQ_EINT0))
-#define INTMSK_UART2	 (1UL << (IRQ_UART2 - IRQ_EINT0))
-#define INTMSK_ADCPARENT (1UL << (IRQ_ADCPARENT - IRQ_EINT0))
-
-
-/* UART0 */
-
-static void
-s3c_irq_uart0_mask(struct irq_data *data)
+static void s3c_subirq_mask(struct irq_data *data)
 {
-	s3c_irqsub_mask(data->irq, INTMSK_UART0, 7);
-}
-
-static void
-s3c_irq_uart0_unmask(struct irq_data *data)
-{
-	s3c_irqsub_unmask(data->irq, INTMSK_UART0);
-}
-
-static void
-s3c_irq_uart0_ack(struct irq_data *data)
-{
-	s3c_irqsub_maskack(data->irq, INTMSK_UART0, 7);
-}
-
-static struct irq_chip s3c_irq_uart0 = {
-	.name		= "s3c-uart0",
-	.irq_mask	= s3c_irq_uart0_mask,
-	.irq_unmask	= s3c_irq_uart0_unmask,
-	.irq_ack	= s3c_irq_uart0_ack,
-};
-
-/* UART1 */
-
-static void
-s3c_irq_uart1_mask(struct irq_data *data)
-{
-	s3c_irqsub_mask(data->irq, INTMSK_UART1, 7 << 3);
-}
-
-static void
-s3c_irq_uart1_unmask(struct irq_data *data)
-{
-	s3c_irqsub_unmask(data->irq, INTMSK_UART1);
-}
+	struct s3c_irq_intc *intc = data->domain->host_data;
+	struct s3c_irq_intc *parent_intc = intc->parent;
+	struct s3c_irq_data *irq_data = &intc->irqs[data->hwirq];
+	struct s3c_irq_data *parent_data;
+	unsigned long submask;
+	unsigned int irqno;
+
+	parent_data = &parent_intc->irqs[irq_data->parent_irq];
+
+	submask = __raw_readl(intc->reg_mask);
+	submask |= (1UL << data->hwirq);
+
+	/* check to see if we need to mask the parent IRQ */
+	if ((submask & parent_data->sub_bits) == parent_data->sub_bits) {
+		irqno = irq_find_mapping(parent_intc->domain,
+					 irq_data->parent_irq);
+		s3c_irq_mask(irq_get_irq_data(irqno));
+	}
 
-static void
-s3c_irq_uart1_ack(struct irq_data *data)
-{
-	s3c_irqsub_maskack(data->irq, INTMSK_UART1, 7 << 3);
+	/* write back masks */
+	__raw_writel(submask, intc->reg_mask);
 }
 
-static struct irq_chip s3c_irq_uart1 = {
-	.name		= "s3c-uart1",
-	.irq_mask	= s3c_irq_uart1_mask,
-	.irq_unmask	= s3c_irq_uart1_unmask,
-	.irq_ack	= s3c_irq_uart1_ack,
-};
-
-/* UART2 */
-
-static void
-s3c_irq_uart2_mask(struct irq_data *data)
+static void s3c_subirq_unmask(struct irq_data *data)
 {
-	s3c_irqsub_mask(data->irq, INTMSK_UART2, 7 << 6);
+	struct s3c_irq_intc *intc = data->domain->host_data;
+	struct s3c_irq_intc *parent_intc = intc->parent;
+	struct s3c_irq_data *irq_data = &intc->irqs[data->hwirq];
+	unsigned long submask;
+	unsigned int irqno;
+
+	submask = __raw_readl(intc->reg_mask);
+	submask &= ~(1UL << data->hwirq);
+	__raw_writel(submask, intc->reg_mask);
+
+	irqno = irq_find_mapping(parent_intc->domain, irq_data->parent_irq);
+	s3c_irq_unmask(irq_get_irq_data(irqno));
 }
 
-static void
-s3c_irq_uart2_unmask(struct irq_data *data)
+static void s3c_subirq_ack(struct irq_data *data)
 {
-	s3c_irqsub_unmask(data->irq, INTMSK_UART2);
+	struct s3c_irq_intc *intc = data->domain->host_data;
+	struct s3c_irq_intc *parent_intc = intc->parent;
+	struct s3c_irq_data *irq_data = &intc->irqs[data->hwirq];
+	unsigned long bit = 1UL << data->hwirq;
+	unsigned int irqno;
+
+	__raw_writel(bit, intc->reg_pending);
+
+	/* only ack parent if we've got all the irqs (seems we must
+	 * ack, all and hope that the irq system retriggers ok when
+	 * the interrupt goes off again)
+	 */
+
+	if (1) {
+		irqno = irq_find_mapping(parent_intc->domain,
+					 irq_data->parent_irq);
+		s3c_irq_ack(irq_get_irq_data(irqno));
+	}
 }
 
-static void
-s3c_irq_uart2_ack(struct irq_data *data)
+static inline void s3c_subirq_maskack(struct irq_data *data)
 {
-	s3c_irqsub_maskack(data->irq, INTMSK_UART2, 7 << 6);
+	s3c_subirq_mask(data);
+	s3c_subirq_ack(data);
 }
 
-static struct irq_chip s3c_irq_uart2 = {
-	.name		= "s3c-uart2",
-	.irq_mask	= s3c_irq_uart2_mask,
-	.irq_unmask	= s3c_irq_uart2_unmask,
-	.irq_ack	= s3c_irq_uart2_ack,
+/* used for UARTs */
+static struct irq_chip s3c_irqsub_level = {
+	.name		= "s3c-sublevel",
+	.irq_mask	= s3c_subirq_mask,
+	.irq_unmask	= s3c_subirq_unmask,
+	.irq_ack	= s3c_subirq_maskack,
 };
 
-/* ADC and Touchscreen */
-
-static void
-s3c_irq_adc_mask(struct irq_data *d)
-{
-	s3c_irqsub_mask(d->irq, INTMSK_ADCPARENT, 3 << 9);
-}
-
-static void
-s3c_irq_adc_unmask(struct irq_data *d)
-{
-	s3c_irqsub_unmask(d->irq, INTMSK_ADCPARENT);
-}
-
-static void
-s3c_irq_adc_ack(struct irq_data *d)
-{
-	s3c_irqsub_ack(d->irq, INTMSK_ADCPARENT, 3 << 9);
-}
-
-static struct irq_chip s3c_irq_adc = {
-	.name		= "s3c-adc",
-	.irq_mask	= s3c_irq_adc_mask,
-	.irq_unmask	= s3c_irq_adc_unmask,
-	.irq_ack	= s3c_irq_adc_ack,
+/* used for ADC and Touchscreen */
+static struct irq_chip s3c_irqsub_edge = {
+	.name		= "s3c-subedge",
+	.irq_mask	= s3c_subirq_mask,
+	.irq_unmask	= s3c_subirq_unmask,
+	.irq_ack	= s3c_subirq_ack,
 };
 
-/* irq demux for adc */
-static void s3c_irq_demux_adc(unsigned int irq,
-			      struct irq_desc *desc)
-{
-	unsigned int subsrc, submsk;
-	unsigned int offset = 9;
-
-	/* read the current pending interrupts, and the mask
-	 * for what it is available */
-
-	subsrc = __raw_readl(S3C2410_SUBSRCPND);
-	submsk = __raw_readl(S3C2410_INTSUBMSK);
-
-	subsrc &= ~submsk;
-	subsrc >>= offset;
-	subsrc &= 3;
-
-	if (subsrc != 0) {
-		if (subsrc & 1) {
-			generic_handle_irq(IRQ_TC);
-		}
-		if (subsrc & 2) {
-			generic_handle_irq(IRQ_ADC);
-		}
-	}
-}
-
-static void s3c_irq_demux_uart(unsigned int start)
+static void s3c_irq_demux(unsigned int irq, struct irq_desc *desc)
 {
-	unsigned int subsrc, submsk;
-	unsigned int offset = start - IRQ_S3CUART_RX0;
+	struct s3c_irq_intc *intc = desc->irq_data.domain->host_data;
+	struct s3c_irq_data *irq_data = &intc->irqs[desc->irq_data.hwirq];
+	struct s3c_irq_intc *sub_intc = irq_data->sub_intc;
+	unsigned int src, msk;
 
 	/* read the current pending interrupts, and the mask
-	 * for what it is available */
-
-	subsrc = __raw_readl(S3C2410_SUBSRCPND);
-	submsk = __raw_readl(S3C2410_INTSUBMSK);
-
-	irqdbf2("s3c_irq_demux_uart: start=%d (%d), subsrc=0x%08x,0x%08x\n",
-		start, offset, subsrc, submsk);
+	 * for what it is available
+	 */
 
-	subsrc &= ~submsk;
-	subsrc >>= offset;
-	subsrc &= 7;
+	src = __raw_readl(sub_intc->reg_pending);
+	msk = __raw_readl(sub_intc->reg_mask);
 
-	if (subsrc != 0) {
-		if (subsrc & 1)
-			generic_handle_irq(start);
+	src &= ~msk;
+	src &= irq_data->sub_bits;
 
-		if (subsrc & 2)
-			generic_handle_irq(start+1);
-
-		if (subsrc & 4)
-			generic_handle_irq(start+2);
-	}
-}
-
-/* uart demux entry points */
-
-static void
-s3c_irq_demux_uart0(unsigned int irq,
-		    struct irq_desc *desc)
-{
-	irq = irq;
-	s3c_irq_demux_uart(IRQ_S3CUART_RX0);
-}
-
-static void
-s3c_irq_demux_uart1(unsigned int irq,
-		    struct irq_desc *desc)
-{
-	irq = irq;
-	s3c_irq_demux_uart(IRQ_S3CUART_RX1);
-}
-
-static void
-s3c_irq_demux_uart2(unsigned int irq,
-		    struct irq_desc *desc)
-{
-	irq = irq;
-	s3c_irq_demux_uart(IRQ_S3CUART_RX2);
-}
-
-static void
-s3c_irq_demux_extint8(unsigned int irq,
-		      struct irq_desc *desc)
-{
-	unsigned long eintpnd = __raw_readl(S3C24XX_EINTPEND);
-	unsigned long eintmsk = __raw_readl(S3C24XX_EINTMASK);
-
-	eintpnd &= ~eintmsk;
-	eintpnd &= ~0xff;	/* ignore lower irqs */
-
-	/* we may as well handle all the pending IRQs here */
-
-	while (eintpnd) {
-		irq = __ffs(eintpnd);
-		eintpnd &= ~(1<<irq);
-
-		irq += (IRQ_EINT4 - 4);
-		generic_handle_irq(irq);
-	}
-
-}
-
-static void
-s3c_irq_demux_extint4t7(unsigned int irq,
-			struct irq_desc *desc)
-{
-	unsigned long eintpnd = __raw_readl(S3C24XX_EINTPEND);
-	unsigned long eintmsk = __raw_readl(S3C24XX_EINTMASK);
-
-	eintpnd &= ~eintmsk;
-	eintpnd &= 0xff;	/* only lower irqs */
-
-	/* we may as well handle all the pending IRQs here */
-
-	while (eintpnd) {
-		irq = __ffs(eintpnd);
-		eintpnd &= ~(1<<irq);
-
-		irq += (IRQ_EINT4 - 4);
-
-		generic_handle_irq(irq);
+	while (src) {
+		irq = __ffs(src);
+		src &= ~(1 << irq);
+		generic_handle_irq(irq_find_mapping(sub_intc->domain, irq));
 	}
 }
 
@@ -519,155 +427,258 @@ int s3c24xx_set_fiq(unsigned int irq, bool on)
 EXPORT_SYMBOL_GPL(s3c24xx_set_fiq);
 #endif
 
-
-/* s3c24xx_init_irq
- *
- * Initialise S3C2410 IRQ system
-*/
-
-void __init s3c24xx_init_irq(void)
+static int s3c24xx_irq_map(struct irq_domain *h, unsigned int virq,
+							irq_hw_number_t hw)
 {
-	unsigned long pend;
-	unsigned long last;
-	int irqno;
-	int i;
-
-#ifdef CONFIG_FIQ
-	init_FIQ(FIQ_START);
-#endif
-
-	irqdbf("s3c2410_init_irq: clearing interrupt status flags\n");
-
-	/* first, clear all interrupts pending... */
+	struct s3c_irq_intc *intc = h->host_data;
+	struct s3c_irq_data *irq_data = &intc->irqs[hw];
+	struct s3c_irq_intc *parent_intc;
+	struct s3c_irq_data *parent_irq_data;
+	bool attach_to_parent = false;
+	unsigned int irqno;
+
+	if (!intc) {
+		pr_err("irq-s3c24xx: no controller found for hwirq %lu\n", hw);
+		return -EINVAL;
+	}
 
-	last = 0;
-	for (i = 0; i < 4; i++) {
-		pend = __raw_readl(S3C24XX_EINTPEND);
+	if (!irq_data) {
+		pr_err("irq-s3c24xx: no irq data found for hwirq %lu\n", hw);
+		return -EINVAL;
+	}
 
-		if (pend == 0 || pend == last)
-			break;
+	/* attach controller pointer to irq_data */
+	irq_data->intc = intc;
 
-		__raw_writel(pend, S3C24XX_EINTPEND);
-		printk("irq: clearing pending ext status %08x\n", (int)pend);
-		last = pend;
+	/* set handler and flags */
+	switch (irq_data->type) {
+	case S3C_IRQTYPE_NONE:
+		return 0;
+	case S3C_IRQTYPE_EINT0T4:
+		irq_set_chip_and_handler(virq, &s3c_irq_eint0t4,
+					 handle_edge_irq);
+		set_irq_flags(virq, IRQF_VALID);
+		break;
+	case S3C_IRQTYPE_EDGE:
+		irq_set_chip_and_handler(virq, &s3c_irq_chip,
+					 handle_edge_irq);
+		set_irq_flags(virq, IRQF_VALID);
+		break;
+	case S3C_IRQTYPE_PARENT:
+		irq_set_chip_and_handler(virq, &s3c_irq_level_chip,
+					 handle_level_irq);
+		break;
+	case S3C_IRQTYPE_SUBEINT:
+		irq_set_chip_and_handler(virq, &s3c_irqext_chip,
+					 handle_edge_irq);
+		set_irq_flags(virq, IRQF_VALID);
+		attach_to_parent = true;
+		break;
+	case S3C_IRQTYPE_SUBLEVEL:
+		irq_set_chip_and_handler(virq, &s3c_irqsub_level,
+					 handle_level_irq);
+		set_irq_flags(virq, IRQF_VALID);
+		attach_to_parent = true;
+		break;
+	case S3C_IRQTYPE_SUBEDGE:
+		irq_set_chip_and_handler(virq, &s3c_irqsub_edge,
+					 handle_edge_irq);
+		set_irq_flags(virq, IRQF_VALID);
+		attach_to_parent = true;
+		break;
+	default:
+		pr_err("irq-s3c24xx: unsupported irqtype %d\n", irq_data->type);
+		return -EINVAL;
 	}
 
-	last = 0;
-	for (i = 0; i < 4; i++) {
-		pend = __raw_readl(S3C2410_INTPND);
+	if (attach_to_parent) {
+		parent_intc = intc->parent;
+		if (!parent_intc) {
+			pr_err("irq-s3c24xx: no parent controller found for hwirq %lu\n",
+			       hw);
+			goto err;
+		}
 
-		if (pend == 0 || pend == last)
-			break;
+		parent_irq_data = &parent_intc->irqs[irq_data->parent_irq];
+		if (!irq_data) {
+			pr_err("irq-s3c24xx: no irq data found for hwirq %lu\n",
+			       hw);
+			goto err;
+		}
 
-		__raw_writel(pend, S3C2410_SRCPND);
-		__raw_writel(pend, S3C2410_INTPND);
-		printk("irq: clearing pending status %08x\n", (int)pend);
-		last = pend;
+		parent_irq_data->sub_intc = intc;
+		parent_irq_data->sub_bits |= (1UL << hw);
+
+		/* attach the demuxer to the parent irq */
+		irqno = irq_find_mapping(parent_intc->domain,
+					 irq_data->parent_irq);
+		irq_set_chained_handler(irqno, s3c_irq_demux);
 	}
 
-	last = 0;
-	for (i = 0; i < 4; i++) {
-		pend = __raw_readl(S3C2410_SUBSRCPND);
+	return 0;
 
-		if (pend == 0 || pend == last)
-			break;
+err:
+	set_irq_flags(virq, 0);
 
-		printk("irq: clearing subpending status %08x\n", (int)pend);
-		__raw_writel(pend, S3C2410_SUBSRCPND);
-		last = pend;
-	}
+	/* the only error results from bad mapping data*/
+	return -EINVAL;
+}
 
-	/* register the main interrupts */
+static struct irq_domain_ops s3c24xx_irq_ops = {
+	.map = s3c24xx_irq_map,
+	.xlate = irq_domain_xlate_twocell,
+};
 
-	irqdbf("s3c2410_init_irq: registering s3c2410 interrupt handlers\n");
+static void s3c24xx_clear_intc(struct s3c_irq_intc *intc)
+{
+	void __iomem *reg_source;
+	unsigned long pend;
+	unsigned long last;
+	int i;
 
-	for (irqno = IRQ_EINT4t7; irqno <= IRQ_ADCPARENT; irqno++) {
-		/* set all the s3c2410 internal irqs */
+	/* if intpnd is set, read the next pending irq from there */
+	reg_source = intc->reg_intpnd ? intc->reg_intpnd : intc->reg_pending;
 
-		switch (irqno) {
-			/* deal with the special IRQs (cascaded) */
+	last = 0;
+	for (i = 0; i < 4; i++) {
+		pend = __raw_readl(reg_source);
 
-		case IRQ_EINT4t7:
-		case IRQ_EINT8t23:
-		case IRQ_UART0:
-		case IRQ_UART1:
-		case IRQ_UART2:
-		case IRQ_ADCPARENT:
-			irq_set_chip_and_handler(irqno, &s3c_irq_level_chip,
-						 handle_level_irq);
+		if (pend == 0 || pend == last)
 			break;
 
-		case IRQ_RESERVED6:
-		case IRQ_RESERVED24:
-			/* no IRQ here */
-			break;
+		__raw_writel(pend, intc->reg_pending);
+		if (intc->reg_intpnd)
+			__raw_writel(pend, intc->reg_intpnd);
 
-		default:
-			//irqdbf("registering irq %d (s3c irq)\n", irqno);
-			irq_set_chip_and_handler(irqno, &s3c_irq_chip,
-						 handle_edge_irq);
-			set_irq_flags(irqno, IRQF_VALID);
-		}
+		pr_info("irq: clearing pending status %08x\n", (int)pend);
+		last = pend;
 	}
+}
 
-	/* setup the cascade irq handlers */
-
-	irq_set_chained_handler(IRQ_EINT4t7, s3c_irq_demux_extint4t7);
-	irq_set_chained_handler(IRQ_EINT8t23, s3c_irq_demux_extint8);
-
-	irq_set_chained_handler(IRQ_UART0, s3c_irq_demux_uart0);
-	irq_set_chained_handler(IRQ_UART1, s3c_irq_demux_uart1);
-	irq_set_chained_handler(IRQ_UART2, s3c_irq_demux_uart2);
-	irq_set_chained_handler(IRQ_ADCPARENT, s3c_irq_demux_adc);
-
-	/* external interrupts */
+/* s3c24xx_init_irq
+ *
+ * Initialise S3C2410 IRQ system
+*/
 
-	for (irqno = IRQ_EINT0; irqno <= IRQ_EINT3; irqno++) {
-		irqdbf("registering irq %d (ext int)\n", irqno);
-		irq_set_chip_and_handler(irqno, &s3c_irq_eint0t4,
-					 handle_edge_irq);
-		set_irq_flags(irqno, IRQF_VALID);
-	}
+struct s3c_irq_data init_base[32] = {
+	{ .type = S3C_IRQTYPE_EINT0T4, }, /* EINT0 */
+	{ .type = S3C_IRQTYPE_EINT0T4, }, /* EINT1 */
+	{ .type = S3C_IRQTYPE_EINT0T4, }, /* EINT2 */
+	{ .type = S3C_IRQTYPE_EINT0T4, }, /* EINT3 */
+	{ .type = S3C_IRQTYPE_PARENT, }, /* EINT4to7 */
+	{ .type = S3C_IRQTYPE_PARENT, }, /* EINT8to23 */
+	{ .type = S3C_IRQTYPE_NONE, }, /* reserved */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* nBATT_FLT */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* TICK */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* WDT */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* TIMER0 */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* TIMER1 */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* TIMER2 */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* TIMER3 */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* TIMER4 */
+	{ .type = S3C_IRQTYPE_PARENT, }, /* UART2 */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* LCD */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* DMA0 */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* DMA1 */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* DMA2 */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* DMA3 */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* SDI */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* SPI0 */
+	{ .type = S3C_IRQTYPE_PARENT, }, /* UART1 */
+	{ .type = S3C_IRQTYPE_NONE, }, /* reserved */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* USBD */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* USBH */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* IIC */
+	{ .type = S3C_IRQTYPE_PARENT, }, /* UART0 */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* SPI1 */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* RTC */
+	{ .type = S3C_IRQTYPE_PARENT, }, /* ADCPARENT */
+};
 
-	for (irqno = IRQ_EINT4; irqno <= IRQ_EINT23; irqno++) {
-		irqdbf("registering irq %d (extended s3c irq)\n", irqno);
-		irq_set_chip_and_handler(irqno, &s3c_irqext_chip,
-					 handle_edge_irq);
-		set_irq_flags(irqno, IRQF_VALID);
-	}
+struct s3c_irq_data init_eint[32] = {
+	{ .type = S3C_IRQTYPE_NONE, }, /* reserved */
+	{ .type = S3C_IRQTYPE_NONE, }, /* reserved */
+	{ .type = S3C_IRQTYPE_NONE, }, /* reserved */
+	{ .type = S3C_IRQTYPE_NONE, }, /* reserved */
+	{ .type = S3C_IRQTYPE_SUBEINT, .parent_irq = 4 }, /* EINT4 */
+	{ .type = S3C_IRQTYPE_SUBEINT, .parent_irq = 4 }, /* EINT5 */
+	{ .type = S3C_IRQTYPE_SUBEINT, .parent_irq = 4 }, /* EINT6 */
+	{ .type = S3C_IRQTYPE_SUBEINT, .parent_irq = 4 }, /* EINT7 */
+	{ .type = S3C_IRQTYPE_SUBEINT, .parent_irq = 5 }, /* EINT8 */
+	{ .type = S3C_IRQTYPE_SUBEINT, .parent_irq = 5 }, /* EINT9 */
+	{ .type = S3C_IRQTYPE_SUBEINT, .parent_irq = 5 }, /* EINT10 */
+	{ .type = S3C_IRQTYPE_SUBEINT, .parent_irq = 5 }, /* EINT11 */
+	{ .type = S3C_IRQTYPE_SUBEINT, .parent_irq = 5 }, /* EINT12 */
+	{ .type = S3C_IRQTYPE_SUBEINT, .parent_irq = 5 }, /* EINT13 */
+	{ .type = S3C_IRQTYPE_SUBEINT, .parent_irq = 5 }, /* EINT14 */
+	{ .type = S3C_IRQTYPE_SUBEINT, .parent_irq = 5 }, /* EINT15 */
+	{ .type = S3C_IRQTYPE_SUBEINT, .parent_irq = 5 }, /* EINT16 */
+	{ .type = S3C_IRQTYPE_SUBEINT, .parent_irq = 5 }, /* EINT17 */
+	{ .type = S3C_IRQTYPE_SUBEINT, .parent_irq = 5 }, /* EINT18 */
+	{ .type = S3C_IRQTYPE_SUBEINT, .parent_irq = 5 }, /* EINT19 */
+	{ .type = S3C_IRQTYPE_SUBEINT, .parent_irq = 5 }, /* EINT20 */
+	{ .type = S3C_IRQTYPE_SUBEINT, .parent_irq = 5 }, /* EINT21 */
+	{ .type = S3C_IRQTYPE_SUBEINT, .parent_irq = 5 }, /* EINT22 */
+	{ .type = S3C_IRQTYPE_SUBEINT, .parent_irq = 5 }, /* EINT23 */
+};
 
-	/* register the uart interrupts */
+struct s3c_irq_data init_subint[32] = {
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 28 }, /* UART0-RX */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 28 }, /* UART0-TX */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 28 }, /* UART0-ERR */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 23 }, /* UART1-RX */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 23 }, /* UART1-TX */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 23 }, /* UART1-ERR */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 15 }, /* UART2-RX */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 15 }, /* UART2-TX */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 15 }, /* UART2-ERR */
+	{ .type = S3C_IRQTYPE_SUBEDGE, .parent_irq = 31 }, /* TC */
+	{ .type = S3C_IRQTYPE_SUBEDGE, .parent_irq = 31 }, /* ADC */
+};
 
-	irqdbf("s3c2410: registering external interrupts\n");
+static struct s3c_irq_intc s3c_intc[3] = {
+	[0] = {
+		.reg_pending = S3C2410_SRCPND,
+		.reg_intpnd = S3C2410_INTPND,
+		.reg_mask = S3C2410_INTMSK,
+		.irqs = &init_base[0],
+	},
+	[1] = {
+		.reg_pending = S3C2410_EINTPEND,
+		.reg_mask = S3C2410_EINTMASK,
+		.irqs = &init_eint[0],
+	},
+	[2] = {
+		.reg_pending = S3C2410_SUBSRCPND,
+		.reg_mask = S3C2410_INTSUBMSK,
+		.irqs = &init_subint[0],
+	},
+};
 
-	for (irqno = IRQ_S3CUART_RX0; irqno <= IRQ_S3CUART_ERR0; irqno++) {
-		irqdbf("registering irq %d (s3c uart0 irq)\n", irqno);
-		irq_set_chip_and_handler(irqno, &s3c_irq_uart0,
-					 handle_level_irq);
-		set_irq_flags(irqno, IRQF_VALID);
-	}
+void __init s3c24xx_init_irq(void)
+{
+#ifdef CONFIG_FIQ
+	init_FIQ(FIQ_START);
+#endif
 
-	for (irqno = IRQ_S3CUART_RX1; irqno <= IRQ_S3CUART_ERR1; irqno++) {
-		irqdbf("registering irq %d (s3c uart1 irq)\n", irqno);
-		irq_set_chip_and_handler(irqno, &s3c_irq_uart1,
-					 handle_level_irq);
-		set_irq_flags(irqno, IRQF_VALID);
-	}
+	/* attach the sub handlers to the main one */
+	s3c_intc[1].parent = &s3c_intc[0];
+	s3c_intc[2].parent = &s3c_intc[0];
 
-	for (irqno = IRQ_S3CUART_RX2; irqno <= IRQ_S3CUART_ERR2; irqno++) {
-		irqdbf("registering irq %d (s3c uart2 irq)\n", irqno);
-		irq_set_chip_and_handler(irqno, &s3c_irq_uart2,
-					 handle_level_irq);
-		set_irq_flags(irqno, IRQF_VALID);
-	}
+	/* basic interrupt register */
+	s3c24xx_clear_intc(&s3c_intc[0]);
+	s3c_intc[0].domain = irq_domain_add_legacy(NULL, 32, IRQ_EINT0, 0,
+					       &s3c24xx_irq_ops, &s3c_intc[0]);
 
-	for (irqno = IRQ_TC; irqno <= IRQ_ADC; irqno++) {
-		irqdbf("registering irq %d (s3c adc irq)\n", irqno);
-		irq_set_chip_and_handler(irqno, &s3c_irq_adc, handle_edge_irq);
-		set_irq_flags(irqno, IRQF_VALID);
-	}
+	/* extint register, irqs begin at bit4 */
+	s3c24xx_clear_intc(&s3c_intc[1]);
+	s3c_intc[1].domain = irq_domain_add_legacy(NULL, 20, IRQ_EINT4, 4,
+					       &s3c24xx_irq_ops, &s3c_intc[1]);
 
-	irqdbf("s3c2410: registered interrupt handlers\n");
+	/* subint register, 29 to fit subints of all SoCs */
+	s3c24xx_clear_intc(&s3c_intc[2]);
+	s3c_intc[2].domain = irq_domain_add_legacy(NULL, 29, IRQ_S3CUART_RX0, 0,
+					       &s3c24xx_irq_ops, &s3c_intc[2]);
 }
 
 struct syscore_ops s3c24xx_irq_syscore_ops = {
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 01/10] ARM: S3C24XX: transform irq handling into a declarative form
@ 2012-11-18  0:52   ` Heiko Stübner
  0 siblings, 0 replies; 24+ messages in thread
From: Heiko Stübner @ 2012-11-18  0:52 UTC (permalink / raw)
  To: linux-arm-kernel

The irqs available on the machine and even the bit settings in the
irq registers differ a lot through all the s3c24xx subarchitectures.
This results in each subarch having its own irq init which adds its
specific irqs to the base ones created in plat-s3c24xx/irq.c.

This of course makes a future move to devicetree hard to implement.

Therefore this patch transforms the base irq handling to a declarative
style, where the irq types as well as its parent/child relationship
gets read from a predefined datastructure, which later on can hopefully
be easily represented in devicetree too.

It should also be easy to include the subarch specific irqs here
in later patches, reducing code size and duplication.

It should not affect anything outside of the file, as the original
irq numbers and their handling are preserved (hopefully) correctly.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
 arch/arm/plat-s3c24xx/Kconfig |    1 +
 arch/arm/plat-s3c24xx/irq.c   |  899 +++++++++++++++++++++--------------------
 2 files changed, 456 insertions(+), 444 deletions(-)

diff --git a/arch/arm/plat-s3c24xx/Kconfig b/arch/arm/plat-s3c24xx/Kconfig
index eef3b6a..3bb5c8f 100644
--- a/arch/arm/plat-s3c24xx/Kconfig
+++ b/arch/arm/plat-s3c24xx/Kconfig
@@ -9,6 +9,7 @@ config PLAT_S3C24XX
 	select ARCH_REQUIRE_GPIOLIB
 	select NO_IOPORT
 	select S3C_DEV_NAND
+	select IRQ_DOMAIN
 	help
 	  Base platform code for any Samsung S3C24XX device
 
diff --git a/arch/arm/plat-s3c24xx/irq.c b/arch/arm/plat-s3c24xx/irq.c
index fe57bbb..2706816 100644
--- a/arch/arm/plat-s3c24xx/irq.c
+++ b/arch/arm/plat-s3c24xx/irq.c
@@ -1,7 +1,9 @@
-/* linux/arch/arm/plat-s3c24xx/irq.c
+/*
+ * S3C24XX IRQ handling
  *
  * Copyright (c) 2003-2004 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
+ * Copyright (c) 2012 Heiko Stuebner <heiko@sntech.de>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -12,10 +14,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
 
 #include <linux/init.h>
@@ -25,6 +23,8 @@
 #include <linux/device.h>
 #include <linux/syscore_ops.h>
 
+#include <linux/irqdomain.h>
+
 #include <asm/irq.h>
 #include <asm/mach/irq.h>
 
@@ -34,54 +34,88 @@
 #include <plat/pm.h>
 #include <plat/irq.h>
 
-static void
-s3c_irq_mask(struct irq_data *data)
-{
-	unsigned int irqno = data->irq - IRQ_EINT0;
-	unsigned long mask;
+#define S3C_IRQTYPE_NONE	0
 
-	mask = __raw_readl(S3C2410_INTMSK);
-	mask |= 1UL << irqno;
-	__raw_writel(mask, S3C2410_INTMSK);
-}
+/* s3c_irq_eint0t4 chip + edge handler */
+#define S3C_IRQTYPE_EINT0T4	1
 
-static inline void
-s3c_irq_ack(struct irq_data *data)
-{
-	unsigned long bitval = 1UL << (data->irq - IRQ_EINT0);
+/* s3c_irq_chip + edge handler */
+#define S3C_IRQTYPE_EDGE	2
 
-	__raw_writel(bitval, S3C2410_SRCPND);
-	__raw_writel(bitval, S3C2410_INTPND);
-}
+/* s3c_irq_level_chip + level handler + without valid flag */
+#define S3C_IRQTYPE_PARENT	3
+
+/* s3c_irqsub_level + level handler */
+#define S3C_IRQTYPE_SUBLEVEL	4
+
+/* s3c_irqsub_edge + edge handler */
+#define S3C_IRQTYPE_SUBEDGE	5
+
+/* s3c_irqext_chip + edge handler */
+#define S3C_IRQTYPE_SUBEINT	6
+
+struct s3c_irq_data {
+	unsigned int type;
+	unsigned long parent_irq;
+
+	/* data gets filled during init */
+	struct s3c_irq_intc *intc;
+	unsigned long sub_bits;
+	struct s3c_irq_intc *sub_intc;
+};
+
+/*
+ * Sructure holding the controller data
+ * @reg_pending		register holding pending irqs
+ * @reg_intpnd		special register intpnd in main intc
+ * @reg_mask		mask register
+ * @domain		irq_domain of the controller
+ * @parent		parent controller for ext and sub irqs
+ * @irqs		irq-data, always s3c_irq_data[32]
+ */
+struct s3c_irq_intc {
+	void __iomem		*reg_pending;
+	void __iomem		*reg_intpnd;
+	void __iomem		*reg_mask;
+	struct irq_domain	*domain;
+	struct s3c_irq_intc	*parent;
+	struct s3c_irq_data	*irqs;
+};
 
-static inline void
-s3c_irq_maskack(struct irq_data *data)
+static inline void s3c_irq_mask(struct irq_data *data)
 {
-	unsigned long bitval = 1UL << (data->irq - IRQ_EINT0);
+	struct s3c_irq_intc *intc = data->domain->host_data;
 	unsigned long mask;
 
-	mask = __raw_readl(S3C2410_INTMSK);
-	__raw_writel(mask|bitval, S3C2410_INTMSK);
-
-	__raw_writel(bitval, S3C2410_SRCPND);
-	__raw_writel(bitval, S3C2410_INTPND);
+	mask = __raw_readl(intc->reg_mask);
+	mask |= 1UL << data->hwirq;
+	__raw_writel(mask, intc->reg_mask);
 }
 
-
-static void
-s3c_irq_unmask(struct irq_data *data)
+static inline void s3c_irq_unmask(struct irq_data *data)
 {
-	unsigned int irqno = data->irq;
+	struct s3c_irq_intc *intc = data->domain->host_data;
 	unsigned long mask;
 
-	if (irqno != IRQ_TIMER4 && irqno != IRQ_EINT8t23)
-		irqdbf2("s3c_irq_unmask %d\n", irqno);
+	mask = __raw_readl(intc->reg_mask);
+	mask &= ~(1UL << data->hwirq);
+	__raw_writel(mask, intc->reg_mask);
+}
+
+static inline void s3c_irq_ack(struct irq_data *data)
+{
+	struct s3c_irq_intc *intc = data->domain->host_data;
+	unsigned long bitval = 1UL << data->hwirq;
 
-	irqno -= IRQ_EINT0;
+	__raw_writel(bitval, intc->reg_pending);
+	if (intc->reg_intpnd)
+		__raw_writel(bitval, intc->reg_intpnd);
+}
 
-	mask = __raw_readl(S3C2410_INTMSK);
-	mask &= ~(1UL << irqno);
-	__raw_writel(mask, S3C2410_INTMSK);
+static inline void s3c_irq_maskack(struct irq_data *data)
+{
+	s3c_irq_mask(data);
+	s3c_irq_ack(data);
 }
 
 struct irq_chip s3c_irq_level_chip = {
@@ -100,87 +134,42 @@ struct irq_chip s3c_irq_chip = {
 	.irq_set_wake	= s3c_irq_wake
 };
 
-static void
-s3c_irqext_mask(struct irq_data *data)
-{
-	unsigned int irqno = data->irq - EXTINT_OFF;
-	unsigned long mask;
-
-	mask = __raw_readl(S3C24XX_EINTMASK);
-	mask |= ( 1UL << irqno);
-	__raw_writel(mask, S3C24XX_EINTMASK);
-}
-
-static void
-s3c_irqext_ack(struct irq_data *data)
+static void s3c_irqext_ack(struct irq_data *data)
 {
+	struct s3c_irq_intc *intc = data->domain->host_data;
+	struct s3c_irq_intc *parent_intc = intc->parent;
+	struct s3c_irq_data *irq_data = &intc->irqs[data->hwirq];
+	struct s3c_irq_data *parent_data;
 	unsigned long req;
-	unsigned long bit;
 	unsigned long mask;
+	unsigned int irqno;
 
-	bit = 1UL << (data->irq - EXTINT_OFF);
+	parent_data = &parent_intc->irqs[irq_data->parent_irq];
 
-	mask = __raw_readl(S3C24XX_EINTMASK);
+	mask = __raw_readl(intc->reg_mask);
 
-	__raw_writel(bit, S3C24XX_EINTPEND);
+	__raw_writel(1UL << data->hwirq, intc->reg_pending);
 
-	req = __raw_readl(S3C24XX_EINTPEND);
+	req = __raw_readl(intc->reg_pending);
 	req &= ~mask;
 
 	/* not sure if we should be acking the parent irq... */
 
-	if (data->irq <= IRQ_EINT7) {
-		if ((req & 0xf0) == 0)
-			s3c_irq_ack(irq_get_irq_data(IRQ_EINT4t7));
-	} else {
-		if ((req >> 8) == 0)
-			s3c_irq_ack(irq_get_irq_data(IRQ_EINT8t23));
+	if ((req & parent_data->sub_bits) == 0) {
+		irqno = irq_find_mapping(parent_intc->domain,
+					 irq_data->parent_irq);
+		s3c_irq_ack(irq_get_irq_data(irqno));
 	}
 }
 
-static void
-s3c_irqext_unmask(struct irq_data *data)
+static int s3c_irqext_type_set(void __iomem *gpcon_reg,
+			       void __iomem *extint_reg,
+			       unsigned long gpcon_offset,
+			       unsigned long extint_offset,
+			       unsigned int type)
 {
-	unsigned int irqno = data->irq - EXTINT_OFF;
-	unsigned long mask;
-
-	mask = __raw_readl(S3C24XX_EINTMASK);
-	mask &= ~(1UL << irqno);
-	__raw_writel(mask, S3C24XX_EINTMASK);
-}
-
-int
-s3c_irqext_type(struct irq_data *data, unsigned int type)
-{
-	void __iomem *extint_reg;
-	void __iomem *gpcon_reg;
-	unsigned long gpcon_offset, extint_offset;
 	unsigned long newvalue = 0, value;
 
-	if ((data->irq >= IRQ_EINT0) && (data->irq <= IRQ_EINT3)) {
-		gpcon_reg = S3C2410_GPFCON;
-		extint_reg = S3C24XX_EXTINT0;
-		gpcon_offset = (data->irq - IRQ_EINT0) * 2;
-		extint_offset = (data->irq - IRQ_EINT0) * 4;
-	} else if ((data->irq >= IRQ_EINT4) && (data->irq <= IRQ_EINT7)) {
-		gpcon_reg = S3C2410_GPFCON;
-		extint_reg = S3C24XX_EXTINT0;
-		gpcon_offset = (data->irq - (EXTINT_OFF)) * 2;
-		extint_offset = (data->irq - (EXTINT_OFF)) * 4;
-	} else if ((data->irq >= IRQ_EINT8) && (data->irq <= IRQ_EINT15)) {
-		gpcon_reg = S3C2410_GPGCON;
-		extint_reg = S3C24XX_EXTINT1;
-		gpcon_offset = (data->irq - IRQ_EINT8) * 2;
-		extint_offset = (data->irq - IRQ_EINT8) * 4;
-	} else if ((data->irq >= IRQ_EINT16) && (data->irq <= IRQ_EINT23)) {
-		gpcon_reg = S3C2410_GPGCON;
-		extint_reg = S3C24XX_EXTINT2;
-		gpcon_offset = (data->irq - IRQ_EINT8) * 2;
-		extint_offset = (data->irq - IRQ_EINT16) * 4;
-	} else {
-		return -1;
-	}
-
 	/* Set the GPIO to external interrupt mode */
 	value = __raw_readl(gpcon_reg);
 	value = (value & ~(3 << gpcon_offset)) | (0x02 << gpcon_offset);
@@ -190,7 +179,7 @@ s3c_irqext_type(struct irq_data *data, unsigned int type)
 	switch (type)
 	{
 		case IRQ_TYPE_NONE:
-			printk(KERN_WARNING "No edge setting!\n");
+			pr_warn("No edge setting!\n");
 			break;
 
 		case IRQ_TYPE_EDGE_RISING:
@@ -214,8 +203,8 @@ s3c_irqext_type(struct irq_data *data, unsigned int type)
 			break;
 
 		default:
-			printk(KERN_ERR "No such irq type %d", type);
-			return -1;
+			pr_err("No such irq type %d", type);
+			return -EINVAL;
 	}
 
 	value = __raw_readl(extint_reg);
@@ -225,10 +214,63 @@ s3c_irqext_type(struct irq_data *data, unsigned int type)
 	return 0;
 }
 
+/* FIXME: make static when it's out of plat-samsung/irq.h */
+int s3c_irqext_type(struct irq_data *data, unsigned int type)
+{
+	void __iomem *extint_reg;
+	void __iomem *gpcon_reg;
+	unsigned long gpcon_offset, extint_offset;
+
+	if ((data->hwirq >= 4) && (data->hwirq <= 7)) {
+		gpcon_reg = S3C2410_GPFCON;
+		extint_reg = S3C24XX_EXTINT0;
+		gpcon_offset = (data->hwirq) * 2;
+		extint_offset = (data->hwirq) * 4;
+	} else if ((data->hwirq >= 8) && (data->hwirq <= 15)) {
+		gpcon_reg = S3C2410_GPGCON;
+		extint_reg = S3C24XX_EXTINT1;
+		gpcon_offset = (data->hwirq - 8) * 2;
+		extint_offset = (data->hwirq - 8) * 4;
+	} else if ((data->hwirq >= 16) && (data->hwirq <= 23)) {
+		gpcon_reg = S3C2410_GPGCON;
+		extint_reg = S3C24XX_EXTINT2;
+		gpcon_offset = (data->hwirq - 8) * 2;
+		extint_offset = (data->hwirq - 16) * 4;
+	} else {
+		return -EINVAL;
+	}
+
+	return s3c_irqext_type_set(gpcon_reg, extint_reg, gpcon_offset,
+				   extint_offset, type);
+}
+
+static int s3c_irqext0_type(struct irq_data *data, unsigned int type)
+{
+	void __iomem *extint_reg;
+	void __iomem *gpcon_reg;
+	unsigned long gpcon_offset, extint_offset;
+
+	if ((data->hwirq >= 0) && (data->hwirq <= 3)) {
+		gpcon_reg = S3C2410_GPFCON;
+		extint_reg = S3C24XX_EXTINT0;
+		gpcon_offset = (data->hwirq) * 2;
+		extint_offset = (data->hwirq) * 4;
+	} else {
+		return -EINVAL;
+	}
+
+	return s3c_irqext_type_set(gpcon_reg, extint_reg, gpcon_offset,
+				   extint_offset, type);
+}
+
+/* FIXME: what is the correct behaviour for mask and unmask?
+ * The previous s3c_irqext_mask/unmask functions only set the EINTMASK
+ * register, while the other subirqs also mask the parent irq
+ */
 static struct irq_chip s3c_irqext_chip = {
 	.name		= "s3c-ext",
-	.irq_mask	= s3c_irqext_mask,
-	.irq_unmask	= s3c_irqext_unmask,
+	.irq_mask	= s3c_irq_mask,
+	.irq_unmask	= s3c_irq_unmask,
 	.irq_ack	= s3c_irqext_ack,
 	.irq_set_type	= s3c_irqext_type,
 	.irq_set_wake	= s3c_irqext_wake
@@ -240,249 +282,115 @@ static struct irq_chip s3c_irq_eint0t4 = {
 	.irq_mask	= s3c_irq_mask,
 	.irq_unmask	= s3c_irq_unmask,
 	.irq_set_wake	= s3c_irq_wake,
-	.irq_set_type	= s3c_irqext_type,
+	.irq_set_type	= s3c_irqext0_type,
 };
 
-/* mask values for the parent registers for each of the interrupt types */
-
-#define INTMSK_UART0	 (1UL << (IRQ_UART0 - IRQ_EINT0))
-#define INTMSK_UART1	 (1UL << (IRQ_UART1 - IRQ_EINT0))
-#define INTMSK_UART2	 (1UL << (IRQ_UART2 - IRQ_EINT0))
-#define INTMSK_ADCPARENT (1UL << (IRQ_ADCPARENT - IRQ_EINT0))
-
-
-/* UART0 */
-
-static void
-s3c_irq_uart0_mask(struct irq_data *data)
+static void s3c_subirq_mask(struct irq_data *data)
 {
-	s3c_irqsub_mask(data->irq, INTMSK_UART0, 7);
-}
-
-static void
-s3c_irq_uart0_unmask(struct irq_data *data)
-{
-	s3c_irqsub_unmask(data->irq, INTMSK_UART0);
-}
-
-static void
-s3c_irq_uart0_ack(struct irq_data *data)
-{
-	s3c_irqsub_maskack(data->irq, INTMSK_UART0, 7);
-}
-
-static struct irq_chip s3c_irq_uart0 = {
-	.name		= "s3c-uart0",
-	.irq_mask	= s3c_irq_uart0_mask,
-	.irq_unmask	= s3c_irq_uart0_unmask,
-	.irq_ack	= s3c_irq_uart0_ack,
-};
-
-/* UART1 */
-
-static void
-s3c_irq_uart1_mask(struct irq_data *data)
-{
-	s3c_irqsub_mask(data->irq, INTMSK_UART1, 7 << 3);
-}
-
-static void
-s3c_irq_uart1_unmask(struct irq_data *data)
-{
-	s3c_irqsub_unmask(data->irq, INTMSK_UART1);
-}
+	struct s3c_irq_intc *intc = data->domain->host_data;
+	struct s3c_irq_intc *parent_intc = intc->parent;
+	struct s3c_irq_data *irq_data = &intc->irqs[data->hwirq];
+	struct s3c_irq_data *parent_data;
+	unsigned long submask;
+	unsigned int irqno;
+
+	parent_data = &parent_intc->irqs[irq_data->parent_irq];
+
+	submask = __raw_readl(intc->reg_mask);
+	submask |= (1UL << data->hwirq);
+
+	/* check to see if we need to mask the parent IRQ */
+	if ((submask & parent_data->sub_bits) == parent_data->sub_bits) {
+		irqno = irq_find_mapping(parent_intc->domain,
+					 irq_data->parent_irq);
+		s3c_irq_mask(irq_get_irq_data(irqno));
+	}
 
-static void
-s3c_irq_uart1_ack(struct irq_data *data)
-{
-	s3c_irqsub_maskack(data->irq, INTMSK_UART1, 7 << 3);
+	/* write back masks */
+	__raw_writel(submask, intc->reg_mask);
 }
 
-static struct irq_chip s3c_irq_uart1 = {
-	.name		= "s3c-uart1",
-	.irq_mask	= s3c_irq_uart1_mask,
-	.irq_unmask	= s3c_irq_uart1_unmask,
-	.irq_ack	= s3c_irq_uart1_ack,
-};
-
-/* UART2 */
-
-static void
-s3c_irq_uart2_mask(struct irq_data *data)
+static void s3c_subirq_unmask(struct irq_data *data)
 {
-	s3c_irqsub_mask(data->irq, INTMSK_UART2, 7 << 6);
+	struct s3c_irq_intc *intc = data->domain->host_data;
+	struct s3c_irq_intc *parent_intc = intc->parent;
+	struct s3c_irq_data *irq_data = &intc->irqs[data->hwirq];
+	unsigned long submask;
+	unsigned int irqno;
+
+	submask = __raw_readl(intc->reg_mask);
+	submask &= ~(1UL << data->hwirq);
+	__raw_writel(submask, intc->reg_mask);
+
+	irqno = irq_find_mapping(parent_intc->domain, irq_data->parent_irq);
+	s3c_irq_unmask(irq_get_irq_data(irqno));
 }
 
-static void
-s3c_irq_uart2_unmask(struct irq_data *data)
+static void s3c_subirq_ack(struct irq_data *data)
 {
-	s3c_irqsub_unmask(data->irq, INTMSK_UART2);
+	struct s3c_irq_intc *intc = data->domain->host_data;
+	struct s3c_irq_intc *parent_intc = intc->parent;
+	struct s3c_irq_data *irq_data = &intc->irqs[data->hwirq];
+	unsigned long bit = 1UL << data->hwirq;
+	unsigned int irqno;
+
+	__raw_writel(bit, intc->reg_pending);
+
+	/* only ack parent if we've got all the irqs (seems we must
+	 * ack, all and hope that the irq system retriggers ok when
+	 * the interrupt goes off again)
+	 */
+
+	if (1) {
+		irqno = irq_find_mapping(parent_intc->domain,
+					 irq_data->parent_irq);
+		s3c_irq_ack(irq_get_irq_data(irqno));
+	}
 }
 
-static void
-s3c_irq_uart2_ack(struct irq_data *data)
+static inline void s3c_subirq_maskack(struct irq_data *data)
 {
-	s3c_irqsub_maskack(data->irq, INTMSK_UART2, 7 << 6);
+	s3c_subirq_mask(data);
+	s3c_subirq_ack(data);
 }
 
-static struct irq_chip s3c_irq_uart2 = {
-	.name		= "s3c-uart2",
-	.irq_mask	= s3c_irq_uart2_mask,
-	.irq_unmask	= s3c_irq_uart2_unmask,
-	.irq_ack	= s3c_irq_uart2_ack,
+/* used for UARTs */
+static struct irq_chip s3c_irqsub_level = {
+	.name		= "s3c-sublevel",
+	.irq_mask	= s3c_subirq_mask,
+	.irq_unmask	= s3c_subirq_unmask,
+	.irq_ack	= s3c_subirq_maskack,
 };
 
-/* ADC and Touchscreen */
-
-static void
-s3c_irq_adc_mask(struct irq_data *d)
-{
-	s3c_irqsub_mask(d->irq, INTMSK_ADCPARENT, 3 << 9);
-}
-
-static void
-s3c_irq_adc_unmask(struct irq_data *d)
-{
-	s3c_irqsub_unmask(d->irq, INTMSK_ADCPARENT);
-}
-
-static void
-s3c_irq_adc_ack(struct irq_data *d)
-{
-	s3c_irqsub_ack(d->irq, INTMSK_ADCPARENT, 3 << 9);
-}
-
-static struct irq_chip s3c_irq_adc = {
-	.name		= "s3c-adc",
-	.irq_mask	= s3c_irq_adc_mask,
-	.irq_unmask	= s3c_irq_adc_unmask,
-	.irq_ack	= s3c_irq_adc_ack,
+/* used for ADC and Touchscreen */
+static struct irq_chip s3c_irqsub_edge = {
+	.name		= "s3c-subedge",
+	.irq_mask	= s3c_subirq_mask,
+	.irq_unmask	= s3c_subirq_unmask,
+	.irq_ack	= s3c_subirq_ack,
 };
 
-/* irq demux for adc */
-static void s3c_irq_demux_adc(unsigned int irq,
-			      struct irq_desc *desc)
-{
-	unsigned int subsrc, submsk;
-	unsigned int offset = 9;
-
-	/* read the current pending interrupts, and the mask
-	 * for what it is available */
-
-	subsrc = __raw_readl(S3C2410_SUBSRCPND);
-	submsk = __raw_readl(S3C2410_INTSUBMSK);
-
-	subsrc &= ~submsk;
-	subsrc >>= offset;
-	subsrc &= 3;
-
-	if (subsrc != 0) {
-		if (subsrc & 1) {
-			generic_handle_irq(IRQ_TC);
-		}
-		if (subsrc & 2) {
-			generic_handle_irq(IRQ_ADC);
-		}
-	}
-}
-
-static void s3c_irq_demux_uart(unsigned int start)
+static void s3c_irq_demux(unsigned int irq, struct irq_desc *desc)
 {
-	unsigned int subsrc, submsk;
-	unsigned int offset = start - IRQ_S3CUART_RX0;
+	struct s3c_irq_intc *intc = desc->irq_data.domain->host_data;
+	struct s3c_irq_data *irq_data = &intc->irqs[desc->irq_data.hwirq];
+	struct s3c_irq_intc *sub_intc = irq_data->sub_intc;
+	unsigned int src, msk;
 
 	/* read the current pending interrupts, and the mask
-	 * for what it is available */
-
-	subsrc = __raw_readl(S3C2410_SUBSRCPND);
-	submsk = __raw_readl(S3C2410_INTSUBMSK);
-
-	irqdbf2("s3c_irq_demux_uart: start=%d (%d), subsrc=0x%08x,0x%08x\n",
-		start, offset, subsrc, submsk);
+	 * for what it is available
+	 */
 
-	subsrc &= ~submsk;
-	subsrc >>= offset;
-	subsrc &= 7;
+	src = __raw_readl(sub_intc->reg_pending);
+	msk = __raw_readl(sub_intc->reg_mask);
 
-	if (subsrc != 0) {
-		if (subsrc & 1)
-			generic_handle_irq(start);
+	src &= ~msk;
+	src &= irq_data->sub_bits;
 
-		if (subsrc & 2)
-			generic_handle_irq(start+1);
-
-		if (subsrc & 4)
-			generic_handle_irq(start+2);
-	}
-}
-
-/* uart demux entry points */
-
-static void
-s3c_irq_demux_uart0(unsigned int irq,
-		    struct irq_desc *desc)
-{
-	irq = irq;
-	s3c_irq_demux_uart(IRQ_S3CUART_RX0);
-}
-
-static void
-s3c_irq_demux_uart1(unsigned int irq,
-		    struct irq_desc *desc)
-{
-	irq = irq;
-	s3c_irq_demux_uart(IRQ_S3CUART_RX1);
-}
-
-static void
-s3c_irq_demux_uart2(unsigned int irq,
-		    struct irq_desc *desc)
-{
-	irq = irq;
-	s3c_irq_demux_uart(IRQ_S3CUART_RX2);
-}
-
-static void
-s3c_irq_demux_extint8(unsigned int irq,
-		      struct irq_desc *desc)
-{
-	unsigned long eintpnd = __raw_readl(S3C24XX_EINTPEND);
-	unsigned long eintmsk = __raw_readl(S3C24XX_EINTMASK);
-
-	eintpnd &= ~eintmsk;
-	eintpnd &= ~0xff;	/* ignore lower irqs */
-
-	/* we may as well handle all the pending IRQs here */
-
-	while (eintpnd) {
-		irq = __ffs(eintpnd);
-		eintpnd &= ~(1<<irq);
-
-		irq += (IRQ_EINT4 - 4);
-		generic_handle_irq(irq);
-	}
-
-}
-
-static void
-s3c_irq_demux_extint4t7(unsigned int irq,
-			struct irq_desc *desc)
-{
-	unsigned long eintpnd = __raw_readl(S3C24XX_EINTPEND);
-	unsigned long eintmsk = __raw_readl(S3C24XX_EINTMASK);
-
-	eintpnd &= ~eintmsk;
-	eintpnd &= 0xff;	/* only lower irqs */
-
-	/* we may as well handle all the pending IRQs here */
-
-	while (eintpnd) {
-		irq = __ffs(eintpnd);
-		eintpnd &= ~(1<<irq);
-
-		irq += (IRQ_EINT4 - 4);
-
-		generic_handle_irq(irq);
+	while (src) {
+		irq = __ffs(src);
+		src &= ~(1 << irq);
+		generic_handle_irq(irq_find_mapping(sub_intc->domain, irq));
 	}
 }
 
@@ -519,155 +427,258 @@ int s3c24xx_set_fiq(unsigned int irq, bool on)
 EXPORT_SYMBOL_GPL(s3c24xx_set_fiq);
 #endif
 
-
-/* s3c24xx_init_irq
- *
- * Initialise S3C2410 IRQ system
-*/
-
-void __init s3c24xx_init_irq(void)
+static int s3c24xx_irq_map(struct irq_domain *h, unsigned int virq,
+							irq_hw_number_t hw)
 {
-	unsigned long pend;
-	unsigned long last;
-	int irqno;
-	int i;
-
-#ifdef CONFIG_FIQ
-	init_FIQ(FIQ_START);
-#endif
-
-	irqdbf("s3c2410_init_irq: clearing interrupt status flags\n");
-
-	/* first, clear all interrupts pending... */
+	struct s3c_irq_intc *intc = h->host_data;
+	struct s3c_irq_data *irq_data = &intc->irqs[hw];
+	struct s3c_irq_intc *parent_intc;
+	struct s3c_irq_data *parent_irq_data;
+	bool attach_to_parent = false;
+	unsigned int irqno;
+
+	if (!intc) {
+		pr_err("irq-s3c24xx: no controller found for hwirq %lu\n", hw);
+		return -EINVAL;
+	}
 
-	last = 0;
-	for (i = 0; i < 4; i++) {
-		pend = __raw_readl(S3C24XX_EINTPEND);
+	if (!irq_data) {
+		pr_err("irq-s3c24xx: no irq data found for hwirq %lu\n", hw);
+		return -EINVAL;
+	}
 
-		if (pend == 0 || pend == last)
-			break;
+	/* attach controller pointer to irq_data */
+	irq_data->intc = intc;
 
-		__raw_writel(pend, S3C24XX_EINTPEND);
-		printk("irq: clearing pending ext status %08x\n", (int)pend);
-		last = pend;
+	/* set handler and flags */
+	switch (irq_data->type) {
+	case S3C_IRQTYPE_NONE:
+		return 0;
+	case S3C_IRQTYPE_EINT0T4:
+		irq_set_chip_and_handler(virq, &s3c_irq_eint0t4,
+					 handle_edge_irq);
+		set_irq_flags(virq, IRQF_VALID);
+		break;
+	case S3C_IRQTYPE_EDGE:
+		irq_set_chip_and_handler(virq, &s3c_irq_chip,
+					 handle_edge_irq);
+		set_irq_flags(virq, IRQF_VALID);
+		break;
+	case S3C_IRQTYPE_PARENT:
+		irq_set_chip_and_handler(virq, &s3c_irq_level_chip,
+					 handle_level_irq);
+		break;
+	case S3C_IRQTYPE_SUBEINT:
+		irq_set_chip_and_handler(virq, &s3c_irqext_chip,
+					 handle_edge_irq);
+		set_irq_flags(virq, IRQF_VALID);
+		attach_to_parent = true;
+		break;
+	case S3C_IRQTYPE_SUBLEVEL:
+		irq_set_chip_and_handler(virq, &s3c_irqsub_level,
+					 handle_level_irq);
+		set_irq_flags(virq, IRQF_VALID);
+		attach_to_parent = true;
+		break;
+	case S3C_IRQTYPE_SUBEDGE:
+		irq_set_chip_and_handler(virq, &s3c_irqsub_edge,
+					 handle_edge_irq);
+		set_irq_flags(virq, IRQF_VALID);
+		attach_to_parent = true;
+		break;
+	default:
+		pr_err("irq-s3c24xx: unsupported irqtype %d\n", irq_data->type);
+		return -EINVAL;
 	}
 
-	last = 0;
-	for (i = 0; i < 4; i++) {
-		pend = __raw_readl(S3C2410_INTPND);
+	if (attach_to_parent) {
+		parent_intc = intc->parent;
+		if (!parent_intc) {
+			pr_err("irq-s3c24xx: no parent controller found for hwirq %lu\n",
+			       hw);
+			goto err;
+		}
 
-		if (pend == 0 || pend == last)
-			break;
+		parent_irq_data = &parent_intc->irqs[irq_data->parent_irq];
+		if (!irq_data) {
+			pr_err("irq-s3c24xx: no irq data found for hwirq %lu\n",
+			       hw);
+			goto err;
+		}
 
-		__raw_writel(pend, S3C2410_SRCPND);
-		__raw_writel(pend, S3C2410_INTPND);
-		printk("irq: clearing pending status %08x\n", (int)pend);
-		last = pend;
+		parent_irq_data->sub_intc = intc;
+		parent_irq_data->sub_bits |= (1UL << hw);
+
+		/* attach the demuxer to the parent irq */
+		irqno = irq_find_mapping(parent_intc->domain,
+					 irq_data->parent_irq);
+		irq_set_chained_handler(irqno, s3c_irq_demux);
 	}
 
-	last = 0;
-	for (i = 0; i < 4; i++) {
-		pend = __raw_readl(S3C2410_SUBSRCPND);
+	return 0;
 
-		if (pend == 0 || pend == last)
-			break;
+err:
+	set_irq_flags(virq, 0);
 
-		printk("irq: clearing subpending status %08x\n", (int)pend);
-		__raw_writel(pend, S3C2410_SUBSRCPND);
-		last = pend;
-	}
+	/* the only error results from bad mapping data*/
+	return -EINVAL;
+}
 
-	/* register the main interrupts */
+static struct irq_domain_ops s3c24xx_irq_ops = {
+	.map = s3c24xx_irq_map,
+	.xlate = irq_domain_xlate_twocell,
+};
 
-	irqdbf("s3c2410_init_irq: registering s3c2410 interrupt handlers\n");
+static void s3c24xx_clear_intc(struct s3c_irq_intc *intc)
+{
+	void __iomem *reg_source;
+	unsigned long pend;
+	unsigned long last;
+	int i;
 
-	for (irqno = IRQ_EINT4t7; irqno <= IRQ_ADCPARENT; irqno++) {
-		/* set all the s3c2410 internal irqs */
+	/* if intpnd is set, read the next pending irq from there */
+	reg_source = intc->reg_intpnd ? intc->reg_intpnd : intc->reg_pending;
 
-		switch (irqno) {
-			/* deal with the special IRQs (cascaded) */
+	last = 0;
+	for (i = 0; i < 4; i++) {
+		pend = __raw_readl(reg_source);
 
-		case IRQ_EINT4t7:
-		case IRQ_EINT8t23:
-		case IRQ_UART0:
-		case IRQ_UART1:
-		case IRQ_UART2:
-		case IRQ_ADCPARENT:
-			irq_set_chip_and_handler(irqno, &s3c_irq_level_chip,
-						 handle_level_irq);
+		if (pend == 0 || pend == last)
 			break;
 
-		case IRQ_RESERVED6:
-		case IRQ_RESERVED24:
-			/* no IRQ here */
-			break;
+		__raw_writel(pend, intc->reg_pending);
+		if (intc->reg_intpnd)
+			__raw_writel(pend, intc->reg_intpnd);
 
-		default:
-			//irqdbf("registering irq %d (s3c irq)\n", irqno);
-			irq_set_chip_and_handler(irqno, &s3c_irq_chip,
-						 handle_edge_irq);
-			set_irq_flags(irqno, IRQF_VALID);
-		}
+		pr_info("irq: clearing pending status %08x\n", (int)pend);
+		last = pend;
 	}
+}
 
-	/* setup the cascade irq handlers */
-
-	irq_set_chained_handler(IRQ_EINT4t7, s3c_irq_demux_extint4t7);
-	irq_set_chained_handler(IRQ_EINT8t23, s3c_irq_demux_extint8);
-
-	irq_set_chained_handler(IRQ_UART0, s3c_irq_demux_uart0);
-	irq_set_chained_handler(IRQ_UART1, s3c_irq_demux_uart1);
-	irq_set_chained_handler(IRQ_UART2, s3c_irq_demux_uart2);
-	irq_set_chained_handler(IRQ_ADCPARENT, s3c_irq_demux_adc);
-
-	/* external interrupts */
+/* s3c24xx_init_irq
+ *
+ * Initialise S3C2410 IRQ system
+*/
 
-	for (irqno = IRQ_EINT0; irqno <= IRQ_EINT3; irqno++) {
-		irqdbf("registering irq %d (ext int)\n", irqno);
-		irq_set_chip_and_handler(irqno, &s3c_irq_eint0t4,
-					 handle_edge_irq);
-		set_irq_flags(irqno, IRQF_VALID);
-	}
+struct s3c_irq_data init_base[32] = {
+	{ .type = S3C_IRQTYPE_EINT0T4, }, /* EINT0 */
+	{ .type = S3C_IRQTYPE_EINT0T4, }, /* EINT1 */
+	{ .type = S3C_IRQTYPE_EINT0T4, }, /* EINT2 */
+	{ .type = S3C_IRQTYPE_EINT0T4, }, /* EINT3 */
+	{ .type = S3C_IRQTYPE_PARENT, }, /* EINT4to7 */
+	{ .type = S3C_IRQTYPE_PARENT, }, /* EINT8to23 */
+	{ .type = S3C_IRQTYPE_NONE, }, /* reserved */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* nBATT_FLT */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* TICK */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* WDT */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* TIMER0 */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* TIMER1 */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* TIMER2 */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* TIMER3 */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* TIMER4 */
+	{ .type = S3C_IRQTYPE_PARENT, }, /* UART2 */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* LCD */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* DMA0 */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* DMA1 */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* DMA2 */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* DMA3 */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* SDI */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* SPI0 */
+	{ .type = S3C_IRQTYPE_PARENT, }, /* UART1 */
+	{ .type = S3C_IRQTYPE_NONE, }, /* reserved */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* USBD */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* USBH */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* IIC */
+	{ .type = S3C_IRQTYPE_PARENT, }, /* UART0 */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* SPI1 */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* RTC */
+	{ .type = S3C_IRQTYPE_PARENT, }, /* ADCPARENT */
+};
 
-	for (irqno = IRQ_EINT4; irqno <= IRQ_EINT23; irqno++) {
-		irqdbf("registering irq %d (extended s3c irq)\n", irqno);
-		irq_set_chip_and_handler(irqno, &s3c_irqext_chip,
-					 handle_edge_irq);
-		set_irq_flags(irqno, IRQF_VALID);
-	}
+struct s3c_irq_data init_eint[32] = {
+	{ .type = S3C_IRQTYPE_NONE, }, /* reserved */
+	{ .type = S3C_IRQTYPE_NONE, }, /* reserved */
+	{ .type = S3C_IRQTYPE_NONE, }, /* reserved */
+	{ .type = S3C_IRQTYPE_NONE, }, /* reserved */
+	{ .type = S3C_IRQTYPE_SUBEINT, .parent_irq = 4 }, /* EINT4 */
+	{ .type = S3C_IRQTYPE_SUBEINT, .parent_irq = 4 }, /* EINT5 */
+	{ .type = S3C_IRQTYPE_SUBEINT, .parent_irq = 4 }, /* EINT6 */
+	{ .type = S3C_IRQTYPE_SUBEINT, .parent_irq = 4 }, /* EINT7 */
+	{ .type = S3C_IRQTYPE_SUBEINT, .parent_irq = 5 }, /* EINT8 */
+	{ .type = S3C_IRQTYPE_SUBEINT, .parent_irq = 5 }, /* EINT9 */
+	{ .type = S3C_IRQTYPE_SUBEINT, .parent_irq = 5 }, /* EINT10 */
+	{ .type = S3C_IRQTYPE_SUBEINT, .parent_irq = 5 }, /* EINT11 */
+	{ .type = S3C_IRQTYPE_SUBEINT, .parent_irq = 5 }, /* EINT12 */
+	{ .type = S3C_IRQTYPE_SUBEINT, .parent_irq = 5 }, /* EINT13 */
+	{ .type = S3C_IRQTYPE_SUBEINT, .parent_irq = 5 }, /* EINT14 */
+	{ .type = S3C_IRQTYPE_SUBEINT, .parent_irq = 5 }, /* EINT15 */
+	{ .type = S3C_IRQTYPE_SUBEINT, .parent_irq = 5 }, /* EINT16 */
+	{ .type = S3C_IRQTYPE_SUBEINT, .parent_irq = 5 }, /* EINT17 */
+	{ .type = S3C_IRQTYPE_SUBEINT, .parent_irq = 5 }, /* EINT18 */
+	{ .type = S3C_IRQTYPE_SUBEINT, .parent_irq = 5 }, /* EINT19 */
+	{ .type = S3C_IRQTYPE_SUBEINT, .parent_irq = 5 }, /* EINT20 */
+	{ .type = S3C_IRQTYPE_SUBEINT, .parent_irq = 5 }, /* EINT21 */
+	{ .type = S3C_IRQTYPE_SUBEINT, .parent_irq = 5 }, /* EINT22 */
+	{ .type = S3C_IRQTYPE_SUBEINT, .parent_irq = 5 }, /* EINT23 */
+};
 
-	/* register the uart interrupts */
+struct s3c_irq_data init_subint[32] = {
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 28 }, /* UART0-RX */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 28 }, /* UART0-TX */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 28 }, /* UART0-ERR */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 23 }, /* UART1-RX */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 23 }, /* UART1-TX */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 23 }, /* UART1-ERR */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 15 }, /* UART2-RX */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 15 }, /* UART2-TX */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 15 }, /* UART2-ERR */
+	{ .type = S3C_IRQTYPE_SUBEDGE, .parent_irq = 31 }, /* TC */
+	{ .type = S3C_IRQTYPE_SUBEDGE, .parent_irq = 31 }, /* ADC */
+};
 
-	irqdbf("s3c2410: registering external interrupts\n");
+static struct s3c_irq_intc s3c_intc[3] = {
+	[0] = {
+		.reg_pending = S3C2410_SRCPND,
+		.reg_intpnd = S3C2410_INTPND,
+		.reg_mask = S3C2410_INTMSK,
+		.irqs = &init_base[0],
+	},
+	[1] = {
+		.reg_pending = S3C2410_EINTPEND,
+		.reg_mask = S3C2410_EINTMASK,
+		.irqs = &init_eint[0],
+	},
+	[2] = {
+		.reg_pending = S3C2410_SUBSRCPND,
+		.reg_mask = S3C2410_INTSUBMSK,
+		.irqs = &init_subint[0],
+	},
+};
 
-	for (irqno = IRQ_S3CUART_RX0; irqno <= IRQ_S3CUART_ERR0; irqno++) {
-		irqdbf("registering irq %d (s3c uart0 irq)\n", irqno);
-		irq_set_chip_and_handler(irqno, &s3c_irq_uart0,
-					 handle_level_irq);
-		set_irq_flags(irqno, IRQF_VALID);
-	}
+void __init s3c24xx_init_irq(void)
+{
+#ifdef CONFIG_FIQ
+	init_FIQ(FIQ_START);
+#endif
 
-	for (irqno = IRQ_S3CUART_RX1; irqno <= IRQ_S3CUART_ERR1; irqno++) {
-		irqdbf("registering irq %d (s3c uart1 irq)\n", irqno);
-		irq_set_chip_and_handler(irqno, &s3c_irq_uart1,
-					 handle_level_irq);
-		set_irq_flags(irqno, IRQF_VALID);
-	}
+	/* attach the sub handlers to the main one */
+	s3c_intc[1].parent = &s3c_intc[0];
+	s3c_intc[2].parent = &s3c_intc[0];
 
-	for (irqno = IRQ_S3CUART_RX2; irqno <= IRQ_S3CUART_ERR2; irqno++) {
-		irqdbf("registering irq %d (s3c uart2 irq)\n", irqno);
-		irq_set_chip_and_handler(irqno, &s3c_irq_uart2,
-					 handle_level_irq);
-		set_irq_flags(irqno, IRQF_VALID);
-	}
+	/* basic interrupt register */
+	s3c24xx_clear_intc(&s3c_intc[0]);
+	s3c_intc[0].domain = irq_domain_add_legacy(NULL, 32, IRQ_EINT0, 0,
+					       &s3c24xx_irq_ops, &s3c_intc[0]);
 
-	for (irqno = IRQ_TC; irqno <= IRQ_ADC; irqno++) {
-		irqdbf("registering irq %d (s3c adc irq)\n", irqno);
-		irq_set_chip_and_handler(irqno, &s3c_irq_adc, handle_edge_irq);
-		set_irq_flags(irqno, IRQF_VALID);
-	}
+	/* extint register, irqs begin@bit4 */
+	s3c24xx_clear_intc(&s3c_intc[1]);
+	s3c_intc[1].domain = irq_domain_add_legacy(NULL, 20, IRQ_EINT4, 4,
+					       &s3c24xx_irq_ops, &s3c_intc[1]);
 
-	irqdbf("s3c2410: registered interrupt handlers\n");
+	/* subint register, 29 to fit subints of all SoCs */
+	s3c24xx_clear_intc(&s3c_intc[2]);
+	s3c_intc[2].domain = irq_domain_add_legacy(NULL, 29, IRQ_S3CUART_RX0, 0,
+					       &s3c24xx_irq_ops, &s3c_intc[2]);
 }
 
 struct syscore_ops s3c24xx_irq_syscore_ops = {
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 02/10] ARM: S3C24XX: move irq-pm code into main irq file
  2012-11-18  0:51 ` Heiko Stübner
@ 2012-11-18  0:52   ` Heiko Stübner
  -1 siblings, 0 replies; 24+ messages in thread
From: Heiko Stübner @ 2012-11-18  0:52 UTC (permalink / raw)
  To: Kukjin Kim; +Cc: Ben Dooks, linux-arm-kernel, linux-samsung-soc

With this change, it's possible to make more elements static
and also reduce the number of .h elements further down the road.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
 arch/arm/mach-s3c24xx/Makefile |    2 +-
 arch/arm/mach-s3c24xx/irq-pm.c |   95 ----------------------------------------
 arch/arm/plat-s3c24xx/irq.c    |   76 ++++++++++++++++++++++++++++++++
 3 files changed, 77 insertions(+), 96 deletions(-)
 delete mode 100644 arch/arm/mach-s3c24xx/irq-pm.c

diff --git a/arch/arm/mach-s3c24xx/Makefile b/arch/arm/mach-s3c24xx/Makefile
index 0ab6ab1..3e1d12c 100644
--- a/arch/arm/mach-s3c24xx/Makefile
+++ b/arch/arm/mach-s3c24xx/Makefile
@@ -37,7 +37,7 @@ obj-$(CONFIG_CPU_S3C2443)	+= s3c2443.o irq-s3c2443.o clock-s3c2443.o
 
 # PM
 
-obj-$(CONFIG_PM)		+= pm.o irq-pm.o sleep.o
+obj-$(CONFIG_PM)		+= pm.o sleep.o
 
 # common code
 
diff --git a/arch/arm/mach-s3c24xx/irq-pm.c b/arch/arm/mach-s3c24xx/irq-pm.c
deleted file mode 100644
index 0efb2e2..0000000
--- a/arch/arm/mach-s3c24xx/irq-pm.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/* linux/arch/arm/plat-s3c24xx/irq-om.c
- *
- * Copyright (c) 2003-2004 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *	http://armlinux.simtec.co.uk/
- *
- * S3C24XX - IRQ PM code
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-
-#include <plat/cpu.h>
-#include <plat/pm.h>
-#include <plat/irq.h>
-
-#include <asm/irq.h>
-
-/* state for IRQs over sleep */
-
-/* default is to allow for EINT0..EINT15, and IRQ_RTC as wakeup sources
- *
- * set bit to 1 in allow bitfield to enable the wakeup settings on it
-*/
-
-unsigned long s3c_irqwake_intallow	= 1L << (IRQ_RTC - IRQ_EINT0) | 0xfL;
-unsigned long s3c_irqwake_eintallow	= 0x0000fff0L;
-
-int s3c_irq_wake(struct irq_data *data, unsigned int state)
-{
-	unsigned long irqbit = 1 << (data->irq - IRQ_EINT0);
-
-	if (!(s3c_irqwake_intallow & irqbit))
-		return -ENOENT;
-
-	printk(KERN_INFO "wake %s for irq %d\n",
-	       state ? "enabled" : "disabled", data->irq);
-
-	if (!state)
-		s3c_irqwake_intmask |= irqbit;
-	else
-		s3c_irqwake_intmask &= ~irqbit;
-
-	return 0;
-}
-
-static struct sleep_save irq_save[] = {
-	SAVE_ITEM(S3C2410_INTMSK),
-	SAVE_ITEM(S3C2410_INTSUBMSK),
-};
-
-/* the extint values move between the s3c2410/s3c2440 and the s3c2412
- * so we use an array to hold them, and to calculate the address of
- * the register at run-time
-*/
-
-static unsigned long save_extint[3];
-static unsigned long save_eintflt[4];
-static unsigned long save_eintmask;
-
-int s3c24xx_irq_suspend(void)
-{
-	unsigned int i;
-
-	for (i = 0; i < ARRAY_SIZE(save_extint); i++)
-		save_extint[i] = __raw_readl(S3C24XX_EXTINT0 + (i*4));
-
-	for (i = 0; i < ARRAY_SIZE(save_eintflt); i++)
-		save_eintflt[i] = __raw_readl(S3C24XX_EINFLT0 + (i*4));
-
-	s3c_pm_do_save(irq_save, ARRAY_SIZE(irq_save));
-	save_eintmask = __raw_readl(S3C24XX_EINTMASK);
-
-	return 0;
-}
-
-void s3c24xx_irq_resume(void)
-{
-	unsigned int i;
-
-	for (i = 0; i < ARRAY_SIZE(save_extint); i++)
-		__raw_writel(save_extint[i], S3C24XX_EXTINT0 + (i*4));
-
-	for (i = 0; i < ARRAY_SIZE(save_eintflt); i++)
-		__raw_writel(save_eintflt[i], S3C24XX_EINFLT0 + (i*4));
-
-	s3c_pm_do_restore(irq_save, ARRAY_SIZE(irq_save));
-	__raw_writel(save_eintmask, S3C24XX_EINTMASK);
-}
diff --git a/arch/arm/plat-s3c24xx/irq.c b/arch/arm/plat-s3c24xx/irq.c
index 2706816..7ce4f84 100644
--- a/arch/arm/plat-s3c24xx/irq.c
+++ b/arch/arm/plat-s3c24xx/irq.c
@@ -118,6 +118,36 @@ static inline void s3c_irq_maskack(struct irq_data *data)
 	s3c_irq_ack(data);
 }
 
+#ifdef CONFIG_PM
+/* state for IRQs over sleep */
+
+/* default is to allow for EINT0..EINT15, and IRQ_RTC as wakeup sources
+ *
+ * set bit to 1 in allow bitfield to enable the wakeup settings on it
+*/
+
+unsigned long s3c_irqwake_intallow	= 1L << (IRQ_RTC - IRQ_EINT0) | 0xfL;
+unsigned long s3c_irqwake_eintallow	= 0x0000fff0L;
+
+int s3c_irq_wake(struct irq_data *data, unsigned int state)
+{
+	unsigned long irqbit = 1 << (data->irq - IRQ_EINT0);
+
+	if (!(s3c_irqwake_intallow & irqbit))
+		return -ENOENT;
+
+	printk(KERN_INFO "wake %s for irq %d\n",
+	       state ? "enabled" : "disabled", data->irq);
+
+	if (!state)
+		s3c_irqwake_intmask |= irqbit;
+	else
+		s3c_irqwake_intmask &= ~irqbit;
+
+	return 0;
+}
+#endif
+
 struct irq_chip s3c_irq_level_chip = {
 	.name		= "s3c-level",
 	.irq_ack	= s3c_irq_maskack,
@@ -681,6 +711,52 @@ void __init s3c24xx_init_irq(void)
 					       &s3c24xx_irq_ops, &s3c_intc[2]);
 }
 
+#ifdef CONFIG_PM
+static struct sleep_save irq_save[] = {
+	SAVE_ITEM(S3C2410_INTMSK),
+	SAVE_ITEM(S3C2410_INTSUBMSK),
+};
+
+/* the extint values move between the s3c2410/s3c2440 and the s3c2412
+ * so we use an array to hold them, and to calculate the address of
+ * the register at run-time
+*/
+
+static unsigned long save_extint[3];
+static unsigned long save_eintflt[4];
+static unsigned long save_eintmask;
+
+int s3c24xx_irq_suspend(void)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(save_extint); i++)
+		save_extint[i] = __raw_readl(S3C24XX_EXTINT0 + (i*4));
+
+	for (i = 0; i < ARRAY_SIZE(save_eintflt); i++)
+		save_eintflt[i] = __raw_readl(S3C24XX_EINFLT0 + (i*4));
+
+	s3c_pm_do_save(irq_save, ARRAY_SIZE(irq_save));
+	save_eintmask = __raw_readl(S3C24XX_EINTMASK);
+
+	return 0;
+}
+
+void s3c24xx_irq_resume(void)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(save_extint); i++)
+		__raw_writel(save_extint[i], S3C24XX_EXTINT0 + (i*4));
+
+	for (i = 0; i < ARRAY_SIZE(save_eintflt); i++)
+		__raw_writel(save_eintflt[i], S3C24XX_EINFLT0 + (i*4));
+
+	s3c_pm_do_restore(irq_save, ARRAY_SIZE(irq_save));
+	__raw_writel(save_eintmask, S3C24XX_EINTMASK);
+}
+#endif
+
 struct syscore_ops s3c24xx_irq_syscore_ops = {
 	.suspend	= s3c24xx_irq_suspend,
 	.resume		= s3c24xx_irq_resume,
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 02/10] ARM: S3C24XX: move irq-pm code into main irq file
@ 2012-11-18  0:52   ` Heiko Stübner
  0 siblings, 0 replies; 24+ messages in thread
From: Heiko Stübner @ 2012-11-18  0:52 UTC (permalink / raw)
  To: linux-arm-kernel

With this change, it's possible to make more elements static
and also reduce the number of .h elements further down the road.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
 arch/arm/mach-s3c24xx/Makefile |    2 +-
 arch/arm/mach-s3c24xx/irq-pm.c |   95 ----------------------------------------
 arch/arm/plat-s3c24xx/irq.c    |   76 ++++++++++++++++++++++++++++++++
 3 files changed, 77 insertions(+), 96 deletions(-)
 delete mode 100644 arch/arm/mach-s3c24xx/irq-pm.c

diff --git a/arch/arm/mach-s3c24xx/Makefile b/arch/arm/mach-s3c24xx/Makefile
index 0ab6ab1..3e1d12c 100644
--- a/arch/arm/mach-s3c24xx/Makefile
+++ b/arch/arm/mach-s3c24xx/Makefile
@@ -37,7 +37,7 @@ obj-$(CONFIG_CPU_S3C2443)	+= s3c2443.o irq-s3c2443.o clock-s3c2443.o
 
 # PM
 
-obj-$(CONFIG_PM)		+= pm.o irq-pm.o sleep.o
+obj-$(CONFIG_PM)		+= pm.o sleep.o
 
 # common code
 
diff --git a/arch/arm/mach-s3c24xx/irq-pm.c b/arch/arm/mach-s3c24xx/irq-pm.c
deleted file mode 100644
index 0efb2e2..0000000
--- a/arch/arm/mach-s3c24xx/irq-pm.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/* linux/arch/arm/plat-s3c24xx/irq-om.c
- *
- * Copyright (c) 2003-2004 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *	http://armlinux.simtec.co.uk/
- *
- * S3C24XX - IRQ PM code
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-
-#include <plat/cpu.h>
-#include <plat/pm.h>
-#include <plat/irq.h>
-
-#include <asm/irq.h>
-
-/* state for IRQs over sleep */
-
-/* default is to allow for EINT0..EINT15, and IRQ_RTC as wakeup sources
- *
- * set bit to 1 in allow bitfield to enable the wakeup settings on it
-*/
-
-unsigned long s3c_irqwake_intallow	= 1L << (IRQ_RTC - IRQ_EINT0) | 0xfL;
-unsigned long s3c_irqwake_eintallow	= 0x0000fff0L;
-
-int s3c_irq_wake(struct irq_data *data, unsigned int state)
-{
-	unsigned long irqbit = 1 << (data->irq - IRQ_EINT0);
-
-	if (!(s3c_irqwake_intallow & irqbit))
-		return -ENOENT;
-
-	printk(KERN_INFO "wake %s for irq %d\n",
-	       state ? "enabled" : "disabled", data->irq);
-
-	if (!state)
-		s3c_irqwake_intmask |= irqbit;
-	else
-		s3c_irqwake_intmask &= ~irqbit;
-
-	return 0;
-}
-
-static struct sleep_save irq_save[] = {
-	SAVE_ITEM(S3C2410_INTMSK),
-	SAVE_ITEM(S3C2410_INTSUBMSK),
-};
-
-/* the extint values move between the s3c2410/s3c2440 and the s3c2412
- * so we use an array to hold them, and to calculate the address of
- * the register at run-time
-*/
-
-static unsigned long save_extint[3];
-static unsigned long save_eintflt[4];
-static unsigned long save_eintmask;
-
-int s3c24xx_irq_suspend(void)
-{
-	unsigned int i;
-
-	for (i = 0; i < ARRAY_SIZE(save_extint); i++)
-		save_extint[i] = __raw_readl(S3C24XX_EXTINT0 + (i*4));
-
-	for (i = 0; i < ARRAY_SIZE(save_eintflt); i++)
-		save_eintflt[i] = __raw_readl(S3C24XX_EINFLT0 + (i*4));
-
-	s3c_pm_do_save(irq_save, ARRAY_SIZE(irq_save));
-	save_eintmask = __raw_readl(S3C24XX_EINTMASK);
-
-	return 0;
-}
-
-void s3c24xx_irq_resume(void)
-{
-	unsigned int i;
-
-	for (i = 0; i < ARRAY_SIZE(save_extint); i++)
-		__raw_writel(save_extint[i], S3C24XX_EXTINT0 + (i*4));
-
-	for (i = 0; i < ARRAY_SIZE(save_eintflt); i++)
-		__raw_writel(save_eintflt[i], S3C24XX_EINFLT0 + (i*4));
-
-	s3c_pm_do_restore(irq_save, ARRAY_SIZE(irq_save));
-	__raw_writel(save_eintmask, S3C24XX_EINTMASK);
-}
diff --git a/arch/arm/plat-s3c24xx/irq.c b/arch/arm/plat-s3c24xx/irq.c
index 2706816..7ce4f84 100644
--- a/arch/arm/plat-s3c24xx/irq.c
+++ b/arch/arm/plat-s3c24xx/irq.c
@@ -118,6 +118,36 @@ static inline void s3c_irq_maskack(struct irq_data *data)
 	s3c_irq_ack(data);
 }
 
+#ifdef CONFIG_PM
+/* state for IRQs over sleep */
+
+/* default is to allow for EINT0..EINT15, and IRQ_RTC as wakeup sources
+ *
+ * set bit to 1 in allow bitfield to enable the wakeup settings on it
+*/
+
+unsigned long s3c_irqwake_intallow	= 1L << (IRQ_RTC - IRQ_EINT0) | 0xfL;
+unsigned long s3c_irqwake_eintallow	= 0x0000fff0L;
+
+int s3c_irq_wake(struct irq_data *data, unsigned int state)
+{
+	unsigned long irqbit = 1 << (data->irq - IRQ_EINT0);
+
+	if (!(s3c_irqwake_intallow & irqbit))
+		return -ENOENT;
+
+	printk(KERN_INFO "wake %s for irq %d\n",
+	       state ? "enabled" : "disabled", data->irq);
+
+	if (!state)
+		s3c_irqwake_intmask |= irqbit;
+	else
+		s3c_irqwake_intmask &= ~irqbit;
+
+	return 0;
+}
+#endif
+
 struct irq_chip s3c_irq_level_chip = {
 	.name		= "s3c-level",
 	.irq_ack	= s3c_irq_maskack,
@@ -681,6 +711,52 @@ void __init s3c24xx_init_irq(void)
 					       &s3c24xx_irq_ops, &s3c_intc[2]);
 }
 
+#ifdef CONFIG_PM
+static struct sleep_save irq_save[] = {
+	SAVE_ITEM(S3C2410_INTMSK),
+	SAVE_ITEM(S3C2410_INTSUBMSK),
+};
+
+/* the extint values move between the s3c2410/s3c2440 and the s3c2412
+ * so we use an array to hold them, and to calculate the address of
+ * the register at run-time
+*/
+
+static unsigned long save_extint[3];
+static unsigned long save_eintflt[4];
+static unsigned long save_eintmask;
+
+int s3c24xx_irq_suspend(void)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(save_extint); i++)
+		save_extint[i] = __raw_readl(S3C24XX_EXTINT0 + (i*4));
+
+	for (i = 0; i < ARRAY_SIZE(save_eintflt); i++)
+		save_eintflt[i] = __raw_readl(S3C24XX_EINFLT0 + (i*4));
+
+	s3c_pm_do_save(irq_save, ARRAY_SIZE(irq_save));
+	save_eintmask = __raw_readl(S3C24XX_EINTMASK);
+
+	return 0;
+}
+
+void s3c24xx_irq_resume(void)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(save_extint); i++)
+		__raw_writel(save_extint[i], S3C24XX_EXTINT0 + (i*4));
+
+	for (i = 0; i < ARRAY_SIZE(save_eintflt); i++)
+		__raw_writel(save_eintflt[i], S3C24XX_EINFLT0 + (i*4));
+
+	s3c_pm_do_restore(irq_save, ARRAY_SIZE(irq_save));
+	__raw_writel(save_eintmask, S3C24XX_EINTMASK);
+}
+#endif
+
 struct syscore_ops s3c24xx_irq_syscore_ops = {
 	.suspend	= s3c24xx_irq_suspend,
 	.resume		= s3c24xx_irq_resume,
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 03/10] ARM: S3C24XX: cleanup irq-pm integration
  2012-11-18  0:51 ` Heiko Stübner
@ 2012-11-18  0:53   ` Heiko Stübner
  -1 siblings, 0 replies; 24+ messages in thread
From: Heiko Stübner @ 2012-11-18  0:53 UTC (permalink / raw)
  To: Kukjin Kim; +Cc: Ben Dooks, linux-arm-kernel, linux-samsung-soc

This patch integrates the irq-pm functions we moved in the previous patch.
This includes some static attributes and the removal of the irq suspend
and resume declaratons from the plat-samsung/pm.h header.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
 arch/arm/mach-s3c24xx/common.h          |    2 ++
 arch/arm/mach-s3c24xx/s3c2410.c         |    4 +++-
 arch/arm/mach-s3c24xx/s3c2412.c         |    4 +++-
 arch/arm/mach-s3c24xx/s3c2416.c         |    4 +++-
 arch/arm/mach-s3c24xx/s3c2440.c         |    4 +++-
 arch/arm/mach-s3c24xx/s3c2442.c         |    4 +++-
 arch/arm/plat-s3c24xx/irq.c             |   22 +++++++++++-----------
 arch/arm/plat-samsung/include/plat/pm.h |    6 ------
 8 files changed, 28 insertions(+), 22 deletions(-)

diff --git a/arch/arm/mach-s3c24xx/common.h b/arch/arm/mach-s3c24xx/common.h
index c2f596e..ed6276f 100644
--- a/arch/arm/mach-s3c24xx/common.h
+++ b/arch/arm/mach-s3c24xx/common.h
@@ -15,4 +15,6 @@
 void s3c2410_restart(char mode, const char *cmd);
 void s3c244x_restart(char mode, const char *cmd);
 
+extern struct syscore_ops s3c24xx_irq_syscore_ops;
+
 #endif /* __ARCH_ARM_MACH_S3C24XX_COMMON_H */
diff --git a/arch/arm/mach-s3c24xx/s3c2410.c b/arch/arm/mach-s3c24xx/s3c2410.c
index a3c5cb0..9ebef95 100644
--- a/arch/arm/mach-s3c24xx/s3c2410.c
+++ b/arch/arm/mach-s3c24xx/s3c2410.c
@@ -49,6 +49,8 @@
 #include <plat/gpio-cfg.h>
 #include <plat/gpio-cfg-helpers.h>
 
+#include "common.h"
+
 /* Initial IO mappings */
 
 static struct map_desc s3c2410_iodesc[] __initdata = {
@@ -182,8 +184,8 @@ int __init s3c2410_init(void)
 
 #ifdef CONFIG_PM
 	register_syscore_ops(&s3c2410_pm_syscore_ops);
-#endif
 	register_syscore_ops(&s3c24xx_irq_syscore_ops);
+#endif
 
 	return device_register(&s3c2410_dev);
 }
diff --git a/arch/arm/mach-s3c24xx/s3c2412.c b/arch/arm/mach-s3c24xx/s3c2412.c
index 6c5f403..0ec08bd 100644
--- a/arch/arm/mach-s3c24xx/s3c2412.c
+++ b/arch/arm/mach-s3c24xx/s3c2412.c
@@ -51,6 +51,8 @@
 #include <plat/pll.h>
 #include <plat/nand-core.h>
 
+#include "common.h"
+
 #ifndef CONFIG_CPU_S3C2412_ONLY
 void __iomem *s3c24xx_va_gpio2 = S3C24XX_VA_GPIO;
 
@@ -244,8 +246,8 @@ int __init s3c2412_init(void)
 
 #ifdef CONFIG_PM
 	register_syscore_ops(&s3c2412_pm_syscore_ops);
-#endif
 	register_syscore_ops(&s3c24xx_irq_syscore_ops);
+#endif
 
 	return device_register(&s3c2412_dev);
 }
diff --git a/arch/arm/mach-s3c24xx/s3c2416.c b/arch/arm/mach-s3c24xx/s3c2416.c
index 77ee0b7..e30476d 100644
--- a/arch/arm/mach-s3c24xx/s3c2416.c
+++ b/arch/arm/mach-s3c24xx/s3c2416.c
@@ -63,6 +63,8 @@
 #include <plat/rtc-core.h>
 #include <plat/spi-core.h>
 
+#include "common.h"
+
 static struct map_desc s3c2416_iodesc[] __initdata = {
 	IODESC_ENT(WATCHDOG),
 	IODESC_ENT(CLKPWR),
@@ -105,9 +107,9 @@ int __init s3c2416_init(void)
 
 #ifdef CONFIG_PM
 	register_syscore_ops(&s3c2416_pm_syscore_ops);
-#endif
 	register_syscore_ops(&s3c24xx_irq_syscore_ops);
 	register_syscore_ops(&s3c2416_irq_syscore_ops);
+#endif
 
 	return device_register(&s3c2416_dev);
 }
diff --git a/arch/arm/mach-s3c24xx/s3c2440.c b/arch/arm/mach-s3c24xx/s3c2440.c
index 2b3dddb..559e394 100644
--- a/arch/arm/mach-s3c24xx/s3c2440.c
+++ b/arch/arm/mach-s3c24xx/s3c2440.c
@@ -40,6 +40,8 @@
 #include <plat/gpio-cfg.h>
 #include <plat/gpio-cfg-helpers.h>
 
+#include "common.h"
+
 static struct device s3c2440_dev = {
 	.bus		= &s3c2440_subsys,
 };
@@ -57,9 +59,9 @@ int __init s3c2440_init(void)
 
 #ifdef CONFIG_PM
 	register_syscore_ops(&s3c2410_pm_syscore_ops);
+	register_syscore_ops(&s3c24xx_irq_syscore_ops);
 #endif
 	register_syscore_ops(&s3c244x_pm_syscore_ops);
-	register_syscore_ops(&s3c24xx_irq_syscore_ops);
 
 	/* register our system device for everything else */
 
diff --git a/arch/arm/mach-s3c24xx/s3c2442.c b/arch/arm/mach-s3c24xx/s3c2442.c
index 22cb7c9..f732826 100644
--- a/arch/arm/mach-s3c24xx/s3c2442.c
+++ b/arch/arm/mach-s3c24xx/s3c2442.c
@@ -51,6 +51,8 @@
 #include <plat/gpio-cfg.h>
 #include <plat/gpio-cfg-helpers.h>
 
+#include "common.h"
+
 /* S3C2442 extended clock support */
 
 static unsigned long s3c2442_camif_upll_round(struct clk *clk,
@@ -172,9 +174,9 @@ int __init s3c2442_init(void)
 
 #ifdef CONFIG_PM
 	register_syscore_ops(&s3c2410_pm_syscore_ops);
+	register_syscore_ops(&s3c24xx_irq_syscore_ops);
 #endif
 	register_syscore_ops(&s3c244x_pm_syscore_ops);
-	register_syscore_ops(&s3c24xx_irq_syscore_ops);
 
 	return device_register(&s3c2442_dev);
 }
diff --git a/arch/arm/plat-s3c24xx/irq.c b/arch/arm/plat-s3c24xx/irq.c
index 7ce4f84..bac8053 100644
--- a/arch/arm/plat-s3c24xx/irq.c
+++ b/arch/arm/plat-s3c24xx/irq.c
@@ -119,25 +119,25 @@ static inline void s3c_irq_maskack(struct irq_data *data)
 }
 
 #ifdef CONFIG_PM
-/* state for IRQs over sleep */
-
-/* default is to allow for EINT0..EINT15, and IRQ_RTC as wakeup sources
+/* state for IRQs over sleep
  *
+ * default is to allow for EINT0..EINT15, and IRQ_RTC as wakeup sources
  * set bit to 1 in allow bitfield to enable the wakeup settings on it
-*/
+ */
 
-unsigned long s3c_irqwake_intallow	= 1L << (IRQ_RTC - IRQ_EINT0) | 0xfL;
+unsigned long s3c_irqwake_intallow	= 1L << 30 | 0xfL;
 unsigned long s3c_irqwake_eintallow	= 0x0000fff0L;
 
+/* FIXME: must not be static until s3c2412 irqs are included */
 int s3c_irq_wake(struct irq_data *data, unsigned int state)
 {
-	unsigned long irqbit = 1 << (data->irq - IRQ_EINT0);
+	unsigned long irqbit = 1 << data->hwirq;
 
 	if (!(s3c_irqwake_intallow & irqbit))
 		return -ENOENT;
 
-	printk(KERN_INFO "wake %s for irq %d\n",
-	       state ? "enabled" : "disabled", data->irq);
+	pr_info("wake %s for hwirq %lu\n",
+		state ? "enabled" : "disabled", data->hwirq);
 
 	if (!state)
 		s3c_irqwake_intmask |= irqbit;
@@ -726,7 +726,7 @@ static unsigned long save_extint[3];
 static unsigned long save_eintflt[4];
 static unsigned long save_eintmask;
 
-int s3c24xx_irq_suspend(void)
+static int s3c24xx_irq_suspend(void)
 {
 	unsigned int i;
 
@@ -742,7 +742,7 @@ int s3c24xx_irq_suspend(void)
 	return 0;
 }
 
-void s3c24xx_irq_resume(void)
+static void s3c24xx_irq_resume(void)
 {
 	unsigned int i;
 
@@ -755,9 +755,9 @@ void s3c24xx_irq_resume(void)
 	s3c_pm_do_restore(irq_save, ARRAY_SIZE(irq_save));
 	__raw_writel(save_eintmask, S3C24XX_EINTMASK);
 }
-#endif
 
 struct syscore_ops s3c24xx_irq_syscore_ops = {
 	.suspend	= s3c24xx_irq_suspend,
 	.resume		= s3c24xx_irq_resume,
 };
+#endif
diff --git a/arch/arm/plat-samsung/include/plat/pm.h b/arch/arm/plat-samsung/include/plat/pm.h
index 61fc537..b86dcca 100644
--- a/arch/arm/plat-samsung/include/plat/pm.h
+++ b/arch/arm/plat-samsung/include/plat/pm.h
@@ -108,16 +108,10 @@ extern void s3c_pm_do_restore_core(struct sleep_save *ptr, int count);
 
 #ifdef CONFIG_PM
 extern int s3c_irqext_wake(struct irq_data *data, unsigned int state);
-extern int s3c24xx_irq_suspend(void);
-extern void s3c24xx_irq_resume(void);
 #else
 #define s3c_irqext_wake NULL
-#define s3c24xx_irq_suspend NULL
-#define s3c24xx_irq_resume  NULL
 #endif
 
-extern struct syscore_ops s3c24xx_irq_syscore_ops;
-
 /* PM debug functions */
 
 #ifdef CONFIG_SAMSUNG_PM_DEBUG
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 03/10] ARM: S3C24XX: cleanup irq-pm integration
@ 2012-11-18  0:53   ` Heiko Stübner
  0 siblings, 0 replies; 24+ messages in thread
From: Heiko Stübner @ 2012-11-18  0:53 UTC (permalink / raw)
  To: linux-arm-kernel

This patch integrates the irq-pm functions we moved in the previous patch.
This includes some static attributes and the removal of the irq suspend
and resume declaratons from the plat-samsung/pm.h header.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
 arch/arm/mach-s3c24xx/common.h          |    2 ++
 arch/arm/mach-s3c24xx/s3c2410.c         |    4 +++-
 arch/arm/mach-s3c24xx/s3c2412.c         |    4 +++-
 arch/arm/mach-s3c24xx/s3c2416.c         |    4 +++-
 arch/arm/mach-s3c24xx/s3c2440.c         |    4 +++-
 arch/arm/mach-s3c24xx/s3c2442.c         |    4 +++-
 arch/arm/plat-s3c24xx/irq.c             |   22 +++++++++++-----------
 arch/arm/plat-samsung/include/plat/pm.h |    6 ------
 8 files changed, 28 insertions(+), 22 deletions(-)

diff --git a/arch/arm/mach-s3c24xx/common.h b/arch/arm/mach-s3c24xx/common.h
index c2f596e..ed6276f 100644
--- a/arch/arm/mach-s3c24xx/common.h
+++ b/arch/arm/mach-s3c24xx/common.h
@@ -15,4 +15,6 @@
 void s3c2410_restart(char mode, const char *cmd);
 void s3c244x_restart(char mode, const char *cmd);
 
+extern struct syscore_ops s3c24xx_irq_syscore_ops;
+
 #endif /* __ARCH_ARM_MACH_S3C24XX_COMMON_H */
diff --git a/arch/arm/mach-s3c24xx/s3c2410.c b/arch/arm/mach-s3c24xx/s3c2410.c
index a3c5cb0..9ebef95 100644
--- a/arch/arm/mach-s3c24xx/s3c2410.c
+++ b/arch/arm/mach-s3c24xx/s3c2410.c
@@ -49,6 +49,8 @@
 #include <plat/gpio-cfg.h>
 #include <plat/gpio-cfg-helpers.h>
 
+#include "common.h"
+
 /* Initial IO mappings */
 
 static struct map_desc s3c2410_iodesc[] __initdata = {
@@ -182,8 +184,8 @@ int __init s3c2410_init(void)
 
 #ifdef CONFIG_PM
 	register_syscore_ops(&s3c2410_pm_syscore_ops);
-#endif
 	register_syscore_ops(&s3c24xx_irq_syscore_ops);
+#endif
 
 	return device_register(&s3c2410_dev);
 }
diff --git a/arch/arm/mach-s3c24xx/s3c2412.c b/arch/arm/mach-s3c24xx/s3c2412.c
index 6c5f403..0ec08bd 100644
--- a/arch/arm/mach-s3c24xx/s3c2412.c
+++ b/arch/arm/mach-s3c24xx/s3c2412.c
@@ -51,6 +51,8 @@
 #include <plat/pll.h>
 #include <plat/nand-core.h>
 
+#include "common.h"
+
 #ifndef CONFIG_CPU_S3C2412_ONLY
 void __iomem *s3c24xx_va_gpio2 = S3C24XX_VA_GPIO;
 
@@ -244,8 +246,8 @@ int __init s3c2412_init(void)
 
 #ifdef CONFIG_PM
 	register_syscore_ops(&s3c2412_pm_syscore_ops);
-#endif
 	register_syscore_ops(&s3c24xx_irq_syscore_ops);
+#endif
 
 	return device_register(&s3c2412_dev);
 }
diff --git a/arch/arm/mach-s3c24xx/s3c2416.c b/arch/arm/mach-s3c24xx/s3c2416.c
index 77ee0b7..e30476d 100644
--- a/arch/arm/mach-s3c24xx/s3c2416.c
+++ b/arch/arm/mach-s3c24xx/s3c2416.c
@@ -63,6 +63,8 @@
 #include <plat/rtc-core.h>
 #include <plat/spi-core.h>
 
+#include "common.h"
+
 static struct map_desc s3c2416_iodesc[] __initdata = {
 	IODESC_ENT(WATCHDOG),
 	IODESC_ENT(CLKPWR),
@@ -105,9 +107,9 @@ int __init s3c2416_init(void)
 
 #ifdef CONFIG_PM
 	register_syscore_ops(&s3c2416_pm_syscore_ops);
-#endif
 	register_syscore_ops(&s3c24xx_irq_syscore_ops);
 	register_syscore_ops(&s3c2416_irq_syscore_ops);
+#endif
 
 	return device_register(&s3c2416_dev);
 }
diff --git a/arch/arm/mach-s3c24xx/s3c2440.c b/arch/arm/mach-s3c24xx/s3c2440.c
index 2b3dddb..559e394 100644
--- a/arch/arm/mach-s3c24xx/s3c2440.c
+++ b/arch/arm/mach-s3c24xx/s3c2440.c
@@ -40,6 +40,8 @@
 #include <plat/gpio-cfg.h>
 #include <plat/gpio-cfg-helpers.h>
 
+#include "common.h"
+
 static struct device s3c2440_dev = {
 	.bus		= &s3c2440_subsys,
 };
@@ -57,9 +59,9 @@ int __init s3c2440_init(void)
 
 #ifdef CONFIG_PM
 	register_syscore_ops(&s3c2410_pm_syscore_ops);
+	register_syscore_ops(&s3c24xx_irq_syscore_ops);
 #endif
 	register_syscore_ops(&s3c244x_pm_syscore_ops);
-	register_syscore_ops(&s3c24xx_irq_syscore_ops);
 
 	/* register our system device for everything else */
 
diff --git a/arch/arm/mach-s3c24xx/s3c2442.c b/arch/arm/mach-s3c24xx/s3c2442.c
index 22cb7c9..f732826 100644
--- a/arch/arm/mach-s3c24xx/s3c2442.c
+++ b/arch/arm/mach-s3c24xx/s3c2442.c
@@ -51,6 +51,8 @@
 #include <plat/gpio-cfg.h>
 #include <plat/gpio-cfg-helpers.h>
 
+#include "common.h"
+
 /* S3C2442 extended clock support */
 
 static unsigned long s3c2442_camif_upll_round(struct clk *clk,
@@ -172,9 +174,9 @@ int __init s3c2442_init(void)
 
 #ifdef CONFIG_PM
 	register_syscore_ops(&s3c2410_pm_syscore_ops);
+	register_syscore_ops(&s3c24xx_irq_syscore_ops);
 #endif
 	register_syscore_ops(&s3c244x_pm_syscore_ops);
-	register_syscore_ops(&s3c24xx_irq_syscore_ops);
 
 	return device_register(&s3c2442_dev);
 }
diff --git a/arch/arm/plat-s3c24xx/irq.c b/arch/arm/plat-s3c24xx/irq.c
index 7ce4f84..bac8053 100644
--- a/arch/arm/plat-s3c24xx/irq.c
+++ b/arch/arm/plat-s3c24xx/irq.c
@@ -119,25 +119,25 @@ static inline void s3c_irq_maskack(struct irq_data *data)
 }
 
 #ifdef CONFIG_PM
-/* state for IRQs over sleep */
-
-/* default is to allow for EINT0..EINT15, and IRQ_RTC as wakeup sources
+/* state for IRQs over sleep
  *
+ * default is to allow for EINT0..EINT15, and IRQ_RTC as wakeup sources
  * set bit to 1 in allow bitfield to enable the wakeup settings on it
-*/
+ */
 
-unsigned long s3c_irqwake_intallow	= 1L << (IRQ_RTC - IRQ_EINT0) | 0xfL;
+unsigned long s3c_irqwake_intallow	= 1L << 30 | 0xfL;
 unsigned long s3c_irqwake_eintallow	= 0x0000fff0L;
 
+/* FIXME: must not be static until s3c2412 irqs are included */
 int s3c_irq_wake(struct irq_data *data, unsigned int state)
 {
-	unsigned long irqbit = 1 << (data->irq - IRQ_EINT0);
+	unsigned long irqbit = 1 << data->hwirq;
 
 	if (!(s3c_irqwake_intallow & irqbit))
 		return -ENOENT;
 
-	printk(KERN_INFO "wake %s for irq %d\n",
-	       state ? "enabled" : "disabled", data->irq);
+	pr_info("wake %s for hwirq %lu\n",
+		state ? "enabled" : "disabled", data->hwirq);
 
 	if (!state)
 		s3c_irqwake_intmask |= irqbit;
@@ -726,7 +726,7 @@ static unsigned long save_extint[3];
 static unsigned long save_eintflt[4];
 static unsigned long save_eintmask;
 
-int s3c24xx_irq_suspend(void)
+static int s3c24xx_irq_suspend(void)
 {
 	unsigned int i;
 
@@ -742,7 +742,7 @@ int s3c24xx_irq_suspend(void)
 	return 0;
 }
 
-void s3c24xx_irq_resume(void)
+static void s3c24xx_irq_resume(void)
 {
 	unsigned int i;
 
@@ -755,9 +755,9 @@ void s3c24xx_irq_resume(void)
 	s3c_pm_do_restore(irq_save, ARRAY_SIZE(irq_save));
 	__raw_writel(save_eintmask, S3C24XX_EINTMASK);
 }
-#endif
 
 struct syscore_ops s3c24xx_irq_syscore_ops = {
 	.suspend	= s3c24xx_irq_suspend,
 	.resume		= s3c24xx_irq_resume,
 };
+#endif
diff --git a/arch/arm/plat-samsung/include/plat/pm.h b/arch/arm/plat-samsung/include/plat/pm.h
index 61fc537..b86dcca 100644
--- a/arch/arm/plat-samsung/include/plat/pm.h
+++ b/arch/arm/plat-samsung/include/plat/pm.h
@@ -108,16 +108,10 @@ extern void s3c_pm_do_restore_core(struct sleep_save *ptr, int count);
 
 #ifdef CONFIG_PM
 extern int s3c_irqext_wake(struct irq_data *data, unsigned int state);
-extern int s3c24xx_irq_suspend(void);
-extern void s3c24xx_irq_resume(void);
 #else
 #define s3c_irqext_wake NULL
-#define s3c24xx_irq_suspend NULL
-#define s3c24xx_irq_resume  NULL
 #endif
 
-extern struct syscore_ops s3c24xx_irq_syscore_ops;
-
 /* PM debug functions */
 
 #ifdef CONFIG_SAMSUNG_PM_DEBUG
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 04/10] ARM: S3C24XX: move s3c2416 irq init to common irq code
  2012-11-18  0:51 ` Heiko Stübner
@ 2012-11-18  0:54   ` Heiko Stübner
  -1 siblings, 0 replies; 24+ messages in thread
From: Heiko Stübner @ 2012-11-18  0:54 UTC (permalink / raw)
  To: Kukjin Kim; +Cc: Ben Dooks, linux-arm-kernel, linux-samsung-soc

This is needed to further clean up the irq init.
The only change made during the move is the renaming of the
possibly conflicting irq_save to irq2_save

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
 arch/arm/mach-s3c24xx/Makefile      |    2 +-
 arch/arm/mach-s3c24xx/irq-s3c2416.c |  348 -----------------------------------
 arch/arm/plat-s3c24xx/irq.c         |  309 +++++++++++++++++++++++++++++++
 3 files changed, 310 insertions(+), 349 deletions(-)
 delete mode 100644 arch/arm/mach-s3c24xx/irq-s3c2416.c

diff --git a/arch/arm/mach-s3c24xx/Makefile b/arch/arm/mach-s3c24xx/Makefile
index 3e1d12c..30904c9 100644
--- a/arch/arm/mach-s3c24xx/Makefile
+++ b/arch/arm/mach-s3c24xx/Makefile
@@ -25,7 +25,7 @@ obj-$(CONFIG_S3C2412_DMA)	+= dma-s3c2412.o
 obj-$(CONFIG_S3C2412_PM)	+= pm-s3c2412.o
 obj-$(CONFIG_S3C2412_PM_SLEEP)	+= sleep-s3c2412.o
 
-obj-$(CONFIG_CPU_S3C2416)	+= s3c2416.o irq-s3c2416.o clock-s3c2416.o
+obj-$(CONFIG_CPU_S3C2416)	+= s3c2416.o clock-s3c2416.o
 obj-$(CONFIG_S3C2416_PM)	+= pm-s3c2416.o
 
 obj-$(CONFIG_CPU_S3C2440)	+= s3c2440.o irq-s3c2440.o clock-s3c2440.o
diff --git a/arch/arm/mach-s3c24xx/irq-s3c2416.c b/arch/arm/mach-s3c24xx/irq-s3c2416.c
deleted file mode 100644
index ff141b0..0000000
--- a/arch/arm/mach-s3c24xx/irq-s3c2416.c
+++ /dev/null
@@ -1,348 +0,0 @@
-/* linux/arch/arm/mach-s3c2416/irq.c
- *
- * Copyright (c) 2009 Yauhen Kharuzhy <jekhor@gmail.com>,
- *	as part of OpenInkpot project
- * Copyright (c) 2009 Promwad Innovation Company
- *	Yauhen Kharuzhy <yauhen.kharuzhy@promwad.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
-*/
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/device.h>
-#include <linux/io.h>
-#include <linux/syscore_ops.h>
-
-#include <mach/hardware.h>
-#include <asm/irq.h>
-
-#include <asm/mach/irq.h>
-
-#include <mach/regs-irq.h>
-#include <mach/regs-gpio.h>
-
-#include <plat/cpu.h>
-#include <plat/pm.h>
-#include <plat/irq.h>
-
-#define INTMSK(start, end) ((1 << ((end) + 1 - (start))) - 1)
-
-static inline void s3c2416_irq_demux(unsigned int irq, unsigned int len)
-{
-	unsigned int subsrc, submsk;
-	unsigned int end;
-
-	/* read the current pending interrupts, and the mask
-	 * for what it is available */
-
-	subsrc = __raw_readl(S3C2410_SUBSRCPND);
-	submsk = __raw_readl(S3C2410_INTSUBMSK);
-
-	subsrc  &= ~submsk;
-	subsrc >>= (irq - S3C2410_IRQSUB(0));
-	subsrc  &= (1 << len)-1;
-
-	end = len + irq;
-
-	for (; irq < end && subsrc; irq++) {
-		if (subsrc & 1)
-			generic_handle_irq(irq);
-
-		subsrc >>= 1;
-	}
-}
-
-/* WDT/AC97 sub interrupts */
-
-static void s3c2416_irq_demux_wdtac97(unsigned int irq, struct irq_desc *desc)
-{
-	s3c2416_irq_demux(IRQ_S3C2443_WDT, 4);
-}
-
-#define INTMSK_WDTAC97	(1UL << (IRQ_WDT - IRQ_EINT0))
-#define SUBMSK_WDTAC97	INTMSK(IRQ_S3C2443_WDT, IRQ_S3C2443_AC97)
-
-static void s3c2416_irq_wdtac97_mask(struct irq_data *data)
-{
-	s3c_irqsub_mask(data->irq, INTMSK_WDTAC97, SUBMSK_WDTAC97);
-}
-
-static void s3c2416_irq_wdtac97_unmask(struct irq_data *data)
-{
-	s3c_irqsub_unmask(data->irq, INTMSK_WDTAC97);
-}
-
-static void s3c2416_irq_wdtac97_ack(struct irq_data *data)
-{
-	s3c_irqsub_maskack(data->irq, INTMSK_WDTAC97, SUBMSK_WDTAC97);
-}
-
-static struct irq_chip s3c2416_irq_wdtac97 = {
-	.irq_mask	= s3c2416_irq_wdtac97_mask,
-	.irq_unmask	= s3c2416_irq_wdtac97_unmask,
-	.irq_ack	= s3c2416_irq_wdtac97_ack,
-};
-
-/* LCD sub interrupts */
-
-static void s3c2416_irq_demux_lcd(unsigned int irq, struct irq_desc *desc)
-{
-	s3c2416_irq_demux(IRQ_S3C2443_LCD1, 4);
-}
-
-#define INTMSK_LCD	(1UL << (IRQ_LCD - IRQ_EINT0))
-#define SUBMSK_LCD	INTMSK(IRQ_S3C2443_LCD1, IRQ_S3C2443_LCD4)
-
-static void s3c2416_irq_lcd_mask(struct irq_data *data)
-{
-	s3c_irqsub_mask(data->irq, INTMSK_LCD, SUBMSK_LCD);
-}
-
-static void s3c2416_irq_lcd_unmask(struct irq_data *data)
-{
-	s3c_irqsub_unmask(data->irq, INTMSK_LCD);
-}
-
-static void s3c2416_irq_lcd_ack(struct irq_data *data)
-{
-	s3c_irqsub_maskack(data->irq, INTMSK_LCD, SUBMSK_LCD);
-}
-
-static struct irq_chip s3c2416_irq_lcd = {
-	.irq_mask	= s3c2416_irq_lcd_mask,
-	.irq_unmask	= s3c2416_irq_lcd_unmask,
-	.irq_ack	= s3c2416_irq_lcd_ack,
-};
-
-/* DMA sub interrupts */
-
-static void s3c2416_irq_demux_dma(unsigned int irq, struct irq_desc *desc)
-{
-	s3c2416_irq_demux(IRQ_S3C2443_DMA0, 6);
-}
-
-#define INTMSK_DMA	(1UL << (IRQ_S3C2443_DMA - IRQ_EINT0))
-#define SUBMSK_DMA	INTMSK(IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5)
-
-
-static void s3c2416_irq_dma_mask(struct irq_data *data)
-{
-	s3c_irqsub_mask(data->irq, INTMSK_DMA, SUBMSK_DMA);
-}
-
-static void s3c2416_irq_dma_unmask(struct irq_data *data)
-{
-	s3c_irqsub_unmask(data->irq, INTMSK_DMA);
-}
-
-static void s3c2416_irq_dma_ack(struct irq_data *data)
-{
-	s3c_irqsub_maskack(data->irq, INTMSK_DMA, SUBMSK_DMA);
-}
-
-static struct irq_chip s3c2416_irq_dma = {
-	.irq_mask	= s3c2416_irq_dma_mask,
-	.irq_unmask	= s3c2416_irq_dma_unmask,
-	.irq_ack	= s3c2416_irq_dma_ack,
-};
-
-/* UART3 sub interrupts */
-
-static void s3c2416_irq_demux_uart3(unsigned int irq, struct irq_desc *desc)
-{
-	s3c2416_irq_demux(IRQ_S3C2443_RX3, 3);
-}
-
-#define INTMSK_UART3	(1UL << (IRQ_S3C2443_UART3 - IRQ_EINT0))
-#define SUBMSK_UART3	(0x7 << (IRQ_S3C2443_RX3 - S3C2410_IRQSUB(0)))
-
-static void s3c2416_irq_uart3_mask(struct irq_data *data)
-{
-	s3c_irqsub_mask(data->irq, INTMSK_UART3, SUBMSK_UART3);
-}
-
-static void s3c2416_irq_uart3_unmask(struct irq_data *data)
-{
-	s3c_irqsub_unmask(data->irq, INTMSK_UART3);
-}
-
-static void s3c2416_irq_uart3_ack(struct irq_data *data)
-{
-	s3c_irqsub_maskack(data->irq, INTMSK_UART3, SUBMSK_UART3);
-}
-
-static struct irq_chip s3c2416_irq_uart3 = {
-	.irq_mask	= s3c2416_irq_uart3_mask,
-	.irq_unmask	= s3c2416_irq_uart3_unmask,
-	.irq_ack	= s3c2416_irq_uart3_ack,
-};
-
-/* second interrupt register */
-
-static inline void s3c2416_irq_ack_second(struct irq_data *data)
-{
-	unsigned long bitval = 1UL << (data->irq - IRQ_S3C2416_2D);
-
-	__raw_writel(bitval, S3C2416_SRCPND2);
-	__raw_writel(bitval, S3C2416_INTPND2);
-}
-
-static void s3c2416_irq_mask_second(struct irq_data *data)
-{
-	unsigned long bitval = 1UL << (data->irq - IRQ_S3C2416_2D);
-	unsigned long mask;
-
-	mask = __raw_readl(S3C2416_INTMSK2);
-	mask |= bitval;
-	__raw_writel(mask, S3C2416_INTMSK2);
-}
-
-static void s3c2416_irq_unmask_second(struct irq_data *data)
-{
-	unsigned long bitval = 1UL << (data->irq - IRQ_S3C2416_2D);
-	unsigned long mask;
-
-	mask = __raw_readl(S3C2416_INTMSK2);
-	mask &= ~bitval;
-	__raw_writel(mask, S3C2416_INTMSK2);
-}
-
-struct irq_chip s3c2416_irq_second = {
-	.irq_ack	= s3c2416_irq_ack_second,
-	.irq_mask	= s3c2416_irq_mask_second,
-	.irq_unmask	= s3c2416_irq_unmask_second,
-};
-
-
-/* IRQ initialisation code */
-
-static int s3c2416_add_sub(unsigned int base,
-				   void (*demux)(unsigned int,
-						 struct irq_desc *),
-				   struct irq_chip *chip,
-				   unsigned int start, unsigned int end)
-{
-	unsigned int irqno;
-
-	irq_set_chip_and_handler(base, &s3c_irq_level_chip, handle_level_irq);
-	irq_set_chained_handler(base, demux);
-
-	for (irqno = start; irqno <= end; irqno++) {
-		irq_set_chip_and_handler(irqno, chip, handle_level_irq);
-		set_irq_flags(irqno, IRQF_VALID);
-	}
-
-	return 0;
-}
-
-static void s3c2416_irq_add_second(void)
-{
-	unsigned long pend;
-	unsigned long last;
-	int irqno;
-	int i;
-
-	/* first, clear all interrupts pending... */
-	last = 0;
-	for (i = 0; i < 4; i++) {
-		pend = __raw_readl(S3C2416_INTPND2);
-
-		if (pend == 0 || pend == last)
-			break;
-
-		__raw_writel(pend, S3C2416_SRCPND2);
-		__raw_writel(pend, S3C2416_INTPND2);
-		printk(KERN_INFO "irq: clearing pending status %08x\n",
-		       (int)pend);
-		last = pend;
-	}
-
-	for (irqno = IRQ_S3C2416_2D; irqno <= IRQ_S3C2416_I2S1; irqno++) {
-		switch (irqno) {
-		case IRQ_S3C2416_RESERVED2:
-		case IRQ_S3C2416_RESERVED3:
-			/* no IRQ here */
-			break;
-		default:
-			irq_set_chip_and_handler(irqno, &s3c2416_irq_second,
-						 handle_edge_irq);
-			set_irq_flags(irqno, IRQF_VALID);
-		}
-	}
-}
-
-static int s3c2416_irq_add(struct device *dev,
-				  struct subsys_interface *sif)
-{
-	printk(KERN_INFO "S3C2416: IRQ Support\n");
-
-	s3c2416_add_sub(IRQ_LCD, s3c2416_irq_demux_lcd, &s3c2416_irq_lcd,
-			IRQ_S3C2443_LCD2, IRQ_S3C2443_LCD4);
-
-	s3c2416_add_sub(IRQ_S3C2443_DMA, s3c2416_irq_demux_dma,
-			&s3c2416_irq_dma, IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5);
-
-	s3c2416_add_sub(IRQ_S3C2443_UART3, s3c2416_irq_demux_uart3,
-			&s3c2416_irq_uart3,
-			IRQ_S3C2443_RX3, IRQ_S3C2443_ERR3);
-
-	s3c2416_add_sub(IRQ_WDT, s3c2416_irq_demux_wdtac97,
-			&s3c2416_irq_wdtac97,
-			IRQ_S3C2443_WDT, IRQ_S3C2443_AC97);
-
-	s3c2416_irq_add_second();
-
-	return 0;
-}
-
-static struct subsys_interface s3c2416_irq_interface = {
-	.name		= "s3c2416_irq",
-	.subsys		= &s3c2416_subsys,
-	.add_dev	= s3c2416_irq_add,
-};
-
-static int __init s3c2416_irq_init(void)
-{
-	return subsys_interface_register(&s3c2416_irq_interface);
-}
-
-arch_initcall(s3c2416_irq_init);
-
-#ifdef CONFIG_PM
-static struct sleep_save irq_save[] = {
-	SAVE_ITEM(S3C2416_INTMSK2),
-};
-
-int s3c2416_irq_suspend(void)
-{
-	s3c_pm_do_save(irq_save, ARRAY_SIZE(irq_save));
-
-	return 0;
-}
-
-void s3c2416_irq_resume(void)
-{
-	s3c_pm_do_restore(irq_save, ARRAY_SIZE(irq_save));
-}
-
-struct syscore_ops s3c2416_irq_syscore_ops = {
-	.suspend	= s3c2416_irq_suspend,
-	.resume		= s3c2416_irq_resume,
-};
-#endif
diff --git a/arch/arm/plat-s3c24xx/irq.c b/arch/arm/plat-s3c24xx/irq.c
index bac8053..febbe2c 100644
--- a/arch/arm/plat-s3c24xx/irq.c
+++ b/arch/arm/plat-s3c24xx/irq.c
@@ -761,3 +761,312 @@ struct syscore_ops s3c24xx_irq_syscore_ops = {
 	.resume		= s3c24xx_irq_resume,
 };
 #endif
+
+#ifdef CONFIG_CPU_S3C2416
+#define INTMSK(start, end) ((1 << ((end) + 1 - (start))) - 1)
+
+static inline void s3c2416_irq_demux(unsigned int irq, unsigned int len)
+{
+	unsigned int subsrc, submsk;
+	unsigned int end;
+
+	/* read the current pending interrupts, and the mask
+	 * for what it is available */
+
+	subsrc = __raw_readl(S3C2410_SUBSRCPND);
+	submsk = __raw_readl(S3C2410_INTSUBMSK);
+
+	subsrc  &= ~submsk;
+	subsrc >>= (irq - S3C2410_IRQSUB(0));
+	subsrc  &= (1 << len)-1;
+
+	end = len + irq;
+
+	for (; irq < end && subsrc; irq++) {
+		if (subsrc & 1)
+			generic_handle_irq(irq);
+
+		subsrc >>= 1;
+	}
+}
+
+/* WDT/AC97 sub interrupts */
+
+static void s3c2416_irq_demux_wdtac97(unsigned int irq, struct irq_desc *desc)
+{
+	s3c2416_irq_demux(IRQ_S3C2443_WDT, 4);
+}
+
+#define INTMSK_WDTAC97	(1UL << (IRQ_WDT - IRQ_EINT0))
+#define SUBMSK_WDTAC97	INTMSK(IRQ_S3C2443_WDT, IRQ_S3C2443_AC97)
+
+static void s3c2416_irq_wdtac97_mask(struct irq_data *data)
+{
+	s3c_irqsub_mask(data->irq, INTMSK_WDTAC97, SUBMSK_WDTAC97);
+}
+
+static void s3c2416_irq_wdtac97_unmask(struct irq_data *data)
+{
+	s3c_irqsub_unmask(data->irq, INTMSK_WDTAC97);
+}
+
+static void s3c2416_irq_wdtac97_ack(struct irq_data *data)
+{
+	s3c_irqsub_maskack(data->irq, INTMSK_WDTAC97, SUBMSK_WDTAC97);
+}
+
+static struct irq_chip s3c2416_irq_wdtac97 = {
+	.irq_mask	= s3c2416_irq_wdtac97_mask,
+	.irq_unmask	= s3c2416_irq_wdtac97_unmask,
+	.irq_ack	= s3c2416_irq_wdtac97_ack,
+};
+
+/* LCD sub interrupts */
+
+static void s3c2416_irq_demux_lcd(unsigned int irq, struct irq_desc *desc)
+{
+	s3c2416_irq_demux(IRQ_S3C2443_LCD1, 4);
+}
+
+#define INTMSK_LCD	(1UL << (IRQ_LCD - IRQ_EINT0))
+#define SUBMSK_LCD	INTMSK(IRQ_S3C2443_LCD1, IRQ_S3C2443_LCD4)
+
+static void s3c2416_irq_lcd_mask(struct irq_data *data)
+{
+	s3c_irqsub_mask(data->irq, INTMSK_LCD, SUBMSK_LCD);
+}
+
+static void s3c2416_irq_lcd_unmask(struct irq_data *data)
+{
+	s3c_irqsub_unmask(data->irq, INTMSK_LCD);
+}
+
+static void s3c2416_irq_lcd_ack(struct irq_data *data)
+{
+	s3c_irqsub_maskack(data->irq, INTMSK_LCD, SUBMSK_LCD);
+}
+
+static struct irq_chip s3c2416_irq_lcd = {
+	.irq_mask	= s3c2416_irq_lcd_mask,
+	.irq_unmask	= s3c2416_irq_lcd_unmask,
+	.irq_ack	= s3c2416_irq_lcd_ack,
+};
+
+/* DMA sub interrupts */
+
+static void s3c2416_irq_demux_dma(unsigned int irq, struct irq_desc *desc)
+{
+	s3c2416_irq_demux(IRQ_S3C2443_DMA0, 6);
+}
+
+#define INTMSK_DMA	(1UL << (IRQ_S3C2443_DMA - IRQ_EINT0))
+#define SUBMSK_DMA	INTMSK(IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5)
+
+
+static void s3c2416_irq_dma_mask(struct irq_data *data)
+{
+	s3c_irqsub_mask(data->irq, INTMSK_DMA, SUBMSK_DMA);
+}
+
+static void s3c2416_irq_dma_unmask(struct irq_data *data)
+{
+	s3c_irqsub_unmask(data->irq, INTMSK_DMA);
+}
+
+static void s3c2416_irq_dma_ack(struct irq_data *data)
+{
+	s3c_irqsub_maskack(data->irq, INTMSK_DMA, SUBMSK_DMA);
+}
+
+static struct irq_chip s3c2416_irq_dma = {
+	.irq_mask	= s3c2416_irq_dma_mask,
+	.irq_unmask	= s3c2416_irq_dma_unmask,
+	.irq_ack	= s3c2416_irq_dma_ack,
+};
+
+/* UART3 sub interrupts */
+
+static void s3c2416_irq_demux_uart3(unsigned int irq, struct irq_desc *desc)
+{
+	s3c2416_irq_demux(IRQ_S3C2443_RX3, 3);
+}
+
+#define INTMSK_UART3	(1UL << (IRQ_S3C2443_UART3 - IRQ_EINT0))
+#define SUBMSK_UART3	(0x7 << (IRQ_S3C2443_RX3 - S3C2410_IRQSUB(0)))
+
+static void s3c2416_irq_uart3_mask(struct irq_data *data)
+{
+	s3c_irqsub_mask(data->irq, INTMSK_UART3, SUBMSK_UART3);
+}
+
+static void s3c2416_irq_uart3_unmask(struct irq_data *data)
+{
+	s3c_irqsub_unmask(data->irq, INTMSK_UART3);
+}
+
+static void s3c2416_irq_uart3_ack(struct irq_data *data)
+{
+	s3c_irqsub_maskack(data->irq, INTMSK_UART3, SUBMSK_UART3);
+}
+
+static struct irq_chip s3c2416_irq_uart3 = {
+	.irq_mask	= s3c2416_irq_uart3_mask,
+	.irq_unmask	= s3c2416_irq_uart3_unmask,
+	.irq_ack	= s3c2416_irq_uart3_ack,
+};
+
+/* second interrupt register */
+
+static inline void s3c2416_irq_ack_second(struct irq_data *data)
+{
+	unsigned long bitval = 1UL << (data->irq - IRQ_S3C2416_2D);
+
+	__raw_writel(bitval, S3C2416_SRCPND2);
+	__raw_writel(bitval, S3C2416_INTPND2);
+}
+
+static void s3c2416_irq_mask_second(struct irq_data *data)
+{
+	unsigned long bitval = 1UL << (data->irq - IRQ_S3C2416_2D);
+	unsigned long mask;
+
+	mask = __raw_readl(S3C2416_INTMSK2);
+	mask |= bitval;
+	__raw_writel(mask, S3C2416_INTMSK2);
+}
+
+static void s3c2416_irq_unmask_second(struct irq_data *data)
+{
+	unsigned long bitval = 1UL << (data->irq - IRQ_S3C2416_2D);
+	unsigned long mask;
+
+	mask = __raw_readl(S3C2416_INTMSK2);
+	mask &= ~bitval;
+	__raw_writel(mask, S3C2416_INTMSK2);
+}
+
+struct irq_chip s3c2416_irq_second = {
+	.irq_ack	= s3c2416_irq_ack_second,
+	.irq_mask	= s3c2416_irq_mask_second,
+	.irq_unmask	= s3c2416_irq_unmask_second,
+};
+
+
+/* IRQ initialisation code */
+
+static int s3c2416_add_sub(unsigned int base,
+				   void (*demux)(unsigned int,
+						 struct irq_desc *),
+				   struct irq_chip *chip,
+				   unsigned int start, unsigned int end)
+{
+	unsigned int irqno;
+
+	irq_set_chip_and_handler(base, &s3c_irq_level_chip, handle_level_irq);
+	irq_set_chained_handler(base, demux);
+
+	for (irqno = start; irqno <= end; irqno++) {
+		irq_set_chip_and_handler(irqno, chip, handle_level_irq);
+		set_irq_flags(irqno, IRQF_VALID);
+	}
+
+	return 0;
+}
+
+static void s3c2416_irq_add_second(void)
+{
+	unsigned long pend;
+	unsigned long last;
+	int irqno;
+	int i;
+
+	/* first, clear all interrupts pending... */
+	last = 0;
+	for (i = 0; i < 4; i++) {
+		pend = __raw_readl(S3C2416_INTPND2);
+
+		if (pend == 0 || pend == last)
+			break;
+
+		__raw_writel(pend, S3C2416_SRCPND2);
+		__raw_writel(pend, S3C2416_INTPND2);
+		printk(KERN_INFO "irq: clearing pending status %08x\n",
+		       (int)pend);
+		last = pend;
+	}
+
+	for (irqno = IRQ_S3C2416_2D; irqno <= IRQ_S3C2416_I2S1; irqno++) {
+		switch (irqno) {
+		case IRQ_S3C2416_RESERVED2:
+		case IRQ_S3C2416_RESERVED3:
+			/* no IRQ here */
+			break;
+		default:
+			irq_set_chip_and_handler(irqno, &s3c2416_irq_second,
+						 handle_edge_irq);
+			set_irq_flags(irqno, IRQF_VALID);
+		}
+	}
+}
+
+static int s3c2416_irq_add(struct device *dev,
+				  struct subsys_interface *sif)
+{
+	printk(KERN_INFO "S3C2416: IRQ Support\n");
+
+	s3c2416_add_sub(IRQ_LCD, s3c2416_irq_demux_lcd, &s3c2416_irq_lcd,
+			IRQ_S3C2443_LCD2, IRQ_S3C2443_LCD4);
+
+	s3c2416_add_sub(IRQ_S3C2443_DMA, s3c2416_irq_demux_dma,
+			&s3c2416_irq_dma, IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5);
+
+	s3c2416_add_sub(IRQ_S3C2443_UART3, s3c2416_irq_demux_uart3,
+			&s3c2416_irq_uart3,
+			IRQ_S3C2443_RX3, IRQ_S3C2443_ERR3);
+
+	s3c2416_add_sub(IRQ_WDT, s3c2416_irq_demux_wdtac97,
+			&s3c2416_irq_wdtac97,
+			IRQ_S3C2443_WDT, IRQ_S3C2443_AC97);
+
+	s3c2416_irq_add_second();
+
+	return 0;
+}
+
+static struct subsys_interface s3c2416_irq_interface = {
+	.name		= "s3c2416_irq",
+	.subsys		= &s3c2416_subsys,
+	.add_dev	= s3c2416_irq_add,
+};
+
+static int __init s3c2416_irq_init(void)
+{
+	return subsys_interface_register(&s3c2416_irq_interface);
+}
+
+arch_initcall(s3c2416_irq_init);
+
+#ifdef CONFIG_PM
+static struct sleep_save irq2_save[] = {
+	SAVE_ITEM(S3C2416_INTMSK2),
+};
+
+int s3c2416_irq_suspend(void)
+{
+	s3c_pm_do_save(irq2_save, ARRAY_SIZE(irq2_save));
+
+	return 0;
+}
+
+void s3c2416_irq_resume(void)
+{
+	s3c_pm_do_restore(irq2_save, ARRAY_SIZE(irq2_save));
+}
+
+struct syscore_ops s3c2416_irq_syscore_ops = {
+	.suspend	= s3c2416_irq_suspend,
+	.resume		= s3c2416_irq_resume,
+};
+#endif
+
+#endif
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 04/10] ARM: S3C24XX: move s3c2416 irq init to common irq code
@ 2012-11-18  0:54   ` Heiko Stübner
  0 siblings, 0 replies; 24+ messages in thread
From: Heiko Stübner @ 2012-11-18  0:54 UTC (permalink / raw)
  To: linux-arm-kernel

This is needed to further clean up the irq init.
The only change made during the move is the renaming of the
possibly conflicting irq_save to irq2_save

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
 arch/arm/mach-s3c24xx/Makefile      |    2 +-
 arch/arm/mach-s3c24xx/irq-s3c2416.c |  348 -----------------------------------
 arch/arm/plat-s3c24xx/irq.c         |  309 +++++++++++++++++++++++++++++++
 3 files changed, 310 insertions(+), 349 deletions(-)
 delete mode 100644 arch/arm/mach-s3c24xx/irq-s3c2416.c

diff --git a/arch/arm/mach-s3c24xx/Makefile b/arch/arm/mach-s3c24xx/Makefile
index 3e1d12c..30904c9 100644
--- a/arch/arm/mach-s3c24xx/Makefile
+++ b/arch/arm/mach-s3c24xx/Makefile
@@ -25,7 +25,7 @@ obj-$(CONFIG_S3C2412_DMA)	+= dma-s3c2412.o
 obj-$(CONFIG_S3C2412_PM)	+= pm-s3c2412.o
 obj-$(CONFIG_S3C2412_PM_SLEEP)	+= sleep-s3c2412.o
 
-obj-$(CONFIG_CPU_S3C2416)	+= s3c2416.o irq-s3c2416.o clock-s3c2416.o
+obj-$(CONFIG_CPU_S3C2416)	+= s3c2416.o clock-s3c2416.o
 obj-$(CONFIG_S3C2416_PM)	+= pm-s3c2416.o
 
 obj-$(CONFIG_CPU_S3C2440)	+= s3c2440.o irq-s3c2440.o clock-s3c2440.o
diff --git a/arch/arm/mach-s3c24xx/irq-s3c2416.c b/arch/arm/mach-s3c24xx/irq-s3c2416.c
deleted file mode 100644
index ff141b0..0000000
--- a/arch/arm/mach-s3c24xx/irq-s3c2416.c
+++ /dev/null
@@ -1,348 +0,0 @@
-/* linux/arch/arm/mach-s3c2416/irq.c
- *
- * Copyright (c) 2009 Yauhen Kharuzhy <jekhor@gmail.com>,
- *	as part of OpenInkpot project
- * Copyright (c) 2009 Promwad Innovation Company
- *	Yauhen Kharuzhy <yauhen.kharuzhy@promwad.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
-*/
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/device.h>
-#include <linux/io.h>
-#include <linux/syscore_ops.h>
-
-#include <mach/hardware.h>
-#include <asm/irq.h>
-
-#include <asm/mach/irq.h>
-
-#include <mach/regs-irq.h>
-#include <mach/regs-gpio.h>
-
-#include <plat/cpu.h>
-#include <plat/pm.h>
-#include <plat/irq.h>
-
-#define INTMSK(start, end) ((1 << ((end) + 1 - (start))) - 1)
-
-static inline void s3c2416_irq_demux(unsigned int irq, unsigned int len)
-{
-	unsigned int subsrc, submsk;
-	unsigned int end;
-
-	/* read the current pending interrupts, and the mask
-	 * for what it is available */
-
-	subsrc = __raw_readl(S3C2410_SUBSRCPND);
-	submsk = __raw_readl(S3C2410_INTSUBMSK);
-
-	subsrc  &= ~submsk;
-	subsrc >>= (irq - S3C2410_IRQSUB(0));
-	subsrc  &= (1 << len)-1;
-
-	end = len + irq;
-
-	for (; irq < end && subsrc; irq++) {
-		if (subsrc & 1)
-			generic_handle_irq(irq);
-
-		subsrc >>= 1;
-	}
-}
-
-/* WDT/AC97 sub interrupts */
-
-static void s3c2416_irq_demux_wdtac97(unsigned int irq, struct irq_desc *desc)
-{
-	s3c2416_irq_demux(IRQ_S3C2443_WDT, 4);
-}
-
-#define INTMSK_WDTAC97	(1UL << (IRQ_WDT - IRQ_EINT0))
-#define SUBMSK_WDTAC97	INTMSK(IRQ_S3C2443_WDT, IRQ_S3C2443_AC97)
-
-static void s3c2416_irq_wdtac97_mask(struct irq_data *data)
-{
-	s3c_irqsub_mask(data->irq, INTMSK_WDTAC97, SUBMSK_WDTAC97);
-}
-
-static void s3c2416_irq_wdtac97_unmask(struct irq_data *data)
-{
-	s3c_irqsub_unmask(data->irq, INTMSK_WDTAC97);
-}
-
-static void s3c2416_irq_wdtac97_ack(struct irq_data *data)
-{
-	s3c_irqsub_maskack(data->irq, INTMSK_WDTAC97, SUBMSK_WDTAC97);
-}
-
-static struct irq_chip s3c2416_irq_wdtac97 = {
-	.irq_mask	= s3c2416_irq_wdtac97_mask,
-	.irq_unmask	= s3c2416_irq_wdtac97_unmask,
-	.irq_ack	= s3c2416_irq_wdtac97_ack,
-};
-
-/* LCD sub interrupts */
-
-static void s3c2416_irq_demux_lcd(unsigned int irq, struct irq_desc *desc)
-{
-	s3c2416_irq_demux(IRQ_S3C2443_LCD1, 4);
-}
-
-#define INTMSK_LCD	(1UL << (IRQ_LCD - IRQ_EINT0))
-#define SUBMSK_LCD	INTMSK(IRQ_S3C2443_LCD1, IRQ_S3C2443_LCD4)
-
-static void s3c2416_irq_lcd_mask(struct irq_data *data)
-{
-	s3c_irqsub_mask(data->irq, INTMSK_LCD, SUBMSK_LCD);
-}
-
-static void s3c2416_irq_lcd_unmask(struct irq_data *data)
-{
-	s3c_irqsub_unmask(data->irq, INTMSK_LCD);
-}
-
-static void s3c2416_irq_lcd_ack(struct irq_data *data)
-{
-	s3c_irqsub_maskack(data->irq, INTMSK_LCD, SUBMSK_LCD);
-}
-
-static struct irq_chip s3c2416_irq_lcd = {
-	.irq_mask	= s3c2416_irq_lcd_mask,
-	.irq_unmask	= s3c2416_irq_lcd_unmask,
-	.irq_ack	= s3c2416_irq_lcd_ack,
-};
-
-/* DMA sub interrupts */
-
-static void s3c2416_irq_demux_dma(unsigned int irq, struct irq_desc *desc)
-{
-	s3c2416_irq_demux(IRQ_S3C2443_DMA0, 6);
-}
-
-#define INTMSK_DMA	(1UL << (IRQ_S3C2443_DMA - IRQ_EINT0))
-#define SUBMSK_DMA	INTMSK(IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5)
-
-
-static void s3c2416_irq_dma_mask(struct irq_data *data)
-{
-	s3c_irqsub_mask(data->irq, INTMSK_DMA, SUBMSK_DMA);
-}
-
-static void s3c2416_irq_dma_unmask(struct irq_data *data)
-{
-	s3c_irqsub_unmask(data->irq, INTMSK_DMA);
-}
-
-static void s3c2416_irq_dma_ack(struct irq_data *data)
-{
-	s3c_irqsub_maskack(data->irq, INTMSK_DMA, SUBMSK_DMA);
-}
-
-static struct irq_chip s3c2416_irq_dma = {
-	.irq_mask	= s3c2416_irq_dma_mask,
-	.irq_unmask	= s3c2416_irq_dma_unmask,
-	.irq_ack	= s3c2416_irq_dma_ack,
-};
-
-/* UART3 sub interrupts */
-
-static void s3c2416_irq_demux_uart3(unsigned int irq, struct irq_desc *desc)
-{
-	s3c2416_irq_demux(IRQ_S3C2443_RX3, 3);
-}
-
-#define INTMSK_UART3	(1UL << (IRQ_S3C2443_UART3 - IRQ_EINT0))
-#define SUBMSK_UART3	(0x7 << (IRQ_S3C2443_RX3 - S3C2410_IRQSUB(0)))
-
-static void s3c2416_irq_uart3_mask(struct irq_data *data)
-{
-	s3c_irqsub_mask(data->irq, INTMSK_UART3, SUBMSK_UART3);
-}
-
-static void s3c2416_irq_uart3_unmask(struct irq_data *data)
-{
-	s3c_irqsub_unmask(data->irq, INTMSK_UART3);
-}
-
-static void s3c2416_irq_uart3_ack(struct irq_data *data)
-{
-	s3c_irqsub_maskack(data->irq, INTMSK_UART3, SUBMSK_UART3);
-}
-
-static struct irq_chip s3c2416_irq_uart3 = {
-	.irq_mask	= s3c2416_irq_uart3_mask,
-	.irq_unmask	= s3c2416_irq_uart3_unmask,
-	.irq_ack	= s3c2416_irq_uart3_ack,
-};
-
-/* second interrupt register */
-
-static inline void s3c2416_irq_ack_second(struct irq_data *data)
-{
-	unsigned long bitval = 1UL << (data->irq - IRQ_S3C2416_2D);
-
-	__raw_writel(bitval, S3C2416_SRCPND2);
-	__raw_writel(bitval, S3C2416_INTPND2);
-}
-
-static void s3c2416_irq_mask_second(struct irq_data *data)
-{
-	unsigned long bitval = 1UL << (data->irq - IRQ_S3C2416_2D);
-	unsigned long mask;
-
-	mask = __raw_readl(S3C2416_INTMSK2);
-	mask |= bitval;
-	__raw_writel(mask, S3C2416_INTMSK2);
-}
-
-static void s3c2416_irq_unmask_second(struct irq_data *data)
-{
-	unsigned long bitval = 1UL << (data->irq - IRQ_S3C2416_2D);
-	unsigned long mask;
-
-	mask = __raw_readl(S3C2416_INTMSK2);
-	mask &= ~bitval;
-	__raw_writel(mask, S3C2416_INTMSK2);
-}
-
-struct irq_chip s3c2416_irq_second = {
-	.irq_ack	= s3c2416_irq_ack_second,
-	.irq_mask	= s3c2416_irq_mask_second,
-	.irq_unmask	= s3c2416_irq_unmask_second,
-};
-
-
-/* IRQ initialisation code */
-
-static int s3c2416_add_sub(unsigned int base,
-				   void (*demux)(unsigned int,
-						 struct irq_desc *),
-				   struct irq_chip *chip,
-				   unsigned int start, unsigned int end)
-{
-	unsigned int irqno;
-
-	irq_set_chip_and_handler(base, &s3c_irq_level_chip, handle_level_irq);
-	irq_set_chained_handler(base, demux);
-
-	for (irqno = start; irqno <= end; irqno++) {
-		irq_set_chip_and_handler(irqno, chip, handle_level_irq);
-		set_irq_flags(irqno, IRQF_VALID);
-	}
-
-	return 0;
-}
-
-static void s3c2416_irq_add_second(void)
-{
-	unsigned long pend;
-	unsigned long last;
-	int irqno;
-	int i;
-
-	/* first, clear all interrupts pending... */
-	last = 0;
-	for (i = 0; i < 4; i++) {
-		pend = __raw_readl(S3C2416_INTPND2);
-
-		if (pend == 0 || pend == last)
-			break;
-
-		__raw_writel(pend, S3C2416_SRCPND2);
-		__raw_writel(pend, S3C2416_INTPND2);
-		printk(KERN_INFO "irq: clearing pending status %08x\n",
-		       (int)pend);
-		last = pend;
-	}
-
-	for (irqno = IRQ_S3C2416_2D; irqno <= IRQ_S3C2416_I2S1; irqno++) {
-		switch (irqno) {
-		case IRQ_S3C2416_RESERVED2:
-		case IRQ_S3C2416_RESERVED3:
-			/* no IRQ here */
-			break;
-		default:
-			irq_set_chip_and_handler(irqno, &s3c2416_irq_second,
-						 handle_edge_irq);
-			set_irq_flags(irqno, IRQF_VALID);
-		}
-	}
-}
-
-static int s3c2416_irq_add(struct device *dev,
-				  struct subsys_interface *sif)
-{
-	printk(KERN_INFO "S3C2416: IRQ Support\n");
-
-	s3c2416_add_sub(IRQ_LCD, s3c2416_irq_demux_lcd, &s3c2416_irq_lcd,
-			IRQ_S3C2443_LCD2, IRQ_S3C2443_LCD4);
-
-	s3c2416_add_sub(IRQ_S3C2443_DMA, s3c2416_irq_demux_dma,
-			&s3c2416_irq_dma, IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5);
-
-	s3c2416_add_sub(IRQ_S3C2443_UART3, s3c2416_irq_demux_uart3,
-			&s3c2416_irq_uart3,
-			IRQ_S3C2443_RX3, IRQ_S3C2443_ERR3);
-
-	s3c2416_add_sub(IRQ_WDT, s3c2416_irq_demux_wdtac97,
-			&s3c2416_irq_wdtac97,
-			IRQ_S3C2443_WDT, IRQ_S3C2443_AC97);
-
-	s3c2416_irq_add_second();
-
-	return 0;
-}
-
-static struct subsys_interface s3c2416_irq_interface = {
-	.name		= "s3c2416_irq",
-	.subsys		= &s3c2416_subsys,
-	.add_dev	= s3c2416_irq_add,
-};
-
-static int __init s3c2416_irq_init(void)
-{
-	return subsys_interface_register(&s3c2416_irq_interface);
-}
-
-arch_initcall(s3c2416_irq_init);
-
-#ifdef CONFIG_PM
-static struct sleep_save irq_save[] = {
-	SAVE_ITEM(S3C2416_INTMSK2),
-};
-
-int s3c2416_irq_suspend(void)
-{
-	s3c_pm_do_save(irq_save, ARRAY_SIZE(irq_save));
-
-	return 0;
-}
-
-void s3c2416_irq_resume(void)
-{
-	s3c_pm_do_restore(irq_save, ARRAY_SIZE(irq_save));
-}
-
-struct syscore_ops s3c2416_irq_syscore_ops = {
-	.suspend	= s3c2416_irq_suspend,
-	.resume		= s3c2416_irq_resume,
-};
-#endif
diff --git a/arch/arm/plat-s3c24xx/irq.c b/arch/arm/plat-s3c24xx/irq.c
index bac8053..febbe2c 100644
--- a/arch/arm/plat-s3c24xx/irq.c
+++ b/arch/arm/plat-s3c24xx/irq.c
@@ -761,3 +761,312 @@ struct syscore_ops s3c24xx_irq_syscore_ops = {
 	.resume		= s3c24xx_irq_resume,
 };
 #endif
+
+#ifdef CONFIG_CPU_S3C2416
+#define INTMSK(start, end) ((1 << ((end) + 1 - (start))) - 1)
+
+static inline void s3c2416_irq_demux(unsigned int irq, unsigned int len)
+{
+	unsigned int subsrc, submsk;
+	unsigned int end;
+
+	/* read the current pending interrupts, and the mask
+	 * for what it is available */
+
+	subsrc = __raw_readl(S3C2410_SUBSRCPND);
+	submsk = __raw_readl(S3C2410_INTSUBMSK);
+
+	subsrc  &= ~submsk;
+	subsrc >>= (irq - S3C2410_IRQSUB(0));
+	subsrc  &= (1 << len)-1;
+
+	end = len + irq;
+
+	for (; irq < end && subsrc; irq++) {
+		if (subsrc & 1)
+			generic_handle_irq(irq);
+
+		subsrc >>= 1;
+	}
+}
+
+/* WDT/AC97 sub interrupts */
+
+static void s3c2416_irq_demux_wdtac97(unsigned int irq, struct irq_desc *desc)
+{
+	s3c2416_irq_demux(IRQ_S3C2443_WDT, 4);
+}
+
+#define INTMSK_WDTAC97	(1UL << (IRQ_WDT - IRQ_EINT0))
+#define SUBMSK_WDTAC97	INTMSK(IRQ_S3C2443_WDT, IRQ_S3C2443_AC97)
+
+static void s3c2416_irq_wdtac97_mask(struct irq_data *data)
+{
+	s3c_irqsub_mask(data->irq, INTMSK_WDTAC97, SUBMSK_WDTAC97);
+}
+
+static void s3c2416_irq_wdtac97_unmask(struct irq_data *data)
+{
+	s3c_irqsub_unmask(data->irq, INTMSK_WDTAC97);
+}
+
+static void s3c2416_irq_wdtac97_ack(struct irq_data *data)
+{
+	s3c_irqsub_maskack(data->irq, INTMSK_WDTAC97, SUBMSK_WDTAC97);
+}
+
+static struct irq_chip s3c2416_irq_wdtac97 = {
+	.irq_mask	= s3c2416_irq_wdtac97_mask,
+	.irq_unmask	= s3c2416_irq_wdtac97_unmask,
+	.irq_ack	= s3c2416_irq_wdtac97_ack,
+};
+
+/* LCD sub interrupts */
+
+static void s3c2416_irq_demux_lcd(unsigned int irq, struct irq_desc *desc)
+{
+	s3c2416_irq_demux(IRQ_S3C2443_LCD1, 4);
+}
+
+#define INTMSK_LCD	(1UL << (IRQ_LCD - IRQ_EINT0))
+#define SUBMSK_LCD	INTMSK(IRQ_S3C2443_LCD1, IRQ_S3C2443_LCD4)
+
+static void s3c2416_irq_lcd_mask(struct irq_data *data)
+{
+	s3c_irqsub_mask(data->irq, INTMSK_LCD, SUBMSK_LCD);
+}
+
+static void s3c2416_irq_lcd_unmask(struct irq_data *data)
+{
+	s3c_irqsub_unmask(data->irq, INTMSK_LCD);
+}
+
+static void s3c2416_irq_lcd_ack(struct irq_data *data)
+{
+	s3c_irqsub_maskack(data->irq, INTMSK_LCD, SUBMSK_LCD);
+}
+
+static struct irq_chip s3c2416_irq_lcd = {
+	.irq_mask	= s3c2416_irq_lcd_mask,
+	.irq_unmask	= s3c2416_irq_lcd_unmask,
+	.irq_ack	= s3c2416_irq_lcd_ack,
+};
+
+/* DMA sub interrupts */
+
+static void s3c2416_irq_demux_dma(unsigned int irq, struct irq_desc *desc)
+{
+	s3c2416_irq_demux(IRQ_S3C2443_DMA0, 6);
+}
+
+#define INTMSK_DMA	(1UL << (IRQ_S3C2443_DMA - IRQ_EINT0))
+#define SUBMSK_DMA	INTMSK(IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5)
+
+
+static void s3c2416_irq_dma_mask(struct irq_data *data)
+{
+	s3c_irqsub_mask(data->irq, INTMSK_DMA, SUBMSK_DMA);
+}
+
+static void s3c2416_irq_dma_unmask(struct irq_data *data)
+{
+	s3c_irqsub_unmask(data->irq, INTMSK_DMA);
+}
+
+static void s3c2416_irq_dma_ack(struct irq_data *data)
+{
+	s3c_irqsub_maskack(data->irq, INTMSK_DMA, SUBMSK_DMA);
+}
+
+static struct irq_chip s3c2416_irq_dma = {
+	.irq_mask	= s3c2416_irq_dma_mask,
+	.irq_unmask	= s3c2416_irq_dma_unmask,
+	.irq_ack	= s3c2416_irq_dma_ack,
+};
+
+/* UART3 sub interrupts */
+
+static void s3c2416_irq_demux_uart3(unsigned int irq, struct irq_desc *desc)
+{
+	s3c2416_irq_demux(IRQ_S3C2443_RX3, 3);
+}
+
+#define INTMSK_UART3	(1UL << (IRQ_S3C2443_UART3 - IRQ_EINT0))
+#define SUBMSK_UART3	(0x7 << (IRQ_S3C2443_RX3 - S3C2410_IRQSUB(0)))
+
+static void s3c2416_irq_uart3_mask(struct irq_data *data)
+{
+	s3c_irqsub_mask(data->irq, INTMSK_UART3, SUBMSK_UART3);
+}
+
+static void s3c2416_irq_uart3_unmask(struct irq_data *data)
+{
+	s3c_irqsub_unmask(data->irq, INTMSK_UART3);
+}
+
+static void s3c2416_irq_uart3_ack(struct irq_data *data)
+{
+	s3c_irqsub_maskack(data->irq, INTMSK_UART3, SUBMSK_UART3);
+}
+
+static struct irq_chip s3c2416_irq_uart3 = {
+	.irq_mask	= s3c2416_irq_uart3_mask,
+	.irq_unmask	= s3c2416_irq_uart3_unmask,
+	.irq_ack	= s3c2416_irq_uart3_ack,
+};
+
+/* second interrupt register */
+
+static inline void s3c2416_irq_ack_second(struct irq_data *data)
+{
+	unsigned long bitval = 1UL << (data->irq - IRQ_S3C2416_2D);
+
+	__raw_writel(bitval, S3C2416_SRCPND2);
+	__raw_writel(bitval, S3C2416_INTPND2);
+}
+
+static void s3c2416_irq_mask_second(struct irq_data *data)
+{
+	unsigned long bitval = 1UL << (data->irq - IRQ_S3C2416_2D);
+	unsigned long mask;
+
+	mask = __raw_readl(S3C2416_INTMSK2);
+	mask |= bitval;
+	__raw_writel(mask, S3C2416_INTMSK2);
+}
+
+static void s3c2416_irq_unmask_second(struct irq_data *data)
+{
+	unsigned long bitval = 1UL << (data->irq - IRQ_S3C2416_2D);
+	unsigned long mask;
+
+	mask = __raw_readl(S3C2416_INTMSK2);
+	mask &= ~bitval;
+	__raw_writel(mask, S3C2416_INTMSK2);
+}
+
+struct irq_chip s3c2416_irq_second = {
+	.irq_ack	= s3c2416_irq_ack_second,
+	.irq_mask	= s3c2416_irq_mask_second,
+	.irq_unmask	= s3c2416_irq_unmask_second,
+};
+
+
+/* IRQ initialisation code */
+
+static int s3c2416_add_sub(unsigned int base,
+				   void (*demux)(unsigned int,
+						 struct irq_desc *),
+				   struct irq_chip *chip,
+				   unsigned int start, unsigned int end)
+{
+	unsigned int irqno;
+
+	irq_set_chip_and_handler(base, &s3c_irq_level_chip, handle_level_irq);
+	irq_set_chained_handler(base, demux);
+
+	for (irqno = start; irqno <= end; irqno++) {
+		irq_set_chip_and_handler(irqno, chip, handle_level_irq);
+		set_irq_flags(irqno, IRQF_VALID);
+	}
+
+	return 0;
+}
+
+static void s3c2416_irq_add_second(void)
+{
+	unsigned long pend;
+	unsigned long last;
+	int irqno;
+	int i;
+
+	/* first, clear all interrupts pending... */
+	last = 0;
+	for (i = 0; i < 4; i++) {
+		pend = __raw_readl(S3C2416_INTPND2);
+
+		if (pend == 0 || pend == last)
+			break;
+
+		__raw_writel(pend, S3C2416_SRCPND2);
+		__raw_writel(pend, S3C2416_INTPND2);
+		printk(KERN_INFO "irq: clearing pending status %08x\n",
+		       (int)pend);
+		last = pend;
+	}
+
+	for (irqno = IRQ_S3C2416_2D; irqno <= IRQ_S3C2416_I2S1; irqno++) {
+		switch (irqno) {
+		case IRQ_S3C2416_RESERVED2:
+		case IRQ_S3C2416_RESERVED3:
+			/* no IRQ here */
+			break;
+		default:
+			irq_set_chip_and_handler(irqno, &s3c2416_irq_second,
+						 handle_edge_irq);
+			set_irq_flags(irqno, IRQF_VALID);
+		}
+	}
+}
+
+static int s3c2416_irq_add(struct device *dev,
+				  struct subsys_interface *sif)
+{
+	printk(KERN_INFO "S3C2416: IRQ Support\n");
+
+	s3c2416_add_sub(IRQ_LCD, s3c2416_irq_demux_lcd, &s3c2416_irq_lcd,
+			IRQ_S3C2443_LCD2, IRQ_S3C2443_LCD4);
+
+	s3c2416_add_sub(IRQ_S3C2443_DMA, s3c2416_irq_demux_dma,
+			&s3c2416_irq_dma, IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5);
+
+	s3c2416_add_sub(IRQ_S3C2443_UART3, s3c2416_irq_demux_uart3,
+			&s3c2416_irq_uart3,
+			IRQ_S3C2443_RX3, IRQ_S3C2443_ERR3);
+
+	s3c2416_add_sub(IRQ_WDT, s3c2416_irq_demux_wdtac97,
+			&s3c2416_irq_wdtac97,
+			IRQ_S3C2443_WDT, IRQ_S3C2443_AC97);
+
+	s3c2416_irq_add_second();
+
+	return 0;
+}
+
+static struct subsys_interface s3c2416_irq_interface = {
+	.name		= "s3c2416_irq",
+	.subsys		= &s3c2416_subsys,
+	.add_dev	= s3c2416_irq_add,
+};
+
+static int __init s3c2416_irq_init(void)
+{
+	return subsys_interface_register(&s3c2416_irq_interface);
+}
+
+arch_initcall(s3c2416_irq_init);
+
+#ifdef CONFIG_PM
+static struct sleep_save irq2_save[] = {
+	SAVE_ITEM(S3C2416_INTMSK2),
+};
+
+int s3c2416_irq_suspend(void)
+{
+	s3c_pm_do_save(irq2_save, ARRAY_SIZE(irq2_save));
+
+	return 0;
+}
+
+void s3c2416_irq_resume(void)
+{
+	s3c_pm_do_restore(irq2_save, ARRAY_SIZE(irq2_save));
+}
+
+struct syscore_ops s3c2416_irq_syscore_ops = {
+	.suspend	= s3c2416_irq_suspend,
+	.resume		= s3c2416_irq_resume,
+};
+#endif
+
+#endif
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 05/10] ARM: S3C24XX: modify s3c2416 irq init to initialize all irqs
  2012-11-18  0:51 ` Heiko Stübner
@ 2012-11-18  0:54   ` Heiko Stübner
  -1 siblings, 0 replies; 24+ messages in thread
From: Heiko Stübner @ 2012-11-18  0:54 UTC (permalink / raw)
  To: Kukjin Kim; +Cc: Ben Dooks, linux-arm-kernel, linux-samsung-soc

Previously the irq init used s3c24xx_init_irq and an additional
arch_initcall to add the cpu specific irqs.

To be able to simplyfy the irq init later, create a new function
s3c416_init_irq, which then calls s3c24xx_init_irq but also adds
the cpu specific irqs.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
 arch/arm/mach-s3c24xx/mach-smdk2416.c        |    2 +-
 arch/arm/plat-s3c24xx/irq.c                  |   22 ++++------------------
 arch/arm/plat-samsung/include/plat/s3c2416.h |    1 +
 3 files changed, 6 insertions(+), 19 deletions(-)

diff --git a/arch/arm/mach-s3c24xx/mach-smdk2416.c b/arch/arm/mach-s3c24xx/mach-smdk2416.c
index f30d7fc..5f6858f 100644
--- a/arch/arm/mach-s3c24xx/mach-smdk2416.c
+++ b/arch/arm/mach-s3c24xx/mach-smdk2416.c
@@ -251,7 +251,7 @@ MACHINE_START(SMDK2416, "SMDK2416")
 	/* Maintainer: Yauhen Kharuzhy <jekhor@gmail.com> */
 	.atag_offset	= 0x100,
 
-	.init_irq	= s3c24xx_init_irq,
+	.init_irq	= s3c2416_init_irq,
 	.map_io		= smdk2416_map_io,
 	.init_machine	= smdk2416_machine_init,
 	.timer		= &s3c24xx_timer,
diff --git a/arch/arm/plat-s3c24xx/irq.c b/arch/arm/plat-s3c24xx/irq.c
index febbe2c..ca60486 100644
--- a/arch/arm/plat-s3c24xx/irq.c
+++ b/arch/arm/plat-s3c24xx/irq.c
@@ -1009,10 +1009,11 @@ static void s3c2416_irq_add_second(void)
 	}
 }
 
-static int s3c2416_irq_add(struct device *dev,
-				  struct subsys_interface *sif)
+void __init s3c2416_init_irq(void)
 {
-	printk(KERN_INFO "S3C2416: IRQ Support\n");
+	pr_info("S3C2416: IRQ Support\n");
+
+	s3c24xx_init_irq();
 
 	s3c2416_add_sub(IRQ_LCD, s3c2416_irq_demux_lcd, &s3c2416_irq_lcd,
 			IRQ_S3C2443_LCD2, IRQ_S3C2443_LCD4);
@@ -1029,23 +1030,8 @@ static int s3c2416_irq_add(struct device *dev,
 			IRQ_S3C2443_WDT, IRQ_S3C2443_AC97);
 
 	s3c2416_irq_add_second();
-
-	return 0;
 }
 
-static struct subsys_interface s3c2416_irq_interface = {
-	.name		= "s3c2416_irq",
-	.subsys		= &s3c2416_subsys,
-	.add_dev	= s3c2416_irq_add,
-};
-
-static int __init s3c2416_irq_init(void)
-{
-	return subsys_interface_register(&s3c2416_irq_interface);
-}
-
-arch_initcall(s3c2416_irq_init);
-
 #ifdef CONFIG_PM
 static struct sleep_save irq2_save[] = {
 	SAVE_ITEM(S3C2416_INTMSK2),
diff --git a/arch/arm/plat-samsung/include/plat/s3c2416.h b/arch/arm/plat-samsung/include/plat/s3c2416.h
index 7178e33..f27399a 100644
--- a/arch/arm/plat-samsung/include/plat/s3c2416.h
+++ b/arch/arm/plat-samsung/include/plat/s3c2416.h
@@ -25,6 +25,7 @@ extern  int s3c2416_baseclk_add(void);
 
 extern void s3c2416_restart(char mode, const char *cmd);
 
+extern void s3c2416_init_irq(void);
 extern struct syscore_ops s3c2416_irq_syscore_ops;
 
 #else
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 05/10] ARM: S3C24XX: modify s3c2416 irq init to initialize all irqs
@ 2012-11-18  0:54   ` Heiko Stübner
  0 siblings, 0 replies; 24+ messages in thread
From: Heiko Stübner @ 2012-11-18  0:54 UTC (permalink / raw)
  To: linux-arm-kernel

Previously the irq init used s3c24xx_init_irq and an additional
arch_initcall to add the cpu specific irqs.

To be able to simplyfy the irq init later, create a new function
s3c416_init_irq, which then calls s3c24xx_init_irq but also adds
the cpu specific irqs.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
 arch/arm/mach-s3c24xx/mach-smdk2416.c        |    2 +-
 arch/arm/plat-s3c24xx/irq.c                  |   22 ++++------------------
 arch/arm/plat-samsung/include/plat/s3c2416.h |    1 +
 3 files changed, 6 insertions(+), 19 deletions(-)

diff --git a/arch/arm/mach-s3c24xx/mach-smdk2416.c b/arch/arm/mach-s3c24xx/mach-smdk2416.c
index f30d7fc..5f6858f 100644
--- a/arch/arm/mach-s3c24xx/mach-smdk2416.c
+++ b/arch/arm/mach-s3c24xx/mach-smdk2416.c
@@ -251,7 +251,7 @@ MACHINE_START(SMDK2416, "SMDK2416")
 	/* Maintainer: Yauhen Kharuzhy <jekhor@gmail.com> */
 	.atag_offset	= 0x100,
 
-	.init_irq	= s3c24xx_init_irq,
+	.init_irq	= s3c2416_init_irq,
 	.map_io		= smdk2416_map_io,
 	.init_machine	= smdk2416_machine_init,
 	.timer		= &s3c24xx_timer,
diff --git a/arch/arm/plat-s3c24xx/irq.c b/arch/arm/plat-s3c24xx/irq.c
index febbe2c..ca60486 100644
--- a/arch/arm/plat-s3c24xx/irq.c
+++ b/arch/arm/plat-s3c24xx/irq.c
@@ -1009,10 +1009,11 @@ static void s3c2416_irq_add_second(void)
 	}
 }
 
-static int s3c2416_irq_add(struct device *dev,
-				  struct subsys_interface *sif)
+void __init s3c2416_init_irq(void)
 {
-	printk(KERN_INFO "S3C2416: IRQ Support\n");
+	pr_info("S3C2416: IRQ Support\n");
+
+	s3c24xx_init_irq();
 
 	s3c2416_add_sub(IRQ_LCD, s3c2416_irq_demux_lcd, &s3c2416_irq_lcd,
 			IRQ_S3C2443_LCD2, IRQ_S3C2443_LCD4);
@@ -1029,23 +1030,8 @@ static int s3c2416_irq_add(struct device *dev,
 			IRQ_S3C2443_WDT, IRQ_S3C2443_AC97);
 
 	s3c2416_irq_add_second();
-
-	return 0;
 }
 
-static struct subsys_interface s3c2416_irq_interface = {
-	.name		= "s3c2416_irq",
-	.subsys		= &s3c2416_subsys,
-	.add_dev	= s3c2416_irq_add,
-};
-
-static int __init s3c2416_irq_init(void)
-{
-	return subsys_interface_register(&s3c2416_irq_interface);
-}
-
-arch_initcall(s3c2416_irq_init);
-
 #ifdef CONFIG_PM
 static struct sleep_save irq2_save[] = {
 	SAVE_ITEM(S3C2416_INTMSK2),
diff --git a/arch/arm/plat-samsung/include/plat/s3c2416.h b/arch/arm/plat-samsung/include/plat/s3c2416.h
index 7178e33..f27399a 100644
--- a/arch/arm/plat-samsung/include/plat/s3c2416.h
+++ b/arch/arm/plat-samsung/include/plat/s3c2416.h
@@ -25,6 +25,7 @@ extern  int s3c2416_baseclk_add(void);
 
 extern void s3c2416_restart(char mode, const char *cmd);
 
+extern void s3c2416_init_irq(void);
 extern struct syscore_ops s3c2416_irq_syscore_ops;
 
 #else
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 06/10] ARM: S3C24XX: assimilate s3c2416 subirqs into new structure
  2012-11-18  0:51 ` Heiko Stübner
@ 2012-11-18  0:55   ` Heiko Stübner
  -1 siblings, 0 replies; 24+ messages in thread
From: Heiko Stübner @ 2012-11-18  0:55 UTC (permalink / raw)
  To: Kukjin Kim; +Cc: Ben Dooks, linux-arm-kernel, linux-samsung-soc

The contents of the base interrupt register is identical for
s3c2443 and s3c2416/2450, so keep it separate already.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
 arch/arm/plat-s3c24xx/irq.c |  257 ++++++++++++-------------------------------
 1 files changed, 72 insertions(+), 185 deletions(-)

diff --git a/arch/arm/plat-s3c24xx/irq.c b/arch/arm/plat-s3c24xx/irq.c
index ca60486..ace7e34 100644
--- a/arch/arm/plat-s3c24xx/irq.c
+++ b/arch/arm/plat-s3c24xx/irq.c
@@ -762,158 +762,44 @@ struct syscore_ops s3c24xx_irq_syscore_ops = {
 };
 #endif
 
-#ifdef CONFIG_CPU_S3C2416
-#define INTMSK(start, end) ((1 << ((end) + 1 - (start))) - 1)
-
-static inline void s3c2416_irq_demux(unsigned int irq, unsigned int len)
-{
-	unsigned int subsrc, submsk;
-	unsigned int end;
-
-	/* read the current pending interrupts, and the mask
-	 * for what it is available */
-
-	subsrc = __raw_readl(S3C2410_SUBSRCPND);
-	submsk = __raw_readl(S3C2410_INTSUBMSK);
-
-	subsrc  &= ~submsk;
-	subsrc >>= (irq - S3C2410_IRQSUB(0));
-	subsrc  &= (1 << len)-1;
-
-	end = len + irq;
-
-	for (; irq < end && subsrc; irq++) {
-		if (subsrc & 1)
-			generic_handle_irq(irq);
-
-		subsrc >>= 1;
-	}
-}
-
-/* WDT/AC97 sub interrupts */
-
-static void s3c2416_irq_demux_wdtac97(unsigned int irq, struct irq_desc *desc)
-{
-	s3c2416_irq_demux(IRQ_S3C2443_WDT, 4);
-}
-
-#define INTMSK_WDTAC97	(1UL << (IRQ_WDT - IRQ_EINT0))
-#define SUBMSK_WDTAC97	INTMSK(IRQ_S3C2443_WDT, IRQ_S3C2443_AC97)
-
-static void s3c2416_irq_wdtac97_mask(struct irq_data *data)
-{
-	s3c_irqsub_mask(data->irq, INTMSK_WDTAC97, SUBMSK_WDTAC97);
-}
-
-static void s3c2416_irq_wdtac97_unmask(struct irq_data *data)
-{
-	s3c_irqsub_unmask(data->irq, INTMSK_WDTAC97);
-}
-
-static void s3c2416_irq_wdtac97_ack(struct irq_data *data)
-{
-	s3c_irqsub_maskack(data->irq, INTMSK_WDTAC97, SUBMSK_WDTAC97);
-}
-
-static struct irq_chip s3c2416_irq_wdtac97 = {
-	.irq_mask	= s3c2416_irq_wdtac97_mask,
-	.irq_unmask	= s3c2416_irq_wdtac97_unmask,
-	.irq_ack	= s3c2416_irq_wdtac97_ack,
-};
-
-/* LCD sub interrupts */
-
-static void s3c2416_irq_demux_lcd(unsigned int irq, struct irq_desc *desc)
-{
-	s3c2416_irq_demux(IRQ_S3C2443_LCD1, 4);
-}
-
-#define INTMSK_LCD	(1UL << (IRQ_LCD - IRQ_EINT0))
-#define SUBMSK_LCD	INTMSK(IRQ_S3C2443_LCD1, IRQ_S3C2443_LCD4)
-
-static void s3c2416_irq_lcd_mask(struct irq_data *data)
-{
-	s3c_irqsub_mask(data->irq, INTMSK_LCD, SUBMSK_LCD);
-}
-
-static void s3c2416_irq_lcd_unmask(struct irq_data *data)
-{
-	s3c_irqsub_unmask(data->irq, INTMSK_LCD);
-}
-
-static void s3c2416_irq_lcd_ack(struct irq_data *data)
-{
-	s3c_irqsub_maskack(data->irq, INTMSK_LCD, SUBMSK_LCD);
-}
-
-static struct irq_chip s3c2416_irq_lcd = {
-	.irq_mask	= s3c2416_irq_lcd_mask,
-	.irq_unmask	= s3c2416_irq_lcd_unmask,
-	.irq_ack	= s3c2416_irq_lcd_ack,
-};
-
-/* DMA sub interrupts */
-
-static void s3c2416_irq_demux_dma(unsigned int irq, struct irq_desc *desc)
-{
-	s3c2416_irq_demux(IRQ_S3C2443_DMA0, 6);
-}
-
-#define INTMSK_DMA	(1UL << (IRQ_S3C2443_DMA - IRQ_EINT0))
-#define SUBMSK_DMA	INTMSK(IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5)
-
-
-static void s3c2416_irq_dma_mask(struct irq_data *data)
-{
-	s3c_irqsub_mask(data->irq, INTMSK_DMA, SUBMSK_DMA);
-}
-
-static void s3c2416_irq_dma_unmask(struct irq_data *data)
-{
-	s3c_irqsub_unmask(data->irq, INTMSK_DMA);
-}
-
-static void s3c2416_irq_dma_ack(struct irq_data *data)
-{
-	s3c_irqsub_maskack(data->irq, INTMSK_DMA, SUBMSK_DMA);
-}
-
-static struct irq_chip s3c2416_irq_dma = {
-	.irq_mask	= s3c2416_irq_dma_mask,
-	.irq_unmask	= s3c2416_irq_dma_unmask,
-	.irq_ack	= s3c2416_irq_dma_ack,
+#if defined CONFIG_CPU_S3C2416 || defined CONFIG_CPU_S3C2443
+struct s3c_irq_data init_s3c2443base[32] = {
+	{ .type = S3C_IRQTYPE_EINT0T4, }, /* EINT0 */
+	{ .type = S3C_IRQTYPE_EINT0T4, }, /* EINT1 */
+	{ .type = S3C_IRQTYPE_EINT0T4, }, /* EINT2 */
+	{ .type = S3C_IRQTYPE_EINT0T4, }, /* EINT3 */
+	{ .type = S3C_IRQTYPE_PARENT, }, /* EINT4to7 */
+	{ .type = S3C_IRQTYPE_PARENT, }, /* EINT8to23 */
+	{ .type = S3C_IRQTYPE_PARENT, }, /* CAM on S3C2443/2450 */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* nBATT_FLT */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* TICK */
+	{ .type = S3C_IRQTYPE_PARENT, }, /* WDT/AC97 */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* TIMER0 */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* TIMER1 */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* TIMER2 */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* TIMER3 */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* TIMER4 */
+	{ .type = S3C_IRQTYPE_PARENT, }, /* UART2 */
+	{ .type = S3C_IRQTYPE_PARENT, }, /* LCD */
+	{ .type = S3C_IRQTYPE_PARENT, }, /* DMA */
+	{ .type = S3C_IRQTYPE_PARENT, }, /* UART3 */
+	{ .type = S3C_IRQTYPE_NONE, }, /* CFON on S3C2443/2450 */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* SDI1 */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* SDI0 */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* SPI0 */
+	{ .type = S3C_IRQTYPE_PARENT, }, /* UART1 */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* NAND */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* USBD */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* USBH */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* IIC */
+	{ .type = S3C_IRQTYPE_PARENT, }, /* UART0 */
+	{ .type = S3C_IRQTYPE_NONE, }, /* SPI1 on S3C243/2450 */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* RTC */
+	{ .type = S3C_IRQTYPE_PARENT, }, /* ADCPARENT */
 };
+#endif
 
-/* UART3 sub interrupts */
-
-static void s3c2416_irq_demux_uart3(unsigned int irq, struct irq_desc *desc)
-{
-	s3c2416_irq_demux(IRQ_S3C2443_RX3, 3);
-}
-
-#define INTMSK_UART3	(1UL << (IRQ_S3C2443_UART3 - IRQ_EINT0))
-#define SUBMSK_UART3	(0x7 << (IRQ_S3C2443_RX3 - S3C2410_IRQSUB(0)))
-
-static void s3c2416_irq_uart3_mask(struct irq_data *data)
-{
-	s3c_irqsub_mask(data->irq, INTMSK_UART3, SUBMSK_UART3);
-}
-
-static void s3c2416_irq_uart3_unmask(struct irq_data *data)
-{
-	s3c_irqsub_unmask(data->irq, INTMSK_UART3);
-}
-
-static void s3c2416_irq_uart3_ack(struct irq_data *data)
-{
-	s3c_irqsub_maskack(data->irq, INTMSK_UART3, SUBMSK_UART3);
-}
-
-static struct irq_chip s3c2416_irq_uart3 = {
-	.irq_mask	= s3c2416_irq_uart3_mask,
-	.irq_unmask	= s3c2416_irq_uart3_unmask,
-	.irq_ack	= s3c2416_irq_uart3_ack,
-};
+#ifdef CONFIG_CPU_S3C2416
 
 /* second interrupt register */
 
@@ -952,27 +838,6 @@ struct irq_chip s3c2416_irq_second = {
 };
 
 
-/* IRQ initialisation code */
-
-static int s3c2416_add_sub(unsigned int base,
-				   void (*demux)(unsigned int,
-						 struct irq_desc *),
-				   struct irq_chip *chip,
-				   unsigned int start, unsigned int end)
-{
-	unsigned int irqno;
-
-	irq_set_chip_and_handler(base, &s3c_irq_level_chip, handle_level_irq);
-	irq_set_chained_handler(base, demux);
-
-	for (irqno = start; irqno <= end; irqno++) {
-		irq_set_chip_and_handler(irqno, chip, handle_level_irq);
-		set_irq_flags(irqno, IRQF_VALID);
-	}
-
-	return 0;
-}
-
 static void s3c2416_irq_add_second(void)
 {
 	unsigned long pend;
@@ -1009,26 +874,48 @@ static void s3c2416_irq_add_second(void)
 	}
 }
 
+struct s3c_irq_data init_s3c2416subint[32] = {
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 28 }, /* UART0-RX */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 28 }, /* UART0-TX */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 28 }, /* UART0-ERR */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 23 }, /* UART1-RX */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 23 }, /* UART1-TX */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 23 }, /* UART1-ERR */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 15 }, /* UART2-RX */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 15 }, /* UART2-TX */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 15 }, /* UART2-ERR */
+	{ .type = S3C_IRQTYPE_SUBEDGE, .parent_irq = 31 }, /* TC */
+	{ .type = S3C_IRQTYPE_SUBEDGE, .parent_irq = 31 }, /* ADC */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 6 }, /* CAM_C S3C2450 */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 6 }, /* CAM_P S3C2450 */
+	{ .type = S3C_IRQTYPE_NONE }, /* reserved */
+	{ .type = S3C_IRQTYPE_NONE }, /* reserved */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 16 }, /* LCD2 */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 16 }, /* LCD3 */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 16 }, /* LCD4 */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 17 }, /* DMA0 */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 17 }, /* DMA1 */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 17 }, /* DMA2 */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 17 }, /* DMA3 */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 17 }, /* DMA4 */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 17 }, /* DMA5 */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 18 }, /* UART3-RX */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 18 }, /* UART3-TX */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 18 }, /* UART3-ERR */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 9 }, /* WDT */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 9 }, /* AC97 */
+};
+
 void __init s3c2416_init_irq(void)
 {
+	/* override irq data */
+	s3c_intc[0].irqs = &init_s3c2443base[0];
+	s3c_intc[2].irqs = &init_s3c2416subint[0];
+
 	pr_info("S3C2416: IRQ Support\n");
 
 	s3c24xx_init_irq();
 
-	s3c2416_add_sub(IRQ_LCD, s3c2416_irq_demux_lcd, &s3c2416_irq_lcd,
-			IRQ_S3C2443_LCD2, IRQ_S3C2443_LCD4);
-
-	s3c2416_add_sub(IRQ_S3C2443_DMA, s3c2416_irq_demux_dma,
-			&s3c2416_irq_dma, IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5);
-
-	s3c2416_add_sub(IRQ_S3C2443_UART3, s3c2416_irq_demux_uart3,
-			&s3c2416_irq_uart3,
-			IRQ_S3C2443_RX3, IRQ_S3C2443_ERR3);
-
-	s3c2416_add_sub(IRQ_WDT, s3c2416_irq_demux_wdtac97,
-			&s3c2416_irq_wdtac97,
-			IRQ_S3C2443_WDT, IRQ_S3C2443_AC97);
-
 	s3c2416_irq_add_second();
 }
 
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 06/10] ARM: S3C24XX: assimilate s3c2416 subirqs into new structure
@ 2012-11-18  0:55   ` Heiko Stübner
  0 siblings, 0 replies; 24+ messages in thread
From: Heiko Stübner @ 2012-11-18  0:55 UTC (permalink / raw)
  To: linux-arm-kernel

The contents of the base interrupt register is identical for
s3c2443 and s3c2416/2450, so keep it separate already.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
 arch/arm/plat-s3c24xx/irq.c |  257 ++++++++++++-------------------------------
 1 files changed, 72 insertions(+), 185 deletions(-)

diff --git a/arch/arm/plat-s3c24xx/irq.c b/arch/arm/plat-s3c24xx/irq.c
index ca60486..ace7e34 100644
--- a/arch/arm/plat-s3c24xx/irq.c
+++ b/arch/arm/plat-s3c24xx/irq.c
@@ -762,158 +762,44 @@ struct syscore_ops s3c24xx_irq_syscore_ops = {
 };
 #endif
 
-#ifdef CONFIG_CPU_S3C2416
-#define INTMSK(start, end) ((1 << ((end) + 1 - (start))) - 1)
-
-static inline void s3c2416_irq_demux(unsigned int irq, unsigned int len)
-{
-	unsigned int subsrc, submsk;
-	unsigned int end;
-
-	/* read the current pending interrupts, and the mask
-	 * for what it is available */
-
-	subsrc = __raw_readl(S3C2410_SUBSRCPND);
-	submsk = __raw_readl(S3C2410_INTSUBMSK);
-
-	subsrc  &= ~submsk;
-	subsrc >>= (irq - S3C2410_IRQSUB(0));
-	subsrc  &= (1 << len)-1;
-
-	end = len + irq;
-
-	for (; irq < end && subsrc; irq++) {
-		if (subsrc & 1)
-			generic_handle_irq(irq);
-
-		subsrc >>= 1;
-	}
-}
-
-/* WDT/AC97 sub interrupts */
-
-static void s3c2416_irq_demux_wdtac97(unsigned int irq, struct irq_desc *desc)
-{
-	s3c2416_irq_demux(IRQ_S3C2443_WDT, 4);
-}
-
-#define INTMSK_WDTAC97	(1UL << (IRQ_WDT - IRQ_EINT0))
-#define SUBMSK_WDTAC97	INTMSK(IRQ_S3C2443_WDT, IRQ_S3C2443_AC97)
-
-static void s3c2416_irq_wdtac97_mask(struct irq_data *data)
-{
-	s3c_irqsub_mask(data->irq, INTMSK_WDTAC97, SUBMSK_WDTAC97);
-}
-
-static void s3c2416_irq_wdtac97_unmask(struct irq_data *data)
-{
-	s3c_irqsub_unmask(data->irq, INTMSK_WDTAC97);
-}
-
-static void s3c2416_irq_wdtac97_ack(struct irq_data *data)
-{
-	s3c_irqsub_maskack(data->irq, INTMSK_WDTAC97, SUBMSK_WDTAC97);
-}
-
-static struct irq_chip s3c2416_irq_wdtac97 = {
-	.irq_mask	= s3c2416_irq_wdtac97_mask,
-	.irq_unmask	= s3c2416_irq_wdtac97_unmask,
-	.irq_ack	= s3c2416_irq_wdtac97_ack,
-};
-
-/* LCD sub interrupts */
-
-static void s3c2416_irq_demux_lcd(unsigned int irq, struct irq_desc *desc)
-{
-	s3c2416_irq_demux(IRQ_S3C2443_LCD1, 4);
-}
-
-#define INTMSK_LCD	(1UL << (IRQ_LCD - IRQ_EINT0))
-#define SUBMSK_LCD	INTMSK(IRQ_S3C2443_LCD1, IRQ_S3C2443_LCD4)
-
-static void s3c2416_irq_lcd_mask(struct irq_data *data)
-{
-	s3c_irqsub_mask(data->irq, INTMSK_LCD, SUBMSK_LCD);
-}
-
-static void s3c2416_irq_lcd_unmask(struct irq_data *data)
-{
-	s3c_irqsub_unmask(data->irq, INTMSK_LCD);
-}
-
-static void s3c2416_irq_lcd_ack(struct irq_data *data)
-{
-	s3c_irqsub_maskack(data->irq, INTMSK_LCD, SUBMSK_LCD);
-}
-
-static struct irq_chip s3c2416_irq_lcd = {
-	.irq_mask	= s3c2416_irq_lcd_mask,
-	.irq_unmask	= s3c2416_irq_lcd_unmask,
-	.irq_ack	= s3c2416_irq_lcd_ack,
-};
-
-/* DMA sub interrupts */
-
-static void s3c2416_irq_demux_dma(unsigned int irq, struct irq_desc *desc)
-{
-	s3c2416_irq_demux(IRQ_S3C2443_DMA0, 6);
-}
-
-#define INTMSK_DMA	(1UL << (IRQ_S3C2443_DMA - IRQ_EINT0))
-#define SUBMSK_DMA	INTMSK(IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5)
-
-
-static void s3c2416_irq_dma_mask(struct irq_data *data)
-{
-	s3c_irqsub_mask(data->irq, INTMSK_DMA, SUBMSK_DMA);
-}
-
-static void s3c2416_irq_dma_unmask(struct irq_data *data)
-{
-	s3c_irqsub_unmask(data->irq, INTMSK_DMA);
-}
-
-static void s3c2416_irq_dma_ack(struct irq_data *data)
-{
-	s3c_irqsub_maskack(data->irq, INTMSK_DMA, SUBMSK_DMA);
-}
-
-static struct irq_chip s3c2416_irq_dma = {
-	.irq_mask	= s3c2416_irq_dma_mask,
-	.irq_unmask	= s3c2416_irq_dma_unmask,
-	.irq_ack	= s3c2416_irq_dma_ack,
+#if defined CONFIG_CPU_S3C2416 || defined CONFIG_CPU_S3C2443
+struct s3c_irq_data init_s3c2443base[32] = {
+	{ .type = S3C_IRQTYPE_EINT0T4, }, /* EINT0 */
+	{ .type = S3C_IRQTYPE_EINT0T4, }, /* EINT1 */
+	{ .type = S3C_IRQTYPE_EINT0T4, }, /* EINT2 */
+	{ .type = S3C_IRQTYPE_EINT0T4, }, /* EINT3 */
+	{ .type = S3C_IRQTYPE_PARENT, }, /* EINT4to7 */
+	{ .type = S3C_IRQTYPE_PARENT, }, /* EINT8to23 */
+	{ .type = S3C_IRQTYPE_PARENT, }, /* CAM on S3C2443/2450 */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* nBATT_FLT */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* TICK */
+	{ .type = S3C_IRQTYPE_PARENT, }, /* WDT/AC97 */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* TIMER0 */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* TIMER1 */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* TIMER2 */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* TIMER3 */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* TIMER4 */
+	{ .type = S3C_IRQTYPE_PARENT, }, /* UART2 */
+	{ .type = S3C_IRQTYPE_PARENT, }, /* LCD */
+	{ .type = S3C_IRQTYPE_PARENT, }, /* DMA */
+	{ .type = S3C_IRQTYPE_PARENT, }, /* UART3 */
+	{ .type = S3C_IRQTYPE_NONE, }, /* CFON on S3C2443/2450 */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* SDI1 */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* SDI0 */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* SPI0 */
+	{ .type = S3C_IRQTYPE_PARENT, }, /* UART1 */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* NAND */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* USBD */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* USBH */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* IIC */
+	{ .type = S3C_IRQTYPE_PARENT, }, /* UART0 */
+	{ .type = S3C_IRQTYPE_NONE, }, /* SPI1 on S3C243/2450 */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* RTC */
+	{ .type = S3C_IRQTYPE_PARENT, }, /* ADCPARENT */
 };
+#endif
 
-/* UART3 sub interrupts */
-
-static void s3c2416_irq_demux_uart3(unsigned int irq, struct irq_desc *desc)
-{
-	s3c2416_irq_demux(IRQ_S3C2443_RX3, 3);
-}
-
-#define INTMSK_UART3	(1UL << (IRQ_S3C2443_UART3 - IRQ_EINT0))
-#define SUBMSK_UART3	(0x7 << (IRQ_S3C2443_RX3 - S3C2410_IRQSUB(0)))
-
-static void s3c2416_irq_uart3_mask(struct irq_data *data)
-{
-	s3c_irqsub_mask(data->irq, INTMSK_UART3, SUBMSK_UART3);
-}
-
-static void s3c2416_irq_uart3_unmask(struct irq_data *data)
-{
-	s3c_irqsub_unmask(data->irq, INTMSK_UART3);
-}
-
-static void s3c2416_irq_uart3_ack(struct irq_data *data)
-{
-	s3c_irqsub_maskack(data->irq, INTMSK_UART3, SUBMSK_UART3);
-}
-
-static struct irq_chip s3c2416_irq_uart3 = {
-	.irq_mask	= s3c2416_irq_uart3_mask,
-	.irq_unmask	= s3c2416_irq_uart3_unmask,
-	.irq_ack	= s3c2416_irq_uart3_ack,
-};
+#ifdef CONFIG_CPU_S3C2416
 
 /* second interrupt register */
 
@@ -952,27 +838,6 @@ struct irq_chip s3c2416_irq_second = {
 };
 
 
-/* IRQ initialisation code */
-
-static int s3c2416_add_sub(unsigned int base,
-				   void (*demux)(unsigned int,
-						 struct irq_desc *),
-				   struct irq_chip *chip,
-				   unsigned int start, unsigned int end)
-{
-	unsigned int irqno;
-
-	irq_set_chip_and_handler(base, &s3c_irq_level_chip, handle_level_irq);
-	irq_set_chained_handler(base, demux);
-
-	for (irqno = start; irqno <= end; irqno++) {
-		irq_set_chip_and_handler(irqno, chip, handle_level_irq);
-		set_irq_flags(irqno, IRQF_VALID);
-	}
-
-	return 0;
-}
-
 static void s3c2416_irq_add_second(void)
 {
 	unsigned long pend;
@@ -1009,26 +874,48 @@ static void s3c2416_irq_add_second(void)
 	}
 }
 
+struct s3c_irq_data init_s3c2416subint[32] = {
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 28 }, /* UART0-RX */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 28 }, /* UART0-TX */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 28 }, /* UART0-ERR */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 23 }, /* UART1-RX */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 23 }, /* UART1-TX */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 23 }, /* UART1-ERR */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 15 }, /* UART2-RX */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 15 }, /* UART2-TX */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 15 }, /* UART2-ERR */
+	{ .type = S3C_IRQTYPE_SUBEDGE, .parent_irq = 31 }, /* TC */
+	{ .type = S3C_IRQTYPE_SUBEDGE, .parent_irq = 31 }, /* ADC */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 6 }, /* CAM_C S3C2450 */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 6 }, /* CAM_P S3C2450 */
+	{ .type = S3C_IRQTYPE_NONE }, /* reserved */
+	{ .type = S3C_IRQTYPE_NONE }, /* reserved */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 16 }, /* LCD2 */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 16 }, /* LCD3 */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 16 }, /* LCD4 */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 17 }, /* DMA0 */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 17 }, /* DMA1 */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 17 }, /* DMA2 */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 17 }, /* DMA3 */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 17 }, /* DMA4 */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 17 }, /* DMA5 */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 18 }, /* UART3-RX */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 18 }, /* UART3-TX */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 18 }, /* UART3-ERR */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 9 }, /* WDT */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 9 }, /* AC97 */
+};
+
 void __init s3c2416_init_irq(void)
 {
+	/* override irq data */
+	s3c_intc[0].irqs = &init_s3c2443base[0];
+	s3c_intc[2].irqs = &init_s3c2416subint[0];
+
 	pr_info("S3C2416: IRQ Support\n");
 
 	s3c24xx_init_irq();
 
-	s3c2416_add_sub(IRQ_LCD, s3c2416_irq_demux_lcd, &s3c2416_irq_lcd,
-			IRQ_S3C2443_LCD2, IRQ_S3C2443_LCD4);
-
-	s3c2416_add_sub(IRQ_S3C2443_DMA, s3c2416_irq_demux_dma,
-			&s3c2416_irq_dma, IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5);
-
-	s3c2416_add_sub(IRQ_S3C2443_UART3, s3c2416_irq_demux_uart3,
-			&s3c2416_irq_uart3,
-			IRQ_S3C2443_RX3, IRQ_S3C2443_ERR3);
-
-	s3c2416_add_sub(IRQ_WDT, s3c2416_irq_demux_wdtac97,
-			&s3c2416_irq_wdtac97,
-			IRQ_S3C2443_WDT, IRQ_S3C2443_AC97);
-
 	s3c2416_irq_add_second();
 }
 
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 07/10] ARM: S3C24XX: assimilate second s3c2416 interrupt into new structure
  2012-11-18  0:51 ` Heiko Stübner
@ 2012-11-18  0:55   ` Heiko Stübner
  -1 siblings, 0 replies; 24+ messages in thread
From: Heiko Stübner @ 2012-11-18  0:55 UTC (permalink / raw)
  To: Kukjin Kim; +Cc: Ben Dooks, linux-arm-kernel, linux-samsung-soc

The interrupt ack,mask and unmask functions for the main interrupt
register are also able to handle the second one of the s3c2416.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
 arch/arm/plat-s3c24xx/irq.c |  118 ++++++++++++++++---------------------------
 1 files changed, 43 insertions(+), 75 deletions(-)

diff --git a/arch/arm/plat-s3c24xx/irq.c b/arch/arm/plat-s3c24xx/irq.c
index ace7e34..675a5f9 100644
--- a/arch/arm/plat-s3c24xx/irq.c
+++ b/arch/arm/plat-s3c24xx/irq.c
@@ -22,6 +22,7 @@
 #include <linux/ioport.h>
 #include <linux/device.h>
 #include <linux/syscore_ops.h>
+#include <linux/slab.h>
 
 #include <linux/irqdomain.h>
 
@@ -54,6 +55,9 @@
 /* s3c_irqext_chip + edge handler */
 #define S3C_IRQTYPE_SUBEINT	6
 
+/* s3c2416_irq2_chip + edge handler */
+#define S3C_IRQTYPE_S3C2416	7
+
 struct s3c_irq_data {
 	unsigned int type;
 	unsigned long parent_irq;
@@ -164,6 +168,13 @@ struct irq_chip s3c_irq_chip = {
 	.irq_set_wake	= s3c_irq_wake
 };
 
+struct irq_chip s3c2416_irq_second = {
+	.name		= "s3c2416",
+	.irq_ack	= s3c_irq_ack,
+	.irq_mask	= s3c_irq_mask,
+	.irq_unmask	= s3c_irq_unmask,
+};
+
 static void s3c_irqext_ack(struct irq_data *data)
 {
 	struct s3c_irq_intc *intc = data->domain->host_data;
@@ -516,6 +527,11 @@ static int s3c24xx_irq_map(struct irq_domain *h, unsigned int virq,
 		set_irq_flags(virq, IRQF_VALID);
 		attach_to_parent = true;
 		break;
+	case S3C_IRQTYPE_S3C2416:
+		irq_set_chip_and_handler(virq, &s3c2416_irq_second,
+					 handle_edge_irq);
+		set_irq_flags(virq, IRQF_VALID);
+		break;
 	default:
 		pr_err("irq-s3c24xx: unsupported irqtype %d\n", irq_data->type);
 		return -EINVAL;
@@ -800,80 +816,6 @@ struct s3c_irq_data init_s3c2443base[32] = {
 #endif
 
 #ifdef CONFIG_CPU_S3C2416
-
-/* second interrupt register */
-
-static inline void s3c2416_irq_ack_second(struct irq_data *data)
-{
-	unsigned long bitval = 1UL << (data->irq - IRQ_S3C2416_2D);
-
-	__raw_writel(bitval, S3C2416_SRCPND2);
-	__raw_writel(bitval, S3C2416_INTPND2);
-}
-
-static void s3c2416_irq_mask_second(struct irq_data *data)
-{
-	unsigned long bitval = 1UL << (data->irq - IRQ_S3C2416_2D);
-	unsigned long mask;
-
-	mask = __raw_readl(S3C2416_INTMSK2);
-	mask |= bitval;
-	__raw_writel(mask, S3C2416_INTMSK2);
-}
-
-static void s3c2416_irq_unmask_second(struct irq_data *data)
-{
-	unsigned long bitval = 1UL << (data->irq - IRQ_S3C2416_2D);
-	unsigned long mask;
-
-	mask = __raw_readl(S3C2416_INTMSK2);
-	mask &= ~bitval;
-	__raw_writel(mask, S3C2416_INTMSK2);
-}
-
-struct irq_chip s3c2416_irq_second = {
-	.irq_ack	= s3c2416_irq_ack_second,
-	.irq_mask	= s3c2416_irq_mask_second,
-	.irq_unmask	= s3c2416_irq_unmask_second,
-};
-
-
-static void s3c2416_irq_add_second(void)
-{
-	unsigned long pend;
-	unsigned long last;
-	int irqno;
-	int i;
-
-	/* first, clear all interrupts pending... */
-	last = 0;
-	for (i = 0; i < 4; i++) {
-		pend = __raw_readl(S3C2416_INTPND2);
-
-		if (pend == 0 || pend == last)
-			break;
-
-		__raw_writel(pend, S3C2416_SRCPND2);
-		__raw_writel(pend, S3C2416_INTPND2);
-		printk(KERN_INFO "irq: clearing pending status %08x\n",
-		       (int)pend);
-		last = pend;
-	}
-
-	for (irqno = IRQ_S3C2416_2D; irqno <= IRQ_S3C2416_I2S1; irqno++) {
-		switch (irqno) {
-		case IRQ_S3C2416_RESERVED2:
-		case IRQ_S3C2416_RESERVED3:
-			/* no IRQ here */
-			break;
-		default:
-			irq_set_chip_and_handler(irqno, &s3c2416_irq_second,
-						 handle_edge_irq);
-			set_irq_flags(irqno, IRQF_VALID);
-		}
-	}
-}
-
 struct s3c_irq_data init_s3c2416subint[32] = {
 	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 28 }, /* UART0-RX */
 	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 28 }, /* UART0-TX */
@@ -906,8 +848,21 @@ struct s3c_irq_data init_s3c2416subint[32] = {
 	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 9 }, /* AC97 */
 };
 
+struct s3c_irq_data init_s3c2416_second[32] = {
+	{ .type = S3C_IRQTYPE_S3C2416 }, /* 2D */
+	{ .type = S3C_IRQTYPE_S3C2416 }, /* IIC1 */
+	{ .type = S3C_IRQTYPE_NONE }, /* reserved */
+	{ .type = S3C_IRQTYPE_NONE }, /* reserved */
+	{ .type = S3C_IRQTYPE_S3C2416 }, /* PCM0 */
+	{ .type = S3C_IRQTYPE_S3C2416 }, /* PCM1 */
+	{ .type = S3C_IRQTYPE_S3C2416 }, /* I2S0 */
+	{ .type = S3C_IRQTYPE_S3C2416 }, /* I2S1 */
+};
+
 void __init s3c2416_init_irq(void)
 {
+	struct s3c_irq_intc *s3c_intc2;
+
 	/* override irq data */
 	s3c_intc[0].irqs = &init_s3c2443base[0];
 	s3c_intc[2].irqs = &init_s3c2416subint[0];
@@ -916,7 +871,20 @@ void __init s3c2416_init_irq(void)
 
 	s3c24xx_init_irq();
 
-	s3c2416_irq_add_second();
+	s3c_intc2 = kzalloc(sizeof(struct s3c_irq_intc), GFP_KERNEL);
+	if (!s3c_intc2) {
+		pr_err("irq: failed to allocate memory for second controller\n");
+		return;
+	}
+
+	s3c_intc2->reg_pending = S3C2416_SRCPND2,
+	s3c_intc2->reg_intpnd = S3C2416_INTPND2,
+	s3c_intc2->reg_mask = S3C2416_INTMSK2,
+	s3c_intc2->irqs = &init_s3c2416_second[0],
+
+	s3c24xx_clear_intc(s3c_intc2);
+	s3c_intc2->domain = irq_domain_add_legacy(NULL, 8, IRQ_S3C2416_2D, 0,
+						  &s3c24xx_irq_ops, s3c_intc2);
 }
 
 #ifdef CONFIG_PM
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 07/10] ARM: S3C24XX: assimilate second s3c2416 interrupt into new structure
@ 2012-11-18  0:55   ` Heiko Stübner
  0 siblings, 0 replies; 24+ messages in thread
From: Heiko Stübner @ 2012-11-18  0:55 UTC (permalink / raw)
  To: linux-arm-kernel

The interrupt ack,mask and unmask functions for the main interrupt
register are also able to handle the second one of the s3c2416.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
 arch/arm/plat-s3c24xx/irq.c |  118 ++++++++++++++++---------------------------
 1 files changed, 43 insertions(+), 75 deletions(-)

diff --git a/arch/arm/plat-s3c24xx/irq.c b/arch/arm/plat-s3c24xx/irq.c
index ace7e34..675a5f9 100644
--- a/arch/arm/plat-s3c24xx/irq.c
+++ b/arch/arm/plat-s3c24xx/irq.c
@@ -22,6 +22,7 @@
 #include <linux/ioport.h>
 #include <linux/device.h>
 #include <linux/syscore_ops.h>
+#include <linux/slab.h>
 
 #include <linux/irqdomain.h>
 
@@ -54,6 +55,9 @@
 /* s3c_irqext_chip + edge handler */
 #define S3C_IRQTYPE_SUBEINT	6
 
+/* s3c2416_irq2_chip + edge handler */
+#define S3C_IRQTYPE_S3C2416	7
+
 struct s3c_irq_data {
 	unsigned int type;
 	unsigned long parent_irq;
@@ -164,6 +168,13 @@ struct irq_chip s3c_irq_chip = {
 	.irq_set_wake	= s3c_irq_wake
 };
 
+struct irq_chip s3c2416_irq_second = {
+	.name		= "s3c2416",
+	.irq_ack	= s3c_irq_ack,
+	.irq_mask	= s3c_irq_mask,
+	.irq_unmask	= s3c_irq_unmask,
+};
+
 static void s3c_irqext_ack(struct irq_data *data)
 {
 	struct s3c_irq_intc *intc = data->domain->host_data;
@@ -516,6 +527,11 @@ static int s3c24xx_irq_map(struct irq_domain *h, unsigned int virq,
 		set_irq_flags(virq, IRQF_VALID);
 		attach_to_parent = true;
 		break;
+	case S3C_IRQTYPE_S3C2416:
+		irq_set_chip_and_handler(virq, &s3c2416_irq_second,
+					 handle_edge_irq);
+		set_irq_flags(virq, IRQF_VALID);
+		break;
 	default:
 		pr_err("irq-s3c24xx: unsupported irqtype %d\n", irq_data->type);
 		return -EINVAL;
@@ -800,80 +816,6 @@ struct s3c_irq_data init_s3c2443base[32] = {
 #endif
 
 #ifdef CONFIG_CPU_S3C2416
-
-/* second interrupt register */
-
-static inline void s3c2416_irq_ack_second(struct irq_data *data)
-{
-	unsigned long bitval = 1UL << (data->irq - IRQ_S3C2416_2D);
-
-	__raw_writel(bitval, S3C2416_SRCPND2);
-	__raw_writel(bitval, S3C2416_INTPND2);
-}
-
-static void s3c2416_irq_mask_second(struct irq_data *data)
-{
-	unsigned long bitval = 1UL << (data->irq - IRQ_S3C2416_2D);
-	unsigned long mask;
-
-	mask = __raw_readl(S3C2416_INTMSK2);
-	mask |= bitval;
-	__raw_writel(mask, S3C2416_INTMSK2);
-}
-
-static void s3c2416_irq_unmask_second(struct irq_data *data)
-{
-	unsigned long bitval = 1UL << (data->irq - IRQ_S3C2416_2D);
-	unsigned long mask;
-
-	mask = __raw_readl(S3C2416_INTMSK2);
-	mask &= ~bitval;
-	__raw_writel(mask, S3C2416_INTMSK2);
-}
-
-struct irq_chip s3c2416_irq_second = {
-	.irq_ack	= s3c2416_irq_ack_second,
-	.irq_mask	= s3c2416_irq_mask_second,
-	.irq_unmask	= s3c2416_irq_unmask_second,
-};
-
-
-static void s3c2416_irq_add_second(void)
-{
-	unsigned long pend;
-	unsigned long last;
-	int irqno;
-	int i;
-
-	/* first, clear all interrupts pending... */
-	last = 0;
-	for (i = 0; i < 4; i++) {
-		pend = __raw_readl(S3C2416_INTPND2);
-
-		if (pend == 0 || pend == last)
-			break;
-
-		__raw_writel(pend, S3C2416_SRCPND2);
-		__raw_writel(pend, S3C2416_INTPND2);
-		printk(KERN_INFO "irq: clearing pending status %08x\n",
-		       (int)pend);
-		last = pend;
-	}
-
-	for (irqno = IRQ_S3C2416_2D; irqno <= IRQ_S3C2416_I2S1; irqno++) {
-		switch (irqno) {
-		case IRQ_S3C2416_RESERVED2:
-		case IRQ_S3C2416_RESERVED3:
-			/* no IRQ here */
-			break;
-		default:
-			irq_set_chip_and_handler(irqno, &s3c2416_irq_second,
-						 handle_edge_irq);
-			set_irq_flags(irqno, IRQF_VALID);
-		}
-	}
-}
-
 struct s3c_irq_data init_s3c2416subint[32] = {
 	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 28 }, /* UART0-RX */
 	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 28 }, /* UART0-TX */
@@ -906,8 +848,21 @@ struct s3c_irq_data init_s3c2416subint[32] = {
 	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 9 }, /* AC97 */
 };
 
+struct s3c_irq_data init_s3c2416_second[32] = {
+	{ .type = S3C_IRQTYPE_S3C2416 }, /* 2D */
+	{ .type = S3C_IRQTYPE_S3C2416 }, /* IIC1 */
+	{ .type = S3C_IRQTYPE_NONE }, /* reserved */
+	{ .type = S3C_IRQTYPE_NONE }, /* reserved */
+	{ .type = S3C_IRQTYPE_S3C2416 }, /* PCM0 */
+	{ .type = S3C_IRQTYPE_S3C2416 }, /* PCM1 */
+	{ .type = S3C_IRQTYPE_S3C2416 }, /* I2S0 */
+	{ .type = S3C_IRQTYPE_S3C2416 }, /* I2S1 */
+};
+
 void __init s3c2416_init_irq(void)
 {
+	struct s3c_irq_intc *s3c_intc2;
+
 	/* override irq data */
 	s3c_intc[0].irqs = &init_s3c2443base[0];
 	s3c_intc[2].irqs = &init_s3c2416subint[0];
@@ -916,7 +871,20 @@ void __init s3c2416_init_irq(void)
 
 	s3c24xx_init_irq();
 
-	s3c2416_irq_add_second();
+	s3c_intc2 = kzalloc(sizeof(struct s3c_irq_intc), GFP_KERNEL);
+	if (!s3c_intc2) {
+		pr_err("irq: failed to allocate memory for second controller\n");
+		return;
+	}
+
+	s3c_intc2->reg_pending = S3C2416_SRCPND2,
+	s3c_intc2->reg_intpnd = S3C2416_INTPND2,
+	s3c_intc2->reg_mask = S3C2416_INTMSK2,
+	s3c_intc2->irqs = &init_s3c2416_second[0],
+
+	s3c24xx_clear_intc(s3c_intc2);
+	s3c_intc2->domain = irq_domain_add_legacy(NULL, 8, IRQ_S3C2416_2D, 0,
+						  &s3c24xx_irq_ops, s3c_intc2);
 }
 
 #ifdef CONFIG_PM
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 08/10] ARM: S3C24XX: move s3c2443 irq code to irq.c
  2012-11-18  0:51 ` Heiko Stübner
@ 2012-11-18  0:56   ` Heiko Stübner
  -1 siblings, 0 replies; 24+ messages in thread
From: Heiko Stübner @ 2012-11-18  0:56 UTC (permalink / raw)
  To: Kukjin Kim; +Cc: Ben Dooks, linux-arm-kernel, linux-samsung-soc

Prequisite for further optimizations.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
 arch/arm/mach-s3c24xx/Makefile      |    2 +-
 arch/arm/mach-s3c24xx/irq-s3c2443.c |  281 -----------------------------------
 arch/arm/plat-s3c24xx/irq.c         |  243 ++++++++++++++++++++++++++++++
 3 files changed, 244 insertions(+), 282 deletions(-)
 delete mode 100644 arch/arm/mach-s3c24xx/irq-s3c2443.c

diff --git a/arch/arm/mach-s3c24xx/Makefile b/arch/arm/mach-s3c24xx/Makefile
index 30904c9..6019b7c 100644
--- a/arch/arm/mach-s3c24xx/Makefile
+++ b/arch/arm/mach-s3c24xx/Makefile
@@ -33,7 +33,7 @@ obj-$(CONFIG_CPU_S3C2442)	+= s3c2442.o
 obj-$(CONFIG_CPU_S3C244X)	+= s3c244x.o irq-s3c244x.o clock-s3c244x.o
 obj-$(CONFIG_S3C2440_DMA)	+= dma-s3c2440.o
 
-obj-$(CONFIG_CPU_S3C2443)	+= s3c2443.o irq-s3c2443.o clock-s3c2443.o
+obj-$(CONFIG_CPU_S3C2443)	+= s3c2443.o clock-s3c2443.o
 
 # PM
 
diff --git a/arch/arm/mach-s3c24xx/irq-s3c2443.c b/arch/arm/mach-s3c24xx/irq-s3c2443.c
deleted file mode 100644
index 5e69109..0000000
--- a/arch/arm/mach-s3c24xx/irq-s3c2443.c
+++ /dev/null
@@ -1,281 +0,0 @@
-/* linux/arch/arm/mach-s3c2443/irq.c
- *
- * Copyright (c) 2007 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
-*/
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/device.h>
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-#include <asm/irq.h>
-
-#include <asm/mach/irq.h>
-
-#include <mach/regs-irq.h>
-#include <mach/regs-gpio.h>
-
-#include <plat/cpu.h>
-#include <plat/pm.h>
-#include <plat/irq.h>
-
-#define INTMSK(start, end) ((1 << ((end) + 1 - (start))) - 1)
-
-static inline void s3c2443_irq_demux(unsigned int irq, unsigned int len)
-{
-	unsigned int subsrc, submsk;
-	unsigned int end;
-
-	/* read the current pending interrupts, and the mask
-	 * for what it is available */
-
-	subsrc = __raw_readl(S3C2410_SUBSRCPND);
-	submsk = __raw_readl(S3C2410_INTSUBMSK);
-
-	subsrc  &= ~submsk;
-	subsrc >>= (irq - S3C2410_IRQSUB(0));
-	subsrc  &= (1 << len)-1;
-
-	end = len + irq;
-
-	for (; irq < end && subsrc; irq++) {
-		if (subsrc & 1)
-			generic_handle_irq(irq);
-
-		subsrc >>= 1;
-	}
-}
-
-/* WDT/AC97 sub interrupts */
-
-static void s3c2443_irq_demux_wdtac97(unsigned int irq, struct irq_desc *desc)
-{
-	s3c2443_irq_demux(IRQ_S3C2443_WDT, 4);
-}
-
-#define INTMSK_WDTAC97	(1UL << (IRQ_WDT - IRQ_EINT0))
-#define SUBMSK_WDTAC97	INTMSK(IRQ_S3C2443_WDT, IRQ_S3C2443_AC97)
-
-static void s3c2443_irq_wdtac97_mask(struct irq_data *data)
-{
-	s3c_irqsub_mask(data->irq, INTMSK_WDTAC97, SUBMSK_WDTAC97);
-}
-
-static void s3c2443_irq_wdtac97_unmask(struct irq_data *data)
-{
-	s3c_irqsub_unmask(data->irq, INTMSK_WDTAC97);
-}
-
-static void s3c2443_irq_wdtac97_ack(struct irq_data *data)
-{
-	s3c_irqsub_maskack(data->irq, INTMSK_WDTAC97, SUBMSK_WDTAC97);
-}
-
-static struct irq_chip s3c2443_irq_wdtac97 = {
-	.irq_mask	= s3c2443_irq_wdtac97_mask,
-	.irq_unmask	= s3c2443_irq_wdtac97_unmask,
-	.irq_ack	= s3c2443_irq_wdtac97_ack,
-};
-
-/* LCD sub interrupts */
-
-static void s3c2443_irq_demux_lcd(unsigned int irq, struct irq_desc *desc)
-{
-	s3c2443_irq_demux(IRQ_S3C2443_LCD1, 4);
-}
-
-#define INTMSK_LCD	(1UL << (IRQ_LCD - IRQ_EINT0))
-#define SUBMSK_LCD	INTMSK(IRQ_S3C2443_LCD1, IRQ_S3C2443_LCD4)
-
-static void s3c2443_irq_lcd_mask(struct irq_data *data)
-{
-	s3c_irqsub_mask(data->irq, INTMSK_LCD, SUBMSK_LCD);
-}
-
-static void s3c2443_irq_lcd_unmask(struct irq_data *data)
-{
-	s3c_irqsub_unmask(data->irq, INTMSK_LCD);
-}
-
-static void s3c2443_irq_lcd_ack(struct irq_data *data)
-{
-	s3c_irqsub_maskack(data->irq, INTMSK_LCD, SUBMSK_LCD);
-}
-
-static struct irq_chip s3c2443_irq_lcd = {
-	.irq_mask	= s3c2443_irq_lcd_mask,
-	.irq_unmask	= s3c2443_irq_lcd_unmask,
-	.irq_ack	= s3c2443_irq_lcd_ack,
-};
-
-/* DMA sub interrupts */
-
-static void s3c2443_irq_demux_dma(unsigned int irq, struct irq_desc *desc)
-{
-	s3c2443_irq_demux(IRQ_S3C2443_DMA0, 6);
-}
-
-#define INTMSK_DMA	(1UL << (IRQ_S3C2443_DMA - IRQ_EINT0))
-#define SUBMSK_DMA	INTMSK(IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5)
-
-static void s3c2443_irq_dma_mask(struct irq_data *data)
-{
-	s3c_irqsub_mask(data->irq, INTMSK_DMA, SUBMSK_DMA);
-}
-
-static void s3c2443_irq_dma_unmask(struct irq_data *data)
-{
-	s3c_irqsub_unmask(data->irq, INTMSK_DMA);
-}
-
-static void s3c2443_irq_dma_ack(struct irq_data *data)
-{
-	s3c_irqsub_maskack(data->irq, INTMSK_DMA, SUBMSK_DMA);
-}
-
-static struct irq_chip s3c2443_irq_dma = {
-	.irq_mask	= s3c2443_irq_dma_mask,
-	.irq_unmask	= s3c2443_irq_dma_unmask,
-	.irq_ack	= s3c2443_irq_dma_ack,
-};
-
-/* UART3 sub interrupts */
-
-static void s3c2443_irq_demux_uart3(unsigned int irq, struct irq_desc *desc)
-{
-	s3c2443_irq_demux(IRQ_S3C2443_RX3, 3);
-}
-
-#define INTMSK_UART3	(1UL << (IRQ_S3C2443_UART3 - IRQ_EINT0))
-#define SUBMSK_UART3	(0x7 << (IRQ_S3C2443_RX3 - S3C2410_IRQSUB(0)))
-
-static void s3c2443_irq_uart3_mask(struct irq_data *data)
-{
-	s3c_irqsub_mask(data->irq, INTMSK_UART3, SUBMSK_UART3);
-}
-
-static void s3c2443_irq_uart3_unmask(struct irq_data *data)
-{
-	s3c_irqsub_unmask(data->irq, INTMSK_UART3);
-}
-
-static void s3c2443_irq_uart3_ack(struct irq_data *data)
-{
-	s3c_irqsub_maskack(data->irq, INTMSK_UART3, SUBMSK_UART3);
-}
-
-static struct irq_chip s3c2443_irq_uart3 = {
-	.irq_mask	= s3c2443_irq_uart3_mask,
-	.irq_unmask	= s3c2443_irq_uart3_unmask,
-	.irq_ack	= s3c2443_irq_uart3_ack,
-};
-
-/* CAM sub interrupts */
-
-static void s3c2443_irq_demux_cam(unsigned int irq, struct irq_desc *desc)
-{
-	s3c2443_irq_demux(IRQ_S3C2440_CAM_C, 4);
-}
-
-#define INTMSK_CAM	(1UL << (IRQ_CAM - IRQ_EINT0))
-#define SUBMSK_CAM	INTMSK(IRQ_S3C2440_CAM_C, IRQ_S3C2440_CAM_P)
-
-static void s3c2443_irq_cam_mask(struct irq_data *data)
-{
-	s3c_irqsub_mask(data->irq, INTMSK_CAM, SUBMSK_CAM);
-}
-
-static void s3c2443_irq_cam_unmask(struct irq_data *data)
-{
-	s3c_irqsub_unmask(data->irq, INTMSK_CAM);
-}
-
-static void s3c2443_irq_cam_ack(struct irq_data *data)
-{
-	s3c_irqsub_maskack(data->irq, INTMSK_CAM, SUBMSK_CAM);
-}
-
-static struct irq_chip s3c2443_irq_cam = {
-	.irq_mask	= s3c2443_irq_cam_mask,
-	.irq_unmask	= s3c2443_irq_cam_unmask,
-	.irq_ack	= s3c2443_irq_cam_ack,
-};
-
-/* IRQ initialisation code */
-
-static int s3c2443_add_sub(unsigned int base,
-				   void (*demux)(unsigned int,
-						 struct irq_desc *),
-				   struct irq_chip *chip,
-				   unsigned int start, unsigned int end)
-{
-	unsigned int irqno;
-
-	irq_set_chip_and_handler(base, &s3c_irq_level_chip, handle_level_irq);
-	irq_set_chained_handler(base, demux);
-
-	for (irqno = start; irqno <= end; irqno++) {
-		irq_set_chip_and_handler(irqno, chip, handle_level_irq);
-		set_irq_flags(irqno, IRQF_VALID);
-	}
-
-	return 0;
-}
-
-static int s3c2443_irq_add(struct device *dev,
-				  struct subsys_interface *sif)
-{
-	printk("S3C2443: IRQ Support\n");
-
-	s3c2443_add_sub(IRQ_CAM, s3c2443_irq_demux_cam, &s3c2443_irq_cam,
-			IRQ_S3C2440_CAM_C, IRQ_S3C2440_CAM_P);
-
-	s3c2443_add_sub(IRQ_LCD, s3c2443_irq_demux_lcd, &s3c2443_irq_lcd,
-			IRQ_S3C2443_LCD1, IRQ_S3C2443_LCD4);
-
-	s3c2443_add_sub(IRQ_S3C2443_DMA, s3c2443_irq_demux_dma,
-			&s3c2443_irq_dma, IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5);
-
-	s3c2443_add_sub(IRQ_S3C2443_UART3, s3c2443_irq_demux_uart3,
-			&s3c2443_irq_uart3,
-			IRQ_S3C2443_RX3, IRQ_S3C2443_ERR3);
-
-	s3c2443_add_sub(IRQ_WDT, s3c2443_irq_demux_wdtac97,
-			&s3c2443_irq_wdtac97,
-			IRQ_S3C2443_WDT, IRQ_S3C2443_AC97);
-
-	return 0;
-}
-
-static struct subsys_interface s3c2443_irq_interface = {
-	.name		= "s3c2443_irq",
-	.subsys		= &s3c2443_subsys,
-	.add_dev	= s3c2443_irq_add,
-};
-
-static int __init s3c2443_irq_init(void)
-{
-	return subsys_interface_register(&s3c2443_irq_interface);
-}
-
-arch_initcall(s3c2443_irq_init);
-
diff --git a/arch/arm/plat-s3c24xx/irq.c b/arch/arm/plat-s3c24xx/irq.c
index 675a5f9..d7baeaf 100644
--- a/arch/arm/plat-s3c24xx/irq.c
+++ b/arch/arm/plat-s3c24xx/irq.c
@@ -911,3 +911,246 @@ struct syscore_ops s3c2416_irq_syscore_ops = {
 #endif
 
 #endif
+
+#ifdef CONFIG_CPU_S3C2443
+#define INTMSK(start, end) ((1 << ((end) + 1 - (start))) - 1)
+
+static inline void s3c2443_irq_demux(unsigned int irq, unsigned int len)
+{
+	unsigned int subsrc, submsk;
+	unsigned int end;
+
+	/* read the current pending interrupts, and the mask
+	 * for what it is available */
+
+	subsrc = __raw_readl(S3C2410_SUBSRCPND);
+	submsk = __raw_readl(S3C2410_INTSUBMSK);
+
+	subsrc  &= ~submsk;
+	subsrc >>= (irq - S3C2410_IRQSUB(0));
+	subsrc  &= (1 << len)-1;
+
+	end = len + irq;
+
+	for (; irq < end && subsrc; irq++) {
+		if (subsrc & 1)
+			generic_handle_irq(irq);
+
+		subsrc >>= 1;
+	}
+}
+
+/* WDT/AC97 sub interrupts */
+
+static void s3c2443_irq_demux_wdtac97(unsigned int irq, struct irq_desc *desc)
+{
+	s3c2443_irq_demux(IRQ_S3C2443_WDT, 4);
+}
+
+#define INTMSK_WDTAC97	(1UL << (IRQ_WDT - IRQ_EINT0))
+#define SUBMSK_WDTAC97	INTMSK(IRQ_S3C2443_WDT, IRQ_S3C2443_AC97)
+
+static void s3c2443_irq_wdtac97_mask(struct irq_data *data)
+{
+	s3c_irqsub_mask(data->irq, INTMSK_WDTAC97, SUBMSK_WDTAC97);
+}
+
+static void s3c2443_irq_wdtac97_unmask(struct irq_data *data)
+{
+	s3c_irqsub_unmask(data->irq, INTMSK_WDTAC97);
+}
+
+static void s3c2443_irq_wdtac97_ack(struct irq_data *data)
+{
+	s3c_irqsub_maskack(data->irq, INTMSK_WDTAC97, SUBMSK_WDTAC97);
+}
+
+static struct irq_chip s3c2443_irq_wdtac97 = {
+	.irq_mask	= s3c2443_irq_wdtac97_mask,
+	.irq_unmask	= s3c2443_irq_wdtac97_unmask,
+	.irq_ack	= s3c2443_irq_wdtac97_ack,
+};
+
+/* LCD sub interrupts */
+
+static void s3c2443_irq_demux_lcd(unsigned int irq, struct irq_desc *desc)
+{
+	s3c2443_irq_demux(IRQ_S3C2443_LCD1, 4);
+}
+
+#define INTMSK_LCD	(1UL << (IRQ_LCD - IRQ_EINT0))
+#define SUBMSK_LCD	INTMSK(IRQ_S3C2443_LCD1, IRQ_S3C2443_LCD4)
+
+static void s3c2443_irq_lcd_mask(struct irq_data *data)
+{
+	s3c_irqsub_mask(data->irq, INTMSK_LCD, SUBMSK_LCD);
+}
+
+static void s3c2443_irq_lcd_unmask(struct irq_data *data)
+{
+	s3c_irqsub_unmask(data->irq, INTMSK_LCD);
+}
+
+static void s3c2443_irq_lcd_ack(struct irq_data *data)
+{
+	s3c_irqsub_maskack(data->irq, INTMSK_LCD, SUBMSK_LCD);
+}
+
+static struct irq_chip s3c2443_irq_lcd = {
+	.irq_mask	= s3c2443_irq_lcd_mask,
+	.irq_unmask	= s3c2443_irq_lcd_unmask,
+	.irq_ack	= s3c2443_irq_lcd_ack,
+};
+
+/* DMA sub interrupts */
+
+static void s3c2443_irq_demux_dma(unsigned int irq, struct irq_desc *desc)
+{
+	s3c2443_irq_demux(IRQ_S3C2443_DMA0, 6);
+}
+
+#define INTMSK_DMA	(1UL << (IRQ_S3C2443_DMA - IRQ_EINT0))
+#define SUBMSK_DMA	INTMSK(IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5)
+
+static void s3c2443_irq_dma_mask(struct irq_data *data)
+{
+	s3c_irqsub_mask(data->irq, INTMSK_DMA, SUBMSK_DMA);
+}
+
+static void s3c2443_irq_dma_unmask(struct irq_data *data)
+{
+	s3c_irqsub_unmask(data->irq, INTMSK_DMA);
+}
+
+static void s3c2443_irq_dma_ack(struct irq_data *data)
+{
+	s3c_irqsub_maskack(data->irq, INTMSK_DMA, SUBMSK_DMA);
+}
+
+static struct irq_chip s3c2443_irq_dma = {
+	.irq_mask	= s3c2443_irq_dma_mask,
+	.irq_unmask	= s3c2443_irq_dma_unmask,
+	.irq_ack	= s3c2443_irq_dma_ack,
+};
+
+/* UART3 sub interrupts */
+
+static void s3c2443_irq_demux_uart3(unsigned int irq, struct irq_desc *desc)
+{
+	s3c2443_irq_demux(IRQ_S3C2443_RX3, 3);
+}
+
+#define INTMSK_UART3	(1UL << (IRQ_S3C2443_UART3 - IRQ_EINT0))
+#define SUBMSK_UART3	(0x7 << (IRQ_S3C2443_RX3 - S3C2410_IRQSUB(0)))
+
+static void s3c2443_irq_uart3_mask(struct irq_data *data)
+{
+	s3c_irqsub_mask(data->irq, INTMSK_UART3, SUBMSK_UART3);
+}
+
+static void s3c2443_irq_uart3_unmask(struct irq_data *data)
+{
+	s3c_irqsub_unmask(data->irq, INTMSK_UART3);
+}
+
+static void s3c2443_irq_uart3_ack(struct irq_data *data)
+{
+	s3c_irqsub_maskack(data->irq, INTMSK_UART3, SUBMSK_UART3);
+}
+
+static struct irq_chip s3c2443_irq_uart3 = {
+	.irq_mask	= s3c2443_irq_uart3_mask,
+	.irq_unmask	= s3c2443_irq_uart3_unmask,
+	.irq_ack	= s3c2443_irq_uart3_ack,
+};
+
+/* CAM sub interrupts */
+
+static void s3c2443_irq_demux_cam(unsigned int irq, struct irq_desc *desc)
+{
+	s3c2443_irq_demux(IRQ_S3C2440_CAM_C, 4);
+}
+
+#define INTMSK_CAM	(1UL << (IRQ_CAM - IRQ_EINT0))
+#define SUBMSK_CAM	INTMSK(IRQ_S3C2440_CAM_C, IRQ_S3C2440_CAM_P)
+
+static void s3c2443_irq_cam_mask(struct irq_data *data)
+{
+	s3c_irqsub_mask(data->irq, INTMSK_CAM, SUBMSK_CAM);
+}
+
+static void s3c2443_irq_cam_unmask(struct irq_data *data)
+{
+	s3c_irqsub_unmask(data->irq, INTMSK_CAM);
+}
+
+static void s3c2443_irq_cam_ack(struct irq_data *data)
+{
+	s3c_irqsub_maskack(data->irq, INTMSK_CAM, SUBMSK_CAM);
+}
+
+static struct irq_chip s3c2443_irq_cam = {
+	.irq_mask	= s3c2443_irq_cam_mask,
+	.irq_unmask	= s3c2443_irq_cam_unmask,
+	.irq_ack	= s3c2443_irq_cam_ack,
+};
+
+/* IRQ initialisation code */
+
+static int s3c2443_add_sub(unsigned int base,
+				   void (*demux)(unsigned int,
+						 struct irq_desc *),
+				   struct irq_chip *chip,
+				   unsigned int start, unsigned int end)
+{
+	unsigned int irqno;
+
+	irq_set_chip_and_handler(base, &s3c_irq_level_chip, handle_level_irq);
+	irq_set_chained_handler(base, demux);
+
+	for (irqno = start; irqno <= end; irqno++) {
+		irq_set_chip_and_handler(irqno, chip, handle_level_irq);
+		set_irq_flags(irqno, IRQF_VALID);
+	}
+
+	return 0;
+}
+
+static int s3c2443_irq_add(struct device *dev,
+				  struct subsys_interface *sif)
+{
+	printk("S3C2443: IRQ Support\n");
+
+	s3c2443_add_sub(IRQ_CAM, s3c2443_irq_demux_cam, &s3c2443_irq_cam,
+			IRQ_S3C2440_CAM_C, IRQ_S3C2440_CAM_P);
+
+	s3c2443_add_sub(IRQ_LCD, s3c2443_irq_demux_lcd, &s3c2443_irq_lcd,
+			IRQ_S3C2443_LCD1, IRQ_S3C2443_LCD4);
+
+	s3c2443_add_sub(IRQ_S3C2443_DMA, s3c2443_irq_demux_dma,
+			&s3c2443_irq_dma, IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5);
+
+	s3c2443_add_sub(IRQ_S3C2443_UART3, s3c2443_irq_demux_uart3,
+			&s3c2443_irq_uart3,
+			IRQ_S3C2443_RX3, IRQ_S3C2443_ERR3);
+
+	s3c2443_add_sub(IRQ_WDT, s3c2443_irq_demux_wdtac97,
+			&s3c2443_irq_wdtac97,
+			IRQ_S3C2443_WDT, IRQ_S3C2443_AC97);
+
+	return 0;
+}
+
+static struct subsys_interface s3c2443_irq_interface = {
+	.name		= "s3c2443_irq",
+	.subsys		= &s3c2443_subsys,
+	.add_dev	= s3c2443_irq_add,
+};
+
+static int __init s3c2443_irq_init(void)
+{
+	return subsys_interface_register(&s3c2443_irq_interface);
+}
+
+arch_initcall(s3c2443_irq_init);
+#endif
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 08/10] ARM: S3C24XX: move s3c2443 irq code to irq.c
@ 2012-11-18  0:56   ` Heiko Stübner
  0 siblings, 0 replies; 24+ messages in thread
From: Heiko Stübner @ 2012-11-18  0:56 UTC (permalink / raw)
  To: linux-arm-kernel

Prequisite for further optimizations.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
 arch/arm/mach-s3c24xx/Makefile      |    2 +-
 arch/arm/mach-s3c24xx/irq-s3c2443.c |  281 -----------------------------------
 arch/arm/plat-s3c24xx/irq.c         |  243 ++++++++++++++++++++++++++++++
 3 files changed, 244 insertions(+), 282 deletions(-)
 delete mode 100644 arch/arm/mach-s3c24xx/irq-s3c2443.c

diff --git a/arch/arm/mach-s3c24xx/Makefile b/arch/arm/mach-s3c24xx/Makefile
index 30904c9..6019b7c 100644
--- a/arch/arm/mach-s3c24xx/Makefile
+++ b/arch/arm/mach-s3c24xx/Makefile
@@ -33,7 +33,7 @@ obj-$(CONFIG_CPU_S3C2442)	+= s3c2442.o
 obj-$(CONFIG_CPU_S3C244X)	+= s3c244x.o irq-s3c244x.o clock-s3c244x.o
 obj-$(CONFIG_S3C2440_DMA)	+= dma-s3c2440.o
 
-obj-$(CONFIG_CPU_S3C2443)	+= s3c2443.o irq-s3c2443.o clock-s3c2443.o
+obj-$(CONFIG_CPU_S3C2443)	+= s3c2443.o clock-s3c2443.o
 
 # PM
 
diff --git a/arch/arm/mach-s3c24xx/irq-s3c2443.c b/arch/arm/mach-s3c24xx/irq-s3c2443.c
deleted file mode 100644
index 5e69109..0000000
--- a/arch/arm/mach-s3c24xx/irq-s3c2443.c
+++ /dev/null
@@ -1,281 +0,0 @@
-/* linux/arch/arm/mach-s3c2443/irq.c
- *
- * Copyright (c) 2007 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
-*/
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/device.h>
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-#include <asm/irq.h>
-
-#include <asm/mach/irq.h>
-
-#include <mach/regs-irq.h>
-#include <mach/regs-gpio.h>
-
-#include <plat/cpu.h>
-#include <plat/pm.h>
-#include <plat/irq.h>
-
-#define INTMSK(start, end) ((1 << ((end) + 1 - (start))) - 1)
-
-static inline void s3c2443_irq_demux(unsigned int irq, unsigned int len)
-{
-	unsigned int subsrc, submsk;
-	unsigned int end;
-
-	/* read the current pending interrupts, and the mask
-	 * for what it is available */
-
-	subsrc = __raw_readl(S3C2410_SUBSRCPND);
-	submsk = __raw_readl(S3C2410_INTSUBMSK);
-
-	subsrc  &= ~submsk;
-	subsrc >>= (irq - S3C2410_IRQSUB(0));
-	subsrc  &= (1 << len)-1;
-
-	end = len + irq;
-
-	for (; irq < end && subsrc; irq++) {
-		if (subsrc & 1)
-			generic_handle_irq(irq);
-
-		subsrc >>= 1;
-	}
-}
-
-/* WDT/AC97 sub interrupts */
-
-static void s3c2443_irq_demux_wdtac97(unsigned int irq, struct irq_desc *desc)
-{
-	s3c2443_irq_demux(IRQ_S3C2443_WDT, 4);
-}
-
-#define INTMSK_WDTAC97	(1UL << (IRQ_WDT - IRQ_EINT0))
-#define SUBMSK_WDTAC97	INTMSK(IRQ_S3C2443_WDT, IRQ_S3C2443_AC97)
-
-static void s3c2443_irq_wdtac97_mask(struct irq_data *data)
-{
-	s3c_irqsub_mask(data->irq, INTMSK_WDTAC97, SUBMSK_WDTAC97);
-}
-
-static void s3c2443_irq_wdtac97_unmask(struct irq_data *data)
-{
-	s3c_irqsub_unmask(data->irq, INTMSK_WDTAC97);
-}
-
-static void s3c2443_irq_wdtac97_ack(struct irq_data *data)
-{
-	s3c_irqsub_maskack(data->irq, INTMSK_WDTAC97, SUBMSK_WDTAC97);
-}
-
-static struct irq_chip s3c2443_irq_wdtac97 = {
-	.irq_mask	= s3c2443_irq_wdtac97_mask,
-	.irq_unmask	= s3c2443_irq_wdtac97_unmask,
-	.irq_ack	= s3c2443_irq_wdtac97_ack,
-};
-
-/* LCD sub interrupts */
-
-static void s3c2443_irq_demux_lcd(unsigned int irq, struct irq_desc *desc)
-{
-	s3c2443_irq_demux(IRQ_S3C2443_LCD1, 4);
-}
-
-#define INTMSK_LCD	(1UL << (IRQ_LCD - IRQ_EINT0))
-#define SUBMSK_LCD	INTMSK(IRQ_S3C2443_LCD1, IRQ_S3C2443_LCD4)
-
-static void s3c2443_irq_lcd_mask(struct irq_data *data)
-{
-	s3c_irqsub_mask(data->irq, INTMSK_LCD, SUBMSK_LCD);
-}
-
-static void s3c2443_irq_lcd_unmask(struct irq_data *data)
-{
-	s3c_irqsub_unmask(data->irq, INTMSK_LCD);
-}
-
-static void s3c2443_irq_lcd_ack(struct irq_data *data)
-{
-	s3c_irqsub_maskack(data->irq, INTMSK_LCD, SUBMSK_LCD);
-}
-
-static struct irq_chip s3c2443_irq_lcd = {
-	.irq_mask	= s3c2443_irq_lcd_mask,
-	.irq_unmask	= s3c2443_irq_lcd_unmask,
-	.irq_ack	= s3c2443_irq_lcd_ack,
-};
-
-/* DMA sub interrupts */
-
-static void s3c2443_irq_demux_dma(unsigned int irq, struct irq_desc *desc)
-{
-	s3c2443_irq_demux(IRQ_S3C2443_DMA0, 6);
-}
-
-#define INTMSK_DMA	(1UL << (IRQ_S3C2443_DMA - IRQ_EINT0))
-#define SUBMSK_DMA	INTMSK(IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5)
-
-static void s3c2443_irq_dma_mask(struct irq_data *data)
-{
-	s3c_irqsub_mask(data->irq, INTMSK_DMA, SUBMSK_DMA);
-}
-
-static void s3c2443_irq_dma_unmask(struct irq_data *data)
-{
-	s3c_irqsub_unmask(data->irq, INTMSK_DMA);
-}
-
-static void s3c2443_irq_dma_ack(struct irq_data *data)
-{
-	s3c_irqsub_maskack(data->irq, INTMSK_DMA, SUBMSK_DMA);
-}
-
-static struct irq_chip s3c2443_irq_dma = {
-	.irq_mask	= s3c2443_irq_dma_mask,
-	.irq_unmask	= s3c2443_irq_dma_unmask,
-	.irq_ack	= s3c2443_irq_dma_ack,
-};
-
-/* UART3 sub interrupts */
-
-static void s3c2443_irq_demux_uart3(unsigned int irq, struct irq_desc *desc)
-{
-	s3c2443_irq_demux(IRQ_S3C2443_RX3, 3);
-}
-
-#define INTMSK_UART3	(1UL << (IRQ_S3C2443_UART3 - IRQ_EINT0))
-#define SUBMSK_UART3	(0x7 << (IRQ_S3C2443_RX3 - S3C2410_IRQSUB(0)))
-
-static void s3c2443_irq_uart3_mask(struct irq_data *data)
-{
-	s3c_irqsub_mask(data->irq, INTMSK_UART3, SUBMSK_UART3);
-}
-
-static void s3c2443_irq_uart3_unmask(struct irq_data *data)
-{
-	s3c_irqsub_unmask(data->irq, INTMSK_UART3);
-}
-
-static void s3c2443_irq_uart3_ack(struct irq_data *data)
-{
-	s3c_irqsub_maskack(data->irq, INTMSK_UART3, SUBMSK_UART3);
-}
-
-static struct irq_chip s3c2443_irq_uart3 = {
-	.irq_mask	= s3c2443_irq_uart3_mask,
-	.irq_unmask	= s3c2443_irq_uart3_unmask,
-	.irq_ack	= s3c2443_irq_uart3_ack,
-};
-
-/* CAM sub interrupts */
-
-static void s3c2443_irq_demux_cam(unsigned int irq, struct irq_desc *desc)
-{
-	s3c2443_irq_demux(IRQ_S3C2440_CAM_C, 4);
-}
-
-#define INTMSK_CAM	(1UL << (IRQ_CAM - IRQ_EINT0))
-#define SUBMSK_CAM	INTMSK(IRQ_S3C2440_CAM_C, IRQ_S3C2440_CAM_P)
-
-static void s3c2443_irq_cam_mask(struct irq_data *data)
-{
-	s3c_irqsub_mask(data->irq, INTMSK_CAM, SUBMSK_CAM);
-}
-
-static void s3c2443_irq_cam_unmask(struct irq_data *data)
-{
-	s3c_irqsub_unmask(data->irq, INTMSK_CAM);
-}
-
-static void s3c2443_irq_cam_ack(struct irq_data *data)
-{
-	s3c_irqsub_maskack(data->irq, INTMSK_CAM, SUBMSK_CAM);
-}
-
-static struct irq_chip s3c2443_irq_cam = {
-	.irq_mask	= s3c2443_irq_cam_mask,
-	.irq_unmask	= s3c2443_irq_cam_unmask,
-	.irq_ack	= s3c2443_irq_cam_ack,
-};
-
-/* IRQ initialisation code */
-
-static int s3c2443_add_sub(unsigned int base,
-				   void (*demux)(unsigned int,
-						 struct irq_desc *),
-				   struct irq_chip *chip,
-				   unsigned int start, unsigned int end)
-{
-	unsigned int irqno;
-
-	irq_set_chip_and_handler(base, &s3c_irq_level_chip, handle_level_irq);
-	irq_set_chained_handler(base, demux);
-
-	for (irqno = start; irqno <= end; irqno++) {
-		irq_set_chip_and_handler(irqno, chip, handle_level_irq);
-		set_irq_flags(irqno, IRQF_VALID);
-	}
-
-	return 0;
-}
-
-static int s3c2443_irq_add(struct device *dev,
-				  struct subsys_interface *sif)
-{
-	printk("S3C2443: IRQ Support\n");
-
-	s3c2443_add_sub(IRQ_CAM, s3c2443_irq_demux_cam, &s3c2443_irq_cam,
-			IRQ_S3C2440_CAM_C, IRQ_S3C2440_CAM_P);
-
-	s3c2443_add_sub(IRQ_LCD, s3c2443_irq_demux_lcd, &s3c2443_irq_lcd,
-			IRQ_S3C2443_LCD1, IRQ_S3C2443_LCD4);
-
-	s3c2443_add_sub(IRQ_S3C2443_DMA, s3c2443_irq_demux_dma,
-			&s3c2443_irq_dma, IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5);
-
-	s3c2443_add_sub(IRQ_S3C2443_UART3, s3c2443_irq_demux_uart3,
-			&s3c2443_irq_uart3,
-			IRQ_S3C2443_RX3, IRQ_S3C2443_ERR3);
-
-	s3c2443_add_sub(IRQ_WDT, s3c2443_irq_demux_wdtac97,
-			&s3c2443_irq_wdtac97,
-			IRQ_S3C2443_WDT, IRQ_S3C2443_AC97);
-
-	return 0;
-}
-
-static struct subsys_interface s3c2443_irq_interface = {
-	.name		= "s3c2443_irq",
-	.subsys		= &s3c2443_subsys,
-	.add_dev	= s3c2443_irq_add,
-};
-
-static int __init s3c2443_irq_init(void)
-{
-	return subsys_interface_register(&s3c2443_irq_interface);
-}
-
-arch_initcall(s3c2443_irq_init);
-
diff --git a/arch/arm/plat-s3c24xx/irq.c b/arch/arm/plat-s3c24xx/irq.c
index 675a5f9..d7baeaf 100644
--- a/arch/arm/plat-s3c24xx/irq.c
+++ b/arch/arm/plat-s3c24xx/irq.c
@@ -911,3 +911,246 @@ struct syscore_ops s3c2416_irq_syscore_ops = {
 #endif
 
 #endif
+
+#ifdef CONFIG_CPU_S3C2443
+#define INTMSK(start, end) ((1 << ((end) + 1 - (start))) - 1)
+
+static inline void s3c2443_irq_demux(unsigned int irq, unsigned int len)
+{
+	unsigned int subsrc, submsk;
+	unsigned int end;
+
+	/* read the current pending interrupts, and the mask
+	 * for what it is available */
+
+	subsrc = __raw_readl(S3C2410_SUBSRCPND);
+	submsk = __raw_readl(S3C2410_INTSUBMSK);
+
+	subsrc  &= ~submsk;
+	subsrc >>= (irq - S3C2410_IRQSUB(0));
+	subsrc  &= (1 << len)-1;
+
+	end = len + irq;
+
+	for (; irq < end && subsrc; irq++) {
+		if (subsrc & 1)
+			generic_handle_irq(irq);
+
+		subsrc >>= 1;
+	}
+}
+
+/* WDT/AC97 sub interrupts */
+
+static void s3c2443_irq_demux_wdtac97(unsigned int irq, struct irq_desc *desc)
+{
+	s3c2443_irq_demux(IRQ_S3C2443_WDT, 4);
+}
+
+#define INTMSK_WDTAC97	(1UL << (IRQ_WDT - IRQ_EINT0))
+#define SUBMSK_WDTAC97	INTMSK(IRQ_S3C2443_WDT, IRQ_S3C2443_AC97)
+
+static void s3c2443_irq_wdtac97_mask(struct irq_data *data)
+{
+	s3c_irqsub_mask(data->irq, INTMSK_WDTAC97, SUBMSK_WDTAC97);
+}
+
+static void s3c2443_irq_wdtac97_unmask(struct irq_data *data)
+{
+	s3c_irqsub_unmask(data->irq, INTMSK_WDTAC97);
+}
+
+static void s3c2443_irq_wdtac97_ack(struct irq_data *data)
+{
+	s3c_irqsub_maskack(data->irq, INTMSK_WDTAC97, SUBMSK_WDTAC97);
+}
+
+static struct irq_chip s3c2443_irq_wdtac97 = {
+	.irq_mask	= s3c2443_irq_wdtac97_mask,
+	.irq_unmask	= s3c2443_irq_wdtac97_unmask,
+	.irq_ack	= s3c2443_irq_wdtac97_ack,
+};
+
+/* LCD sub interrupts */
+
+static void s3c2443_irq_demux_lcd(unsigned int irq, struct irq_desc *desc)
+{
+	s3c2443_irq_demux(IRQ_S3C2443_LCD1, 4);
+}
+
+#define INTMSK_LCD	(1UL << (IRQ_LCD - IRQ_EINT0))
+#define SUBMSK_LCD	INTMSK(IRQ_S3C2443_LCD1, IRQ_S3C2443_LCD4)
+
+static void s3c2443_irq_lcd_mask(struct irq_data *data)
+{
+	s3c_irqsub_mask(data->irq, INTMSK_LCD, SUBMSK_LCD);
+}
+
+static void s3c2443_irq_lcd_unmask(struct irq_data *data)
+{
+	s3c_irqsub_unmask(data->irq, INTMSK_LCD);
+}
+
+static void s3c2443_irq_lcd_ack(struct irq_data *data)
+{
+	s3c_irqsub_maskack(data->irq, INTMSK_LCD, SUBMSK_LCD);
+}
+
+static struct irq_chip s3c2443_irq_lcd = {
+	.irq_mask	= s3c2443_irq_lcd_mask,
+	.irq_unmask	= s3c2443_irq_lcd_unmask,
+	.irq_ack	= s3c2443_irq_lcd_ack,
+};
+
+/* DMA sub interrupts */
+
+static void s3c2443_irq_demux_dma(unsigned int irq, struct irq_desc *desc)
+{
+	s3c2443_irq_demux(IRQ_S3C2443_DMA0, 6);
+}
+
+#define INTMSK_DMA	(1UL << (IRQ_S3C2443_DMA - IRQ_EINT0))
+#define SUBMSK_DMA	INTMSK(IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5)
+
+static void s3c2443_irq_dma_mask(struct irq_data *data)
+{
+	s3c_irqsub_mask(data->irq, INTMSK_DMA, SUBMSK_DMA);
+}
+
+static void s3c2443_irq_dma_unmask(struct irq_data *data)
+{
+	s3c_irqsub_unmask(data->irq, INTMSK_DMA);
+}
+
+static void s3c2443_irq_dma_ack(struct irq_data *data)
+{
+	s3c_irqsub_maskack(data->irq, INTMSK_DMA, SUBMSK_DMA);
+}
+
+static struct irq_chip s3c2443_irq_dma = {
+	.irq_mask	= s3c2443_irq_dma_mask,
+	.irq_unmask	= s3c2443_irq_dma_unmask,
+	.irq_ack	= s3c2443_irq_dma_ack,
+};
+
+/* UART3 sub interrupts */
+
+static void s3c2443_irq_demux_uart3(unsigned int irq, struct irq_desc *desc)
+{
+	s3c2443_irq_demux(IRQ_S3C2443_RX3, 3);
+}
+
+#define INTMSK_UART3	(1UL << (IRQ_S3C2443_UART3 - IRQ_EINT0))
+#define SUBMSK_UART3	(0x7 << (IRQ_S3C2443_RX3 - S3C2410_IRQSUB(0)))
+
+static void s3c2443_irq_uart3_mask(struct irq_data *data)
+{
+	s3c_irqsub_mask(data->irq, INTMSK_UART3, SUBMSK_UART3);
+}
+
+static void s3c2443_irq_uart3_unmask(struct irq_data *data)
+{
+	s3c_irqsub_unmask(data->irq, INTMSK_UART3);
+}
+
+static void s3c2443_irq_uart3_ack(struct irq_data *data)
+{
+	s3c_irqsub_maskack(data->irq, INTMSK_UART3, SUBMSK_UART3);
+}
+
+static struct irq_chip s3c2443_irq_uart3 = {
+	.irq_mask	= s3c2443_irq_uart3_mask,
+	.irq_unmask	= s3c2443_irq_uart3_unmask,
+	.irq_ack	= s3c2443_irq_uart3_ack,
+};
+
+/* CAM sub interrupts */
+
+static void s3c2443_irq_demux_cam(unsigned int irq, struct irq_desc *desc)
+{
+	s3c2443_irq_demux(IRQ_S3C2440_CAM_C, 4);
+}
+
+#define INTMSK_CAM	(1UL << (IRQ_CAM - IRQ_EINT0))
+#define SUBMSK_CAM	INTMSK(IRQ_S3C2440_CAM_C, IRQ_S3C2440_CAM_P)
+
+static void s3c2443_irq_cam_mask(struct irq_data *data)
+{
+	s3c_irqsub_mask(data->irq, INTMSK_CAM, SUBMSK_CAM);
+}
+
+static void s3c2443_irq_cam_unmask(struct irq_data *data)
+{
+	s3c_irqsub_unmask(data->irq, INTMSK_CAM);
+}
+
+static void s3c2443_irq_cam_ack(struct irq_data *data)
+{
+	s3c_irqsub_maskack(data->irq, INTMSK_CAM, SUBMSK_CAM);
+}
+
+static struct irq_chip s3c2443_irq_cam = {
+	.irq_mask	= s3c2443_irq_cam_mask,
+	.irq_unmask	= s3c2443_irq_cam_unmask,
+	.irq_ack	= s3c2443_irq_cam_ack,
+};
+
+/* IRQ initialisation code */
+
+static int s3c2443_add_sub(unsigned int base,
+				   void (*demux)(unsigned int,
+						 struct irq_desc *),
+				   struct irq_chip *chip,
+				   unsigned int start, unsigned int end)
+{
+	unsigned int irqno;
+
+	irq_set_chip_and_handler(base, &s3c_irq_level_chip, handle_level_irq);
+	irq_set_chained_handler(base, demux);
+
+	for (irqno = start; irqno <= end; irqno++) {
+		irq_set_chip_and_handler(irqno, chip, handle_level_irq);
+		set_irq_flags(irqno, IRQF_VALID);
+	}
+
+	return 0;
+}
+
+static int s3c2443_irq_add(struct device *dev,
+				  struct subsys_interface *sif)
+{
+	printk("S3C2443: IRQ Support\n");
+
+	s3c2443_add_sub(IRQ_CAM, s3c2443_irq_demux_cam, &s3c2443_irq_cam,
+			IRQ_S3C2440_CAM_C, IRQ_S3C2440_CAM_P);
+
+	s3c2443_add_sub(IRQ_LCD, s3c2443_irq_demux_lcd, &s3c2443_irq_lcd,
+			IRQ_S3C2443_LCD1, IRQ_S3C2443_LCD4);
+
+	s3c2443_add_sub(IRQ_S3C2443_DMA, s3c2443_irq_demux_dma,
+			&s3c2443_irq_dma, IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5);
+
+	s3c2443_add_sub(IRQ_S3C2443_UART3, s3c2443_irq_demux_uart3,
+			&s3c2443_irq_uart3,
+			IRQ_S3C2443_RX3, IRQ_S3C2443_ERR3);
+
+	s3c2443_add_sub(IRQ_WDT, s3c2443_irq_demux_wdtac97,
+			&s3c2443_irq_wdtac97,
+			IRQ_S3C2443_WDT, IRQ_S3C2443_AC97);
+
+	return 0;
+}
+
+static struct subsys_interface s3c2443_irq_interface = {
+	.name		= "s3c2443_irq",
+	.subsys		= &s3c2443_subsys,
+	.add_dev	= s3c2443_irq_add,
+};
+
+static int __init s3c2443_irq_init(void)
+{
+	return subsys_interface_register(&s3c2443_irq_interface);
+}
+
+arch_initcall(s3c2443_irq_init);
+#endif
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 09/10] ARM: S3C24XX: modify s3c2443 irq init to initialize all irqs
  2012-11-18  0:51 ` Heiko Stübner
@ 2012-11-18  0:57   ` Heiko Stübner
  -1 siblings, 0 replies; 24+ messages in thread
From: Heiko Stübner @ 2012-11-18  0:57 UTC (permalink / raw)
  To: Kukjin Kim; +Cc: Ben Dooks, linux-arm-kernel, linux-samsung-soc

Previously the irq init used s3c24xx_init_irq and an additional
arch_initcall to add the cpu specific irqs.

To be able to simplyfy the irq init later, create a new function
s3c2443_init_irq, which then calls s3c24xx_init_irq but also adds
the cpu specific irqs.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
 arch/arm/mach-s3c24xx/mach-smdk2443.c        |    2 +-
 arch/arm/plat-s3c24xx/irq.c                  |   22 ++++------------------
 arch/arm/plat-samsung/include/plat/s3c2443.h |    2 ++
 3 files changed, 7 insertions(+), 19 deletions(-)

diff --git a/arch/arm/mach-s3c24xx/mach-smdk2443.c b/arch/arm/mach-s3c24xx/mach-smdk2443.c
index 2568656..ddabfdf 100644
--- a/arch/arm/mach-s3c24xx/mach-smdk2443.c
+++ b/arch/arm/mach-s3c24xx/mach-smdk2443.c
@@ -141,7 +141,7 @@ MACHINE_START(SMDK2443, "SMDK2443")
 	/* Maintainer: Ben Dooks <ben-linux@fluff.org> */
 	.atag_offset	= 0x100,
 
-	.init_irq	= s3c24xx_init_irq,
+	.init_irq	= s3c2443_init_irq,
 	.map_io		= smdk2443_map_io,
 	.init_machine	= smdk2443_machine_init,
 	.timer		= &s3c24xx_timer,
diff --git a/arch/arm/plat-s3c24xx/irq.c b/arch/arm/plat-s3c24xx/irq.c
index d7baeaf..9e559ed 100644
--- a/arch/arm/plat-s3c24xx/irq.c
+++ b/arch/arm/plat-s3c24xx/irq.c
@@ -1116,10 +1116,11 @@ static int s3c2443_add_sub(unsigned int base,
 	return 0;
 }
 
-static int s3c2443_irq_add(struct device *dev,
-				  struct subsys_interface *sif)
+void __init s3c2443_init_irq(void)
 {
-	printk("S3C2443: IRQ Support\n");
+	pr_info("S3C2443: IRQ Support\n");
+
+	s3c24xx_init_irq();
 
 	s3c2443_add_sub(IRQ_CAM, s3c2443_irq_demux_cam, &s3c2443_irq_cam,
 			IRQ_S3C2440_CAM_C, IRQ_S3C2440_CAM_P);
@@ -1137,20 +1138,5 @@ static int s3c2443_irq_add(struct device *dev,
 	s3c2443_add_sub(IRQ_WDT, s3c2443_irq_demux_wdtac97,
 			&s3c2443_irq_wdtac97,
 			IRQ_S3C2443_WDT, IRQ_S3C2443_AC97);
-
-	return 0;
-}
-
-static struct subsys_interface s3c2443_irq_interface = {
-	.name		= "s3c2443_irq",
-	.subsys		= &s3c2443_subsys,
-	.add_dev	= s3c2443_irq_add,
-};
-
-static int __init s3c2443_irq_init(void)
-{
-	return subsys_interface_register(&s3c2443_irq_interface);
 }
-
-arch_initcall(s3c2443_irq_init);
 #endif
diff --git a/arch/arm/plat-samsung/include/plat/s3c2443.h b/arch/arm/plat-samsung/include/plat/s3c2443.h
index a5b794f..71b88ec 100644
--- a/arch/arm/plat-samsung/include/plat/s3c2443.h
+++ b/arch/arm/plat-samsung/include/plat/s3c2443.h
@@ -25,6 +25,8 @@ extern void s3c2443_init_clocks(int xtal);
 extern  int s3c2443_baseclk_add(void);
 
 extern void s3c2443_restart(char mode, const char *cmd);
+
+extern void s3c2443_init_irq(void);
 #else
 #define s3c2443_init_clocks NULL
 #define s3c2443_init_uarts NULL
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 09/10] ARM: S3C24XX: modify s3c2443 irq init to initialize all irqs
@ 2012-11-18  0:57   ` Heiko Stübner
  0 siblings, 0 replies; 24+ messages in thread
From: Heiko Stübner @ 2012-11-18  0:57 UTC (permalink / raw)
  To: linux-arm-kernel

Previously the irq init used s3c24xx_init_irq and an additional
arch_initcall to add the cpu specific irqs.

To be able to simplyfy the irq init later, create a new function
s3c2443_init_irq, which then calls s3c24xx_init_irq but also adds
the cpu specific irqs.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
 arch/arm/mach-s3c24xx/mach-smdk2443.c        |    2 +-
 arch/arm/plat-s3c24xx/irq.c                  |   22 ++++------------------
 arch/arm/plat-samsung/include/plat/s3c2443.h |    2 ++
 3 files changed, 7 insertions(+), 19 deletions(-)

diff --git a/arch/arm/mach-s3c24xx/mach-smdk2443.c b/arch/arm/mach-s3c24xx/mach-smdk2443.c
index 2568656..ddabfdf 100644
--- a/arch/arm/mach-s3c24xx/mach-smdk2443.c
+++ b/arch/arm/mach-s3c24xx/mach-smdk2443.c
@@ -141,7 +141,7 @@ MACHINE_START(SMDK2443, "SMDK2443")
 	/* Maintainer: Ben Dooks <ben-linux@fluff.org> */
 	.atag_offset	= 0x100,
 
-	.init_irq	= s3c24xx_init_irq,
+	.init_irq	= s3c2443_init_irq,
 	.map_io		= smdk2443_map_io,
 	.init_machine	= smdk2443_machine_init,
 	.timer		= &s3c24xx_timer,
diff --git a/arch/arm/plat-s3c24xx/irq.c b/arch/arm/plat-s3c24xx/irq.c
index d7baeaf..9e559ed 100644
--- a/arch/arm/plat-s3c24xx/irq.c
+++ b/arch/arm/plat-s3c24xx/irq.c
@@ -1116,10 +1116,11 @@ static int s3c2443_add_sub(unsigned int base,
 	return 0;
 }
 
-static int s3c2443_irq_add(struct device *dev,
-				  struct subsys_interface *sif)
+void __init s3c2443_init_irq(void)
 {
-	printk("S3C2443: IRQ Support\n");
+	pr_info("S3C2443: IRQ Support\n");
+
+	s3c24xx_init_irq();
 
 	s3c2443_add_sub(IRQ_CAM, s3c2443_irq_demux_cam, &s3c2443_irq_cam,
 			IRQ_S3C2440_CAM_C, IRQ_S3C2440_CAM_P);
@@ -1137,20 +1138,5 @@ static int s3c2443_irq_add(struct device *dev,
 	s3c2443_add_sub(IRQ_WDT, s3c2443_irq_demux_wdtac97,
 			&s3c2443_irq_wdtac97,
 			IRQ_S3C2443_WDT, IRQ_S3C2443_AC97);
-
-	return 0;
-}
-
-static struct subsys_interface s3c2443_irq_interface = {
-	.name		= "s3c2443_irq",
-	.subsys		= &s3c2443_subsys,
-	.add_dev	= s3c2443_irq_add,
-};
-
-static int __init s3c2443_irq_init(void)
-{
-	return subsys_interface_register(&s3c2443_irq_interface);
 }
-
-arch_initcall(s3c2443_irq_init);
 #endif
diff --git a/arch/arm/plat-samsung/include/plat/s3c2443.h b/arch/arm/plat-samsung/include/plat/s3c2443.h
index a5b794f..71b88ec 100644
--- a/arch/arm/plat-samsung/include/plat/s3c2443.h
+++ b/arch/arm/plat-samsung/include/plat/s3c2443.h
@@ -25,6 +25,8 @@ extern void s3c2443_init_clocks(int xtal);
 extern  int s3c2443_baseclk_add(void);
 
 extern void s3c2443_restart(char mode, const char *cmd);
+
+extern void s3c2443_init_irq(void);
 #else
 #define s3c2443_init_clocks NULL
 #define s3c2443_init_uarts NULL
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 10/10] ARM: S3C24XX: assimilate s3c2443 subirqs into new structure
  2012-11-18  0:51 ` Heiko Stübner
@ 2012-11-18  0:57   ` Heiko Stübner
  -1 siblings, 0 replies; 24+ messages in thread
From: Heiko Stübner @ 2012-11-18  0:57 UTC (permalink / raw)
  To: Kukjin Kim; +Cc: Ben Dooks, linux-arm-kernel, linux-samsung-soc

The contents of the base irq-register are shared between the s3c2443
and s3c2416/s3c2450.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
 arch/arm/plat-s3c24xx/irq.c |  252 ++++++-------------------------------------
 1 files changed, 34 insertions(+), 218 deletions(-)

diff --git a/arch/arm/plat-s3c24xx/irq.c b/arch/arm/plat-s3c24xx/irq.c
index 9e559ed..bd05af9 100644
--- a/arch/arm/plat-s3c24xx/irq.c
+++ b/arch/arm/plat-s3c24xx/irq.c
@@ -913,230 +913,46 @@ struct syscore_ops s3c2416_irq_syscore_ops = {
 #endif
 
 #ifdef CONFIG_CPU_S3C2443
-#define INTMSK(start, end) ((1 << ((end) + 1 - (start))) - 1)
-
-static inline void s3c2443_irq_demux(unsigned int irq, unsigned int len)
-{
-	unsigned int subsrc, submsk;
-	unsigned int end;
-
-	/* read the current pending interrupts, and the mask
-	 * for what it is available */
-
-	subsrc = __raw_readl(S3C2410_SUBSRCPND);
-	submsk = __raw_readl(S3C2410_INTSUBMSK);
-
-	subsrc  &= ~submsk;
-	subsrc >>= (irq - S3C2410_IRQSUB(0));
-	subsrc  &= (1 << len)-1;
-
-	end = len + irq;
-
-	for (; irq < end && subsrc; irq++) {
-		if (subsrc & 1)
-			generic_handle_irq(irq);
-
-		subsrc >>= 1;
-	}
-}
-
-/* WDT/AC97 sub interrupts */
-
-static void s3c2443_irq_demux_wdtac97(unsigned int irq, struct irq_desc *desc)
-{
-	s3c2443_irq_demux(IRQ_S3C2443_WDT, 4);
-}
-
-#define INTMSK_WDTAC97	(1UL << (IRQ_WDT - IRQ_EINT0))
-#define SUBMSK_WDTAC97	INTMSK(IRQ_S3C2443_WDT, IRQ_S3C2443_AC97)
-
-static void s3c2443_irq_wdtac97_mask(struct irq_data *data)
-{
-	s3c_irqsub_mask(data->irq, INTMSK_WDTAC97, SUBMSK_WDTAC97);
-}
-
-static void s3c2443_irq_wdtac97_unmask(struct irq_data *data)
-{
-	s3c_irqsub_unmask(data->irq, INTMSK_WDTAC97);
-}
-
-static void s3c2443_irq_wdtac97_ack(struct irq_data *data)
-{
-	s3c_irqsub_maskack(data->irq, INTMSK_WDTAC97, SUBMSK_WDTAC97);
-}
-
-static struct irq_chip s3c2443_irq_wdtac97 = {
-	.irq_mask	= s3c2443_irq_wdtac97_mask,
-	.irq_unmask	= s3c2443_irq_wdtac97_unmask,
-	.irq_ack	= s3c2443_irq_wdtac97_ack,
-};
-
-/* LCD sub interrupts */
-
-static void s3c2443_irq_demux_lcd(unsigned int irq, struct irq_desc *desc)
-{
-	s3c2443_irq_demux(IRQ_S3C2443_LCD1, 4);
-}
-
-#define INTMSK_LCD	(1UL << (IRQ_LCD - IRQ_EINT0))
-#define SUBMSK_LCD	INTMSK(IRQ_S3C2443_LCD1, IRQ_S3C2443_LCD4)
-
-static void s3c2443_irq_lcd_mask(struct irq_data *data)
-{
-	s3c_irqsub_mask(data->irq, INTMSK_LCD, SUBMSK_LCD);
-}
-
-static void s3c2443_irq_lcd_unmask(struct irq_data *data)
-{
-	s3c_irqsub_unmask(data->irq, INTMSK_LCD);
-}
-
-static void s3c2443_irq_lcd_ack(struct irq_data *data)
-{
-	s3c_irqsub_maskack(data->irq, INTMSK_LCD, SUBMSK_LCD);
-}
-
-static struct irq_chip s3c2443_irq_lcd = {
-	.irq_mask	= s3c2443_irq_lcd_mask,
-	.irq_unmask	= s3c2443_irq_lcd_unmask,
-	.irq_ack	= s3c2443_irq_lcd_ack,
-};
-
-/* DMA sub interrupts */
-
-static void s3c2443_irq_demux_dma(unsigned int irq, struct irq_desc *desc)
-{
-	s3c2443_irq_demux(IRQ_S3C2443_DMA0, 6);
-}
-
-#define INTMSK_DMA	(1UL << (IRQ_S3C2443_DMA - IRQ_EINT0))
-#define SUBMSK_DMA	INTMSK(IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5)
-
-static void s3c2443_irq_dma_mask(struct irq_data *data)
-{
-	s3c_irqsub_mask(data->irq, INTMSK_DMA, SUBMSK_DMA);
-}
-
-static void s3c2443_irq_dma_unmask(struct irq_data *data)
-{
-	s3c_irqsub_unmask(data->irq, INTMSK_DMA);
-}
-
-static void s3c2443_irq_dma_ack(struct irq_data *data)
-{
-	s3c_irqsub_maskack(data->irq, INTMSK_DMA, SUBMSK_DMA);
-}
-
-static struct irq_chip s3c2443_irq_dma = {
-	.irq_mask	= s3c2443_irq_dma_mask,
-	.irq_unmask	= s3c2443_irq_dma_unmask,
-	.irq_ack	= s3c2443_irq_dma_ack,
-};
-
-/* UART3 sub interrupts */
-
-static void s3c2443_irq_demux_uart3(unsigned int irq, struct irq_desc *desc)
-{
-	s3c2443_irq_demux(IRQ_S3C2443_RX3, 3);
-}
-
-#define INTMSK_UART3	(1UL << (IRQ_S3C2443_UART3 - IRQ_EINT0))
-#define SUBMSK_UART3	(0x7 << (IRQ_S3C2443_RX3 - S3C2410_IRQSUB(0)))
-
-static void s3c2443_irq_uart3_mask(struct irq_data *data)
-{
-	s3c_irqsub_mask(data->irq, INTMSK_UART3, SUBMSK_UART3);
-}
-
-static void s3c2443_irq_uart3_unmask(struct irq_data *data)
-{
-	s3c_irqsub_unmask(data->irq, INTMSK_UART3);
-}
-
-static void s3c2443_irq_uart3_ack(struct irq_data *data)
-{
-	s3c_irqsub_maskack(data->irq, INTMSK_UART3, SUBMSK_UART3);
-}
-
-static struct irq_chip s3c2443_irq_uart3 = {
-	.irq_mask	= s3c2443_irq_uart3_mask,
-	.irq_unmask	= s3c2443_irq_uart3_unmask,
-	.irq_ack	= s3c2443_irq_uart3_ack,
-};
-
-/* CAM sub interrupts */
-
-static void s3c2443_irq_demux_cam(unsigned int irq, struct irq_desc *desc)
-{
-	s3c2443_irq_demux(IRQ_S3C2440_CAM_C, 4);
-}
-
-#define INTMSK_CAM	(1UL << (IRQ_CAM - IRQ_EINT0))
-#define SUBMSK_CAM	INTMSK(IRQ_S3C2440_CAM_C, IRQ_S3C2440_CAM_P)
-
-static void s3c2443_irq_cam_mask(struct irq_data *data)
-{
-	s3c_irqsub_mask(data->irq, INTMSK_CAM, SUBMSK_CAM);
-}
-
-static void s3c2443_irq_cam_unmask(struct irq_data *data)
-{
-	s3c_irqsub_unmask(data->irq, INTMSK_CAM);
-}
-
-static void s3c2443_irq_cam_ack(struct irq_data *data)
-{
-	s3c_irqsub_maskack(data->irq, INTMSK_CAM, SUBMSK_CAM);
-}
-
-static struct irq_chip s3c2443_irq_cam = {
-	.irq_mask	= s3c2443_irq_cam_mask,
-	.irq_unmask	= s3c2443_irq_cam_unmask,
-	.irq_ack	= s3c2443_irq_cam_ack,
+struct s3c_irq_data init_s3c2443subint[32] = {
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 28 }, /* UART0-RX */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 28 }, /* UART0-TX */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 28 }, /* UART0-ERR */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 23 }, /* UART1-RX */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 23 }, /* UART1-TX */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 23 }, /* UART1-ERR */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 15 }, /* UART2-RX */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 15 }, /* UART2-TX */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 15 }, /* UART2-ERR */
+	{ .type = S3C_IRQTYPE_SUBEDGE, .parent_irq = 31 }, /* TC */
+	{ .type = S3C_IRQTYPE_SUBEDGE, .parent_irq = 31 }, /* ADC */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 6 }, /* CAM_C */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 6 }, /* CAM_P */
+	{ .type = S3C_IRQTYPE_NONE }, /* reserved */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 16 }, /* LCD1 (stn) */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 16 }, /* LCD2 */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 16 }, /* LCD3 */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 16 }, /* LCD4 */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 17 }, /* DMA0 */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 17 }, /* DMA1 */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 17 }, /* DMA2 */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 17 }, /* DMA3 */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 17 }, /* DMA4 */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 17 }, /* DMA5 */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 18 }, /* UART3-RX */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 18 }, /* UART3-TX */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 18 }, /* UART3-ERR */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 9 }, /* WDT */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 9 }, /* AC97 */
 };
 
-/* IRQ initialisation code */
-
-static int s3c2443_add_sub(unsigned int base,
-				   void (*demux)(unsigned int,
-						 struct irq_desc *),
-				   struct irq_chip *chip,
-				   unsigned int start, unsigned int end)
-{
-	unsigned int irqno;
-
-	irq_set_chip_and_handler(base, &s3c_irq_level_chip, handle_level_irq);
-	irq_set_chained_handler(base, demux);
-
-	for (irqno = start; irqno <= end; irqno++) {
-		irq_set_chip_and_handler(irqno, chip, handle_level_irq);
-		set_irq_flags(irqno, IRQF_VALID);
-	}
-
-	return 0;
-}
-
 void __init s3c2443_init_irq(void)
 {
+	/* override irq mapping */
+	s3c_intc[0].irqs = &init_s3c2443base[0];
+	s3c_intc[2].irqs = &init_s3c2443subint[0];
+
 	pr_info("S3C2443: IRQ Support\n");
 
 	s3c24xx_init_irq();
-
-	s3c2443_add_sub(IRQ_CAM, s3c2443_irq_demux_cam, &s3c2443_irq_cam,
-			IRQ_S3C2440_CAM_C, IRQ_S3C2440_CAM_P);
-
-	s3c2443_add_sub(IRQ_LCD, s3c2443_irq_demux_lcd, &s3c2443_irq_lcd,
-			IRQ_S3C2443_LCD1, IRQ_S3C2443_LCD4);
-
-	s3c2443_add_sub(IRQ_S3C2443_DMA, s3c2443_irq_demux_dma,
-			&s3c2443_irq_dma, IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5);
-
-	s3c2443_add_sub(IRQ_S3C2443_UART3, s3c2443_irq_demux_uart3,
-			&s3c2443_irq_uart3,
-			IRQ_S3C2443_RX3, IRQ_S3C2443_ERR3);
-
-	s3c2443_add_sub(IRQ_WDT, s3c2443_irq_demux_wdtac97,
-			&s3c2443_irq_wdtac97,
-			IRQ_S3C2443_WDT, IRQ_S3C2443_AC97);
 }
 #endif
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 10/10] ARM: S3C24XX: assimilate s3c2443 subirqs into new structure
@ 2012-11-18  0:57   ` Heiko Stübner
  0 siblings, 0 replies; 24+ messages in thread
From: Heiko Stübner @ 2012-11-18  0:57 UTC (permalink / raw)
  To: linux-arm-kernel

The contents of the base irq-register are shared between the s3c2443
and s3c2416/s3c2450.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
 arch/arm/plat-s3c24xx/irq.c |  252 ++++++-------------------------------------
 1 files changed, 34 insertions(+), 218 deletions(-)

diff --git a/arch/arm/plat-s3c24xx/irq.c b/arch/arm/plat-s3c24xx/irq.c
index 9e559ed..bd05af9 100644
--- a/arch/arm/plat-s3c24xx/irq.c
+++ b/arch/arm/plat-s3c24xx/irq.c
@@ -913,230 +913,46 @@ struct syscore_ops s3c2416_irq_syscore_ops = {
 #endif
 
 #ifdef CONFIG_CPU_S3C2443
-#define INTMSK(start, end) ((1 << ((end) + 1 - (start))) - 1)
-
-static inline void s3c2443_irq_demux(unsigned int irq, unsigned int len)
-{
-	unsigned int subsrc, submsk;
-	unsigned int end;
-
-	/* read the current pending interrupts, and the mask
-	 * for what it is available */
-
-	subsrc = __raw_readl(S3C2410_SUBSRCPND);
-	submsk = __raw_readl(S3C2410_INTSUBMSK);
-
-	subsrc  &= ~submsk;
-	subsrc >>= (irq - S3C2410_IRQSUB(0));
-	subsrc  &= (1 << len)-1;
-
-	end = len + irq;
-
-	for (; irq < end && subsrc; irq++) {
-		if (subsrc & 1)
-			generic_handle_irq(irq);
-
-		subsrc >>= 1;
-	}
-}
-
-/* WDT/AC97 sub interrupts */
-
-static void s3c2443_irq_demux_wdtac97(unsigned int irq, struct irq_desc *desc)
-{
-	s3c2443_irq_demux(IRQ_S3C2443_WDT, 4);
-}
-
-#define INTMSK_WDTAC97	(1UL << (IRQ_WDT - IRQ_EINT0))
-#define SUBMSK_WDTAC97	INTMSK(IRQ_S3C2443_WDT, IRQ_S3C2443_AC97)
-
-static void s3c2443_irq_wdtac97_mask(struct irq_data *data)
-{
-	s3c_irqsub_mask(data->irq, INTMSK_WDTAC97, SUBMSK_WDTAC97);
-}
-
-static void s3c2443_irq_wdtac97_unmask(struct irq_data *data)
-{
-	s3c_irqsub_unmask(data->irq, INTMSK_WDTAC97);
-}
-
-static void s3c2443_irq_wdtac97_ack(struct irq_data *data)
-{
-	s3c_irqsub_maskack(data->irq, INTMSK_WDTAC97, SUBMSK_WDTAC97);
-}
-
-static struct irq_chip s3c2443_irq_wdtac97 = {
-	.irq_mask	= s3c2443_irq_wdtac97_mask,
-	.irq_unmask	= s3c2443_irq_wdtac97_unmask,
-	.irq_ack	= s3c2443_irq_wdtac97_ack,
-};
-
-/* LCD sub interrupts */
-
-static void s3c2443_irq_demux_lcd(unsigned int irq, struct irq_desc *desc)
-{
-	s3c2443_irq_demux(IRQ_S3C2443_LCD1, 4);
-}
-
-#define INTMSK_LCD	(1UL << (IRQ_LCD - IRQ_EINT0))
-#define SUBMSK_LCD	INTMSK(IRQ_S3C2443_LCD1, IRQ_S3C2443_LCD4)
-
-static void s3c2443_irq_lcd_mask(struct irq_data *data)
-{
-	s3c_irqsub_mask(data->irq, INTMSK_LCD, SUBMSK_LCD);
-}
-
-static void s3c2443_irq_lcd_unmask(struct irq_data *data)
-{
-	s3c_irqsub_unmask(data->irq, INTMSK_LCD);
-}
-
-static void s3c2443_irq_lcd_ack(struct irq_data *data)
-{
-	s3c_irqsub_maskack(data->irq, INTMSK_LCD, SUBMSK_LCD);
-}
-
-static struct irq_chip s3c2443_irq_lcd = {
-	.irq_mask	= s3c2443_irq_lcd_mask,
-	.irq_unmask	= s3c2443_irq_lcd_unmask,
-	.irq_ack	= s3c2443_irq_lcd_ack,
-};
-
-/* DMA sub interrupts */
-
-static void s3c2443_irq_demux_dma(unsigned int irq, struct irq_desc *desc)
-{
-	s3c2443_irq_demux(IRQ_S3C2443_DMA0, 6);
-}
-
-#define INTMSK_DMA	(1UL << (IRQ_S3C2443_DMA - IRQ_EINT0))
-#define SUBMSK_DMA	INTMSK(IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5)
-
-static void s3c2443_irq_dma_mask(struct irq_data *data)
-{
-	s3c_irqsub_mask(data->irq, INTMSK_DMA, SUBMSK_DMA);
-}
-
-static void s3c2443_irq_dma_unmask(struct irq_data *data)
-{
-	s3c_irqsub_unmask(data->irq, INTMSK_DMA);
-}
-
-static void s3c2443_irq_dma_ack(struct irq_data *data)
-{
-	s3c_irqsub_maskack(data->irq, INTMSK_DMA, SUBMSK_DMA);
-}
-
-static struct irq_chip s3c2443_irq_dma = {
-	.irq_mask	= s3c2443_irq_dma_mask,
-	.irq_unmask	= s3c2443_irq_dma_unmask,
-	.irq_ack	= s3c2443_irq_dma_ack,
-};
-
-/* UART3 sub interrupts */
-
-static void s3c2443_irq_demux_uart3(unsigned int irq, struct irq_desc *desc)
-{
-	s3c2443_irq_demux(IRQ_S3C2443_RX3, 3);
-}
-
-#define INTMSK_UART3	(1UL << (IRQ_S3C2443_UART3 - IRQ_EINT0))
-#define SUBMSK_UART3	(0x7 << (IRQ_S3C2443_RX3 - S3C2410_IRQSUB(0)))
-
-static void s3c2443_irq_uart3_mask(struct irq_data *data)
-{
-	s3c_irqsub_mask(data->irq, INTMSK_UART3, SUBMSK_UART3);
-}
-
-static void s3c2443_irq_uart3_unmask(struct irq_data *data)
-{
-	s3c_irqsub_unmask(data->irq, INTMSK_UART3);
-}
-
-static void s3c2443_irq_uart3_ack(struct irq_data *data)
-{
-	s3c_irqsub_maskack(data->irq, INTMSK_UART3, SUBMSK_UART3);
-}
-
-static struct irq_chip s3c2443_irq_uart3 = {
-	.irq_mask	= s3c2443_irq_uart3_mask,
-	.irq_unmask	= s3c2443_irq_uart3_unmask,
-	.irq_ack	= s3c2443_irq_uart3_ack,
-};
-
-/* CAM sub interrupts */
-
-static void s3c2443_irq_demux_cam(unsigned int irq, struct irq_desc *desc)
-{
-	s3c2443_irq_demux(IRQ_S3C2440_CAM_C, 4);
-}
-
-#define INTMSK_CAM	(1UL << (IRQ_CAM - IRQ_EINT0))
-#define SUBMSK_CAM	INTMSK(IRQ_S3C2440_CAM_C, IRQ_S3C2440_CAM_P)
-
-static void s3c2443_irq_cam_mask(struct irq_data *data)
-{
-	s3c_irqsub_mask(data->irq, INTMSK_CAM, SUBMSK_CAM);
-}
-
-static void s3c2443_irq_cam_unmask(struct irq_data *data)
-{
-	s3c_irqsub_unmask(data->irq, INTMSK_CAM);
-}
-
-static void s3c2443_irq_cam_ack(struct irq_data *data)
-{
-	s3c_irqsub_maskack(data->irq, INTMSK_CAM, SUBMSK_CAM);
-}
-
-static struct irq_chip s3c2443_irq_cam = {
-	.irq_mask	= s3c2443_irq_cam_mask,
-	.irq_unmask	= s3c2443_irq_cam_unmask,
-	.irq_ack	= s3c2443_irq_cam_ack,
+struct s3c_irq_data init_s3c2443subint[32] = {
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 28 }, /* UART0-RX */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 28 }, /* UART0-TX */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 28 }, /* UART0-ERR */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 23 }, /* UART1-RX */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 23 }, /* UART1-TX */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 23 }, /* UART1-ERR */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 15 }, /* UART2-RX */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 15 }, /* UART2-TX */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 15 }, /* UART2-ERR */
+	{ .type = S3C_IRQTYPE_SUBEDGE, .parent_irq = 31 }, /* TC */
+	{ .type = S3C_IRQTYPE_SUBEDGE, .parent_irq = 31 }, /* ADC */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 6 }, /* CAM_C */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 6 }, /* CAM_P */
+	{ .type = S3C_IRQTYPE_NONE }, /* reserved */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 16 }, /* LCD1 (stn) */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 16 }, /* LCD2 */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 16 }, /* LCD3 */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 16 }, /* LCD4 */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 17 }, /* DMA0 */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 17 }, /* DMA1 */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 17 }, /* DMA2 */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 17 }, /* DMA3 */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 17 }, /* DMA4 */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 17 }, /* DMA5 */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 18 }, /* UART3-RX */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 18 }, /* UART3-TX */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 18 }, /* UART3-ERR */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 9 }, /* WDT */
+	{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 9 }, /* AC97 */
 };
 
-/* IRQ initialisation code */
-
-static int s3c2443_add_sub(unsigned int base,
-				   void (*demux)(unsigned int,
-						 struct irq_desc *),
-				   struct irq_chip *chip,
-				   unsigned int start, unsigned int end)
-{
-	unsigned int irqno;
-
-	irq_set_chip_and_handler(base, &s3c_irq_level_chip, handle_level_irq);
-	irq_set_chained_handler(base, demux);
-
-	for (irqno = start; irqno <= end; irqno++) {
-		irq_set_chip_and_handler(irqno, chip, handle_level_irq);
-		set_irq_flags(irqno, IRQF_VALID);
-	}
-
-	return 0;
-}
-
 void __init s3c2443_init_irq(void)
 {
+	/* override irq mapping */
+	s3c_intc[0].irqs = &init_s3c2443base[0];
+	s3c_intc[2].irqs = &init_s3c2443subint[0];
+
 	pr_info("S3C2443: IRQ Support\n");
 
 	s3c24xx_init_irq();
-
-	s3c2443_add_sub(IRQ_CAM, s3c2443_irq_demux_cam, &s3c2443_irq_cam,
-			IRQ_S3C2440_CAM_C, IRQ_S3C2440_CAM_P);
-
-	s3c2443_add_sub(IRQ_LCD, s3c2443_irq_demux_lcd, &s3c2443_irq_lcd,
-			IRQ_S3C2443_LCD1, IRQ_S3C2443_LCD4);
-
-	s3c2443_add_sub(IRQ_S3C2443_DMA, s3c2443_irq_demux_dma,
-			&s3c2443_irq_dma, IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5);
-
-	s3c2443_add_sub(IRQ_S3C2443_UART3, s3c2443_irq_demux_uart3,
-			&s3c2443_irq_uart3,
-			IRQ_S3C2443_RX3, IRQ_S3C2443_ERR3);
-
-	s3c2443_add_sub(IRQ_WDT, s3c2443_irq_demux_wdtac97,
-			&s3c2443_irq_wdtac97,
-			IRQ_S3C2443_WDT, IRQ_S3C2443_AC97);
 }
 #endif
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* RE: [PATCH 00/10] ARM: S3C24XX: rework irq handling for a later dt usage
  2012-11-18  0:51 ` Heiko Stübner
@ 2012-11-20 11:51   ` Kukjin Kim
  -1 siblings, 0 replies; 24+ messages in thread
From: Kukjin Kim @ 2012-11-20 11:51 UTC (permalink / raw)
  To: 'Heiko Stübner'
  Cc: 'Ben Dooks', linux-arm-kernel, linux-samsung-soc

Heiko Stübner wrote:
> 
> All S3C24XX arches share the same interrupt registers and basic handling
> principles but the individual interrupts differ quite a lot between all
> the arches.
> 
> This series therefore tries to unify this a bit by abstracting the irq
> handling and enabling the arches to simply provide a structure describing
> its individual interrupts.
> 
> With this declarative approach it should also be (hopefully) easy to
> move this to devicetree later.
> 
> For the initial transformation (in patch 1) I gave up on trying to do
> this in individual steps, so the patch might be a bit bumpy to read,
> but the new irq code does provide the exactly same interrupts and
> handlers as the old code. This also means that the unconverted arches
> shouldn't feel any difference at all.
> 
> I've only included the s3c2416 and s3c2443 interrupts for now, as the
> s3c2416 is my main development platform and the s3c2443 is so very
> similar. But the other arches use the same mechanics so conversion
> should be quite easy later.
> 
> As it seems to be the policy for drivers/irqchip that drivers there
> should not contain platform-hooks or pollute the namespace with custom
> init functons, the irq code stays in plat-s3c24xx for now.
> 
> Heiko Stuebner (10):
>   ARM: S3C24XX: transform irq handling into a declarative form
>   ARM: S3C24XX: move irq-pm code into main irq file
>   ARM: S3C24XX: cleanup irq-pm integration
>   ARM: S3C24XX: move s3c2416 irq init to common irq code
>   ARM: S3C24XX: modify s3c2416 irq init to initialize all irqs
>   ARM: S3C24XX: assimilate s3c2416 subirqs into new structure
>   ARM: S3C24XX: assimilate second s3c2416 interrupt into new structure
>   ARM: S3C24XX: move s3c2443 irq code to irq.c
>   ARM: S3C24XX: modify s3c2443 irq init to initialize all irqs
>   ARM: S3C24XX: assimilate s3c2443 subirqs into new structure
> 
>  arch/arm/mach-s3c24xx/Makefile               |    6 +-
>  arch/arm/mach-s3c24xx/common.h               |    2 +
>  arch/arm/mach-s3c24xx/irq-pm.c               |   95 ---
>  arch/arm/mach-s3c24xx/irq-s3c2416.c          |  348 --------
>  arch/arm/mach-s3c24xx/irq-s3c2443.c          |  281 -------
>  arch/arm/mach-s3c24xx/mach-smdk2416.c        |    2 +-
>  arch/arm/mach-s3c24xx/mach-smdk2443.c        |    2 +-
>  arch/arm/mach-s3c24xx/s3c2410.c              |    4 +-
>  arch/arm/mach-s3c24xx/s3c2412.c              |    4 +-
>  arch/arm/mach-s3c24xx/s3c2416.c              |    4 +-
>  arch/arm/mach-s3c24xx/s3c2440.c              |    4 +-
>  arch/arm/mach-s3c24xx/s3c2442.c              |    4 +-
>  arch/arm/plat-s3c24xx/Kconfig                |    1 +
>  arch/arm/plat-s3c24xx/irq.c                  | 1140 ++++++++++++++++---------
> -
>  arch/arm/plat-samsung/include/plat/pm.h      |    6 -
>  arch/arm/plat-samsung/include/plat/s3c2416.h |    1 +
>  arch/arm/plat-samsung/include/plat/s3c2443.h |    2 +
>  17 files changed, 737 insertions(+), 1169 deletions(-)
>  delete mode 100644 arch/arm/mach-s3c24xx/irq-pm.c
>  delete mode 100644 arch/arm/mach-s3c24xx/irq-s3c2416.c
>  delete mode 100644 arch/arm/mach-s3c24xx/irq-s3c2443.c
> 
> --
> 1.7.2.3

Good job, but I need more time to look at this whole series...I will try to do before this weekend ;-)

Thanks.

Best regards,
Kgene.
--
Kukjin Kim <kgene.kim@samsung.com>, Senior Engineer,
SW Solution Development Team, Samsung Electronics Co., Ltd.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH 00/10] ARM: S3C24XX: rework irq handling for a later dt usage
@ 2012-11-20 11:51   ` Kukjin Kim
  0 siblings, 0 replies; 24+ messages in thread
From: Kukjin Kim @ 2012-11-20 11:51 UTC (permalink / raw)
  To: linux-arm-kernel

Heiko St?bner wrote:
> 
> All S3C24XX arches share the same interrupt registers and basic handling
> principles but the individual interrupts differ quite a lot between all
> the arches.
> 
> This series therefore tries to unify this a bit by abstracting the irq
> handling and enabling the arches to simply provide a structure describing
> its individual interrupts.
> 
> With this declarative approach it should also be (hopefully) easy to
> move this to devicetree later.
> 
> For the initial transformation (in patch 1) I gave up on trying to do
> this in individual steps, so the patch might be a bit bumpy to read,
> but the new irq code does provide the exactly same interrupts and
> handlers as the old code. This also means that the unconverted arches
> shouldn't feel any difference at all.
> 
> I've only included the s3c2416 and s3c2443 interrupts for now, as the
> s3c2416 is my main development platform and the s3c2443 is so very
> similar. But the other arches use the same mechanics so conversion
> should be quite easy later.
> 
> As it seems to be the policy for drivers/irqchip that drivers there
> should not contain platform-hooks or pollute the namespace with custom
> init functons, the irq code stays in plat-s3c24xx for now.
> 
> Heiko Stuebner (10):
>   ARM: S3C24XX: transform irq handling into a declarative form
>   ARM: S3C24XX: move irq-pm code into main irq file
>   ARM: S3C24XX: cleanup irq-pm integration
>   ARM: S3C24XX: move s3c2416 irq init to common irq code
>   ARM: S3C24XX: modify s3c2416 irq init to initialize all irqs
>   ARM: S3C24XX: assimilate s3c2416 subirqs into new structure
>   ARM: S3C24XX: assimilate second s3c2416 interrupt into new structure
>   ARM: S3C24XX: move s3c2443 irq code to irq.c
>   ARM: S3C24XX: modify s3c2443 irq init to initialize all irqs
>   ARM: S3C24XX: assimilate s3c2443 subirqs into new structure
> 
>  arch/arm/mach-s3c24xx/Makefile               |    6 +-
>  arch/arm/mach-s3c24xx/common.h               |    2 +
>  arch/arm/mach-s3c24xx/irq-pm.c               |   95 ---
>  arch/arm/mach-s3c24xx/irq-s3c2416.c          |  348 --------
>  arch/arm/mach-s3c24xx/irq-s3c2443.c          |  281 -------
>  arch/arm/mach-s3c24xx/mach-smdk2416.c        |    2 +-
>  arch/arm/mach-s3c24xx/mach-smdk2443.c        |    2 +-
>  arch/arm/mach-s3c24xx/s3c2410.c              |    4 +-
>  arch/arm/mach-s3c24xx/s3c2412.c              |    4 +-
>  arch/arm/mach-s3c24xx/s3c2416.c              |    4 +-
>  arch/arm/mach-s3c24xx/s3c2440.c              |    4 +-
>  arch/arm/mach-s3c24xx/s3c2442.c              |    4 +-
>  arch/arm/plat-s3c24xx/Kconfig                |    1 +
>  arch/arm/plat-s3c24xx/irq.c                  | 1140 ++++++++++++++++---------
> -
>  arch/arm/plat-samsung/include/plat/pm.h      |    6 -
>  arch/arm/plat-samsung/include/plat/s3c2416.h |    1 +
>  arch/arm/plat-samsung/include/plat/s3c2443.h |    2 +
>  17 files changed, 737 insertions(+), 1169 deletions(-)
>  delete mode 100644 arch/arm/mach-s3c24xx/irq-pm.c
>  delete mode 100644 arch/arm/mach-s3c24xx/irq-s3c2416.c
>  delete mode 100644 arch/arm/mach-s3c24xx/irq-s3c2443.c
> 
> --
> 1.7.2.3

Good job, but I need more time to look at this whole series...I will try to do before this weekend ;-)

Thanks.

Best regards,
Kgene.
--
Kukjin Kim <kgene.kim@samsung.com>, Senior Engineer,
SW Solution Development Team, Samsung Electronics Co., Ltd.

^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2012-11-20 11:51 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-11-18  0:51 [PATCH 00/10] ARM: S3C24XX: rework irq handling for a later dt usage Heiko Stübner
2012-11-18  0:51 ` Heiko Stübner
2012-11-18  0:52 ` [PATCH 01/10] ARM: S3C24XX: transform irq handling into a declarative form Heiko Stübner
2012-11-18  0:52   ` Heiko Stübner
2012-11-18  0:52 ` [PATCH 02/10] ARM: S3C24XX: move irq-pm code into main irq file Heiko Stübner
2012-11-18  0:52   ` Heiko Stübner
2012-11-18  0:53 ` [PATCH 03/10] ARM: S3C24XX: cleanup irq-pm integration Heiko Stübner
2012-11-18  0:53   ` Heiko Stübner
2012-11-18  0:54 ` [PATCH 04/10] ARM: S3C24XX: move s3c2416 irq init to common irq code Heiko Stübner
2012-11-18  0:54   ` Heiko Stübner
2012-11-18  0:54 ` [PATCH 05/10] ARM: S3C24XX: modify s3c2416 irq init to initialize all irqs Heiko Stübner
2012-11-18  0:54   ` Heiko Stübner
2012-11-18  0:55 ` [PATCH 06/10] ARM: S3C24XX: assimilate s3c2416 subirqs into new structure Heiko Stübner
2012-11-18  0:55   ` Heiko Stübner
2012-11-18  0:55 ` [PATCH 07/10] ARM: S3C24XX: assimilate second s3c2416 interrupt " Heiko Stübner
2012-11-18  0:55   ` Heiko Stübner
2012-11-18  0:56 ` [PATCH 08/10] ARM: S3C24XX: move s3c2443 irq code to irq.c Heiko Stübner
2012-11-18  0:56   ` Heiko Stübner
2012-11-18  0:57 ` [PATCH 09/10] ARM: S3C24XX: modify s3c2443 irq init to initialize all irqs Heiko Stübner
2012-11-18  0:57   ` Heiko Stübner
2012-11-18  0:57 ` [PATCH 10/10] ARM: S3C24XX: assimilate s3c2443 subirqs into new structure Heiko Stübner
2012-11-18  0:57   ` Heiko Stübner
2012-11-20 11:51 ` [PATCH 00/10] ARM: S3C24XX: rework irq handling for a later dt usage Kukjin Kim
2012-11-20 11:51   ` Kukjin Kim

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.