Skip to contentSkip to conversation

ARM: S3C24XX: rework irq handling for a later dt usage

PATCH Superseded Heiko Stübner 2 participants 14 messages Jan 1, 2013 – Jan 3, 2013

Subsystems (3)

v2 of 4 Superseded Latest is v4 →

lore
Share & tools
lore
#0 lore raw

v2 cover ARM: S3C24XX: rework irq handling for a later dt usage

Second version of redoing the s3c24xx irqs in a generic way by using a declarative approach.

Changes include further generalizations resulting only in common irq-type declarations being needed and thus again easier code.

As in the first version, the 1st patch might be hard to read due to the rewrite character, but I didn't see a way to do these changes in individual steps. So it might be helpful to look at the result after applying this patch.

Runtime-tested on a s3c2416 based board and compile tested for the others.

As also written before, inclusion of the other S3C24XX SoCs to follow once the general approach is acceptable.

Heiko Stuebner (11):
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
ARM: S3C24XX: remove maskack irq ack funtions

 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                  | 1092 +++++++++++++++-----------
 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, 649 insertions(+), 1209 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
Signature · 1 line
1.7.2.3
#1 lore raw

PATCH v2 1/11 ARM: S3C24XX: transform irq handling into a declarative form

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.

---
changes since v1:
- more generalized irq types, resulting in only types for none, eint, edge and level being needed
- use chained_irq_enter/exit to simplify subirq handling

 arch/arm/plat-s3c24xx/Kconfig |    1 +
 arch/arm/plat-s3c24xx/irq.c   |  868 +++++++++++++++++++----------------------
 2 files changed, 395 insertions(+), 474 deletions(-)
arch/arm/plat-s3c24xx/Kconfig +1 -0
index eef3b6a..3bb5c8f 100644
@@ -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
 
arch/arm/plat-s3c24xx/irq.c +394 -474

989 lines not on this page · raw message

Signature · 1 line
1.7.2.3
#2 lore raw

PATCH v2 2/11 ARM: S3C24XX: move irq-pm code into main irq file

In reply to Heiko Stübner

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

---
 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
arch/arm/mach-s3c24xx/Makefile +1 -1
index 0ab6ab1..3e1d12c 100644
@@ -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
 
arch/arm/mach-s3c24xx/irq-pm.c deleted +0 -95

95 lines not on this page · raw message

arch/arm/plat-s3c24xx/irq.c +76 -0

88 lines not on this page · raw message

Signature · 1 line
1.7.2.3
#3 lore raw

PATCH v2 3/11 ARM: S3C24XX: cleanup irq-pm integration

In reply to Heiko Stübner

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.

---
 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(-)
arch/arm/mach-s3c24xx/common.h +2 -0
index c2f596e..ed6276f 100644
@@ -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 */
arch/arm/mach-s3c24xx/s3c2410.c +3 -1
index a3c5cb0..9ebef95 100644
@@ -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);
 }
arch/arm/mach-s3c24xx/s3c2412.c +3 -1
index 6c5f403..0ec08bd 100644
@@ -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);
 }
arch/arm/mach-s3c24xx/s3c2416.c +3 -1
index 77ee0b7..e30476d 100644
@@ -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);
 }
arch/arm/mach-s3c24xx/s3c2440.c +3 -1
index 2b3dddb..559e394 100644
@@ -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 */
 
arch/arm/mach-s3c24xx/s3c2442.c +3 -1
index 22cb7c9..f732826 100644
@@ -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);
 }
arch/arm/plat-s3c24xx/irq.c +11 -11
index 9b4404d..d774c3b 100644
@@ -134,25 +134,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;
@@ -635,7 +635,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;
 
@@ -651,7 +651,7 @@ int s3c24xx_irq_suspend(void)
 	return 0;
 }
 
-void s3c24xx_irq_resume(void)
+static void s3c24xx_irq_resume(void)
 {
 	unsigned int i;
 
@@ -664,9 +664,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
arch/arm/plat-samsung/include/plat/pm.h +0 -6
index 887a0c9..f6fcade 100644
@@ -109,17 +109,11 @@ extern void s3c_pm_do_restore_core(struct sleep_save *ptr, int count);
 #ifdef CONFIG_PM
 extern int s3c_irq_wake(struct irq_data *data, unsigned int state);
 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_irq_wake NULL
 #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
Signature · 1 line
1.7.2.3
#4 lore raw

PATCH v2 4/11 ARM: S3C24XX: move s3c2416 irq init to common irq code

In reply to Heiko Stübner

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

---
 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
arch/arm/mach-s3c24xx/Makefile +1 -1
index 3e1d12c..30904c9 100644
@@ -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
arch/arm/mach-s3c24xx/irq-s3c2416.c deleted +0 -348

348 lines not on this page · raw message

arch/arm/plat-s3c24xx/irq.c +309 -0

312 lines not on this page · raw message

Signature · 1 line
1.7.2.3
#5 lore raw

PATCH v2 5/11 ARM: S3C24XX: modify s3c2416 irq init to initialize all irqs

In reply to Heiko Stübner

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.

---
 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(-)
arch/arm/mach-s3c24xx/mach-smdk2416.c +1 -1
index f30d7fc..5f6858f 100644
@@ -251,7 +251,7 @@ MACHINE_START(SMDK2416, "SMDK2416")
 	/* Maintainer: Yauhen Kharuzhy <[email protected]> */
 	.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,
arch/arm/plat-s3c24xx/irq.c +4 -18
index 450e95b..55b5e6e 100644
@@ -918,10 +918,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);
@@ -938,23 +939,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),
arch/arm/plat-samsung/include/plat/s3c2416.h +1 -0
index 7178e33..f27399a 100644
@@ -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
Signature · 1 line
1.7.2.3
#6 lore raw

PATCH v2 6/11 ARM: S3C24XX: assimilate s3c2416 subirqs into new structure

In reply to Heiko Stübner

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

---
 arch/arm/plat-s3c24xx/irq.c |  257 ++++++++++++-------------------------------
 1 files changed, 72 insertions(+), 185 deletions(-)
arch/arm/plat-s3c24xx/irq.c +72 -185
index 55b5e6e..9407845 100644
@@ -671,158 +671,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_EINT, }, /* EINT0 */
+	{ .type = S3C_IRQTYPE_EINT, }, /* EINT1 */
+	{ .type = S3C_IRQTYPE_EINT, }, /* EINT2 */
+	{ .type = S3C_IRQTYPE_EINT, }, /* EINT3 */
+	{ .type = S3C_IRQTYPE_LEVEL, }, /* EINT4to7 */
+	{ .type = S3C_IRQTYPE_LEVEL, }, /* EINT8to23 */
+	{ .type = S3C_IRQTYPE_LEVEL, }, /* CAM on S3C2443/2450 */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* nBATT_FLT */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* TICK */
+	{ .type = S3C_IRQTYPE_LEVEL, }, /* 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_LEVEL, }, /* UART2 */
+	{ .type = S3C_IRQTYPE_LEVEL, }, /* LCD */
+	{ .type = S3C_IRQTYPE_LEVEL, }, /* DMA */
+	{ .type = S3C_IRQTYPE_LEVEL, }, /* 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_LEVEL, }, /* UART1 */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* NAND */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* USBD */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* USBH */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* IIC */
+	{ .type = S3C_IRQTYPE_LEVEL, }, /* UART0 */
+	{ .type = S3C_IRQTYPE_NONE, }, /* SPI1 on S3C243/2450 */
+	{ .type = S3C_IRQTYPE_EDGE, }, /* RTC */
+	{ .type = S3C_IRQTYPE_LEVEL, }, /* 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 */
 
@@ -861,27 +747,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;
@@ -918,26 +783,48 @@ static void s3c2416_irq_add_second(void)
 	}
 }
 
+struct s3c_irq_data init_s3c2416subint[32] = {
+	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-RX */
+	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-TX */
+	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-ERR */
+	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-RX */
+	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-TX */
+	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-ERR */
+	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-RX */
+	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-TX */
+	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-ERR */
+	{ .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* TC */
+	{ .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* ADC */
+	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 }, /* CAM_C S3C2450 */
+	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 }, /* CAM_P S3C2450 */
+	{ .type = S3C_IRQTYPE_NONE }, /* reserved */
+	{ .type = S3C_IRQTYPE_NONE }, /* reserved */
+	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD2 */
+	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD3 */
+	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD4 */
+	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA0 */
+	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA1 */
+	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA2 */
+	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA3 */
+	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA4 */
+	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA5 */
+	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-RX */
+	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-TX */
+	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-ERR */
+	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* WDT */
+	{ .type = S3C_IRQTYPE_LEVEL, .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();
 }
 
Signature · 1 line
1.7.2.3
#7 lore raw

PATCH v2 7/11 ARM: S3C24XX: assimilate second s3c2416 interrupt into new structure

In reply to Heiko Stübner

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

---
 arch/arm/plat-s3c24xx/irq.c |  106 ++++++++++++-------------------------------
 1 files changed, 30 insertions(+), 76 deletions(-)
arch/arm/plat-s3c24xx/irq.c +30 -76
index 9407845..646861a 100644
@@ -17,6 +17,7 @@
 */
 
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
@@ -409,7 +410,8 @@ static int s3c24xx_irq_map(struct irq_domain *h, unsigned int virq,
 						 handle_edge_irq);
 		break;
 	case S3C_IRQTYPE_EDGE:
-		if (irq_data->parent_irq)
+		if (irq_data->parent_irq ||
+		    intc->reg_pending == S3C2416_SRCPND2)
 			irq_set_chip_and_handler(virq, &s3c_irq_subedge_chip,
 						 handle_edge_irq);
 		else
@@ -709,80 +711,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_LEVEL, .parent_irq = 28 }, /* UART0-RX */
 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-TX */
@@ -815,8 +743,21 @@ struct s3c_irq_data init_s3c2416subint[32] = {
 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* AC97 */
 };
 
+struct s3c_irq_data init_s3c2416_second[32] = {
+	{ .type = S3C_IRQTYPE_EDGE }, /* 2D */
+	{ .type = S3C_IRQTYPE_EDGE }, /* IIC1 */
+	{ .type = S3C_IRQTYPE_NONE }, /* reserved */
+	{ .type = S3C_IRQTYPE_NONE }, /* reserved */
+	{ .type = S3C_IRQTYPE_EDGE }, /* PCM0 */
+	{ .type = S3C_IRQTYPE_EDGE }, /* PCM1 */
+	{ .type = S3C_IRQTYPE_EDGE }, /* I2S0 */
+	{ .type = S3C_IRQTYPE_EDGE }, /* 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];
@@ -825,7 +766,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
Signature · 1 line
1.7.2.3
#8 lore raw

PATCH v2 8/11 ARM: S3C24XX: move s3c2443 irq code to irq.c

In reply to Heiko Stübner

Prequisite for further optimizations.

---
 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
arch/arm/mach-s3c24xx/Makefile +1 -1
index 30904c9..6019b7c 100644
@@ -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
 
arch/arm/mach-s3c24xx/irq-s3c2443.c deleted +0 -281

281 lines not on this page · raw message

arch/arm/plat-s3c24xx/irq.c +243 -0

246 lines not on this page · raw message

Signature · 1 line
1.7.2.3
#9 lore raw

PATCH v2 9/11 ARM: S3C24XX: modify s3c2443 irq init to initialize all irqs

In reply to Heiko Stübner

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.

---
 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(-)
arch/arm/mach-s3c24xx/mach-smdk2443.c +1 -1
index 2568656..ddabfdf 100644
@@ -141,7 +141,7 @@ MACHINE_START(SMDK2443, "SMDK2443")
 	/* Maintainer: Ben Dooks <[email protected]> */
 	.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,
arch/arm/plat-s3c24xx/irq.c +4 -18
index e021c44..97c1907 100644
@@ -1011,10 +1011,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);
@@ -1032,20 +1033,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
arch/arm/plat-samsung/include/plat/s3c2443.h +2 -0
index a5b794f..71b88ec 100644
@@ -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
Signature · 1 line
1.7.2.3
#10 lore raw

PATCH v2 10/11 ARM: S3C24XX: assimilate s3c2443 subirqs into new structure

In reply to Heiko Stübner

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

---
 arch/arm/plat-s3c24xx/irq.c |  252 ++++++-------------------------------------
 1 files changed, 34 insertions(+), 218 deletions(-)
arch/arm/plat-s3c24xx/irq.c +34 -218
index 97c1907..8cba552 100644
@@ -808,230 +808,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_LEVEL, .parent_irq = 28 }, /* UART0-RX */
+	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-TX */
+	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-ERR */
+	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-RX */
+	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-TX */
+	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-ERR */
+	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-RX */
+	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-TX */
+	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-ERR */
+	{ .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* TC */
+	{ .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* ADC */
+	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 }, /* CAM_C */
+	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 }, /* CAM_P */
+	{ .type = S3C_IRQTYPE_NONE }, /* reserved */
+	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD1 (stn) */
+	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD2 */
+	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD3 */
+	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD4 */
+	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA0 */
+	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA1 */
+	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA2 */
+	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA3 */
+	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA4 */
+	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA5 */
+	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-RX */
+	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-TX */
+	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-ERR */
+	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* WDT */
+	{ .type = S3C_IRQTYPE_LEVEL, .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
Signature · 1 line
1.7.2.3
#11 lore raw

PATCH v2 11/11 ARM: S3C24XX: remove maskack irq ack funtions

In reply to Heiko Stübner

In the past level irqs provided a special ack handler that also masked the interrupt. But handle_level_irq also does mask-ack the interrupt itself, so there is no need to keep this special ack function around.

We therefore can simplyfy the number of irq-chips again.

---
 arch/arm/plat-s3c24xx/irq.c |   41 +++++++++--------------------------------
 1 files changed, 9 insertions(+), 32 deletions(-)
arch/arm/plat-s3c24xx/irq.c +9 -32
index 8cba552..0516cbc 100644
@@ -128,12 +128,6 @@ static inline void s3c_irq_ack(struct irq_data *data)
 		__raw_writel(bitval, intc->reg_intpnd);
 }
 
-static inline void s3c_irq_maskack(struct irq_data *data)
-{
-	s3c_irq_mask(data);
-	s3c_irq_ack(data);
-}
-
 #ifdef CONFIG_PM
 /* state for IRQs over sleep
  *
@@ -164,22 +158,6 @@ int s3c_irq_wake(struct irq_data *data, unsigned int state)
 }
 #endif
 
-struct irq_chip s3c_irq_level_chip = {
-	.name		= "s3c-level",
-	.irq_ack	= s3c_irq_maskack,
-	.irq_mask	= s3c_irq_mask,
-	.irq_unmask	= s3c_irq_unmask,
-	.irq_set_wake	= s3c_irq_wake
-};
-
-struct irq_chip s3c_irq_chip = {
-	.name		= "s3c",
-	.irq_ack	= s3c_irq_ack,
-	.irq_mask	= s3c_irq_mask,
-	.irq_unmask	= s3c_irq_unmask,
-	.irq_set_wake	= s3c_irq_wake
-};
-
 static int s3c_irqext_type_set(void __iomem *gpcon_reg,
 			       void __iomem *extint_reg,
 			       unsigned long gpcon_offset,
@@ -299,17 +277,16 @@ static struct irq_chip s3c_irq_eint0t4 = {
 	.irq_set_type	= s3c_irqext0_type,
 };
 
-/* used for UARTs */
-static struct irq_chip s3c_irq_sublevel_chip = {
-	.name		= "s3c-sublevel",
+struct irq_chip s3c_irq_chip = {
+	.name		= "s3c",
+	.irq_ack	= s3c_irq_ack,
 	.irq_mask	= s3c_irq_mask,
 	.irq_unmask	= s3c_irq_unmask,
-	.irq_ack	= s3c_irq_maskack,
+	.irq_set_wake	= s3c_irq_wake
 };
 
-/* used for ADC and Touchscreen */
-static struct irq_chip s3c_irq_subedge_chip = {
-	.name		= "s3c-subedge",
+static struct irq_chip s3c_irq_general_chip = {
+	.name		= "s3c-general",
 	.irq_mask	= s3c_irq_mask,
 	.irq_unmask	= s3c_irq_unmask,
 	.irq_ack	= s3c_irq_ack,
@@ -412,7 +389,7 @@ static int s3c24xx_irq_map(struct irq_domain *h, unsigned int virq,
 	case S3C_IRQTYPE_EDGE:
 		if (irq_data->parent_irq ||
 		    intc->reg_pending == S3C2416_SRCPND2)
-			irq_set_chip_and_handler(virq, &s3c_irq_subedge_chip,
+			irq_set_chip_and_handler(virq, &s3c_irq_general_chip,
 						 handle_edge_irq);
 		else
 			irq_set_chip_and_handler(virq, &s3c_irq_chip,
@@ -420,10 +397,10 @@ static int s3c24xx_irq_map(struct irq_domain *h, unsigned int virq,
 		break;
 	case S3C_IRQTYPE_LEVEL:
 		if (irq_data->parent_irq)
-			irq_set_chip_and_handler(virq, &s3c_irq_sublevel_chip,
+			irq_set_chip_and_handler(virq, &s3c_irq_general_chip,
 						 handle_level_irq);
 		else
-			irq_set_chip_and_handler(virq, &s3c_irq_level_chip,
+			irq_set_chip_and_handler(virq, &s3c_irq_chip,
 						 handle_level_irq);
 		break;
 	default:
Signature · 1 line
1.7.2.3
#12 lore raw

v2 cover ARM: S3C24XX: rework irq handling for a later dt usage

In reply to Heiko Stübner
Quoted 42 lines · Heiko St?bner

Second version of redoing the s3c24xx irqs in a generic way by using a declarative approach.

Changes include further generalizations resulting only in common irq-type declarations being needed and thus again easier code.

As in the first version, the 1st patch might be hard to read due to the rewrite character, but I didn't see a way to do these changes in individual steps. So it might be helpful to look at the result after applying this patch.

Runtime-tested on a s3c2416 based board and compile tested for the others.

As also written before, inclusion of the other S3C24XX SoCs to follow once the general approach is acceptable.

Heiko Stuebner (11):
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
ARM: S3C24XX: remove maskack irq ack funtions

 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 +
Quoted 9 lines
 arch/arm/plat-s3c24xx/irq.c                  | 1092 +++++++++++++++-----------
 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, 649 insertions(+), 1209 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

Hi Heiko,

Happy New Year!

Basically, looks OK but will look at in this weekend :-)

BTW, I have no idea why you want to keep the irq.c in plat-s3c24xx. As I said, I'm cleaning up the plat-s3c24xx directory and it will be going away.

- Kukjin

#13 lore raw

v2 cover ARM: S3C24XX: rework irq handling for a later dt usage

Am Donnerstag, 3. Januar 2013, 00:34:36 schrieb Kukjin Kim:

Quoted 54 lines
Quoted 44 lines · Heiko St?bner

Second version of redoing the s3c24xx irqs in a generic way by using a declarative approach.

Changes include further generalizations resulting only in common irq-type declarations being needed and thus again easier code.

As in the first version, the 1st patch might be hard to read due to the rewrite character, but I didn't see a way to do these changes in individual steps. So it might be helpful to look at the result after applying this patch.

Runtime-tested on a s3c2416 based board and compile tested for the others.

As also written before, inclusion of the other S3C24XX SoCs to follow once the general approach is acceptable.

Heiko Stuebner (11):
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
ARM: S3C24XX: remove maskack irq ack funtions

 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                  | 1092
Quoted 8 lines

+++++++++++++++----------- 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, 649 insertions(+), 1209 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
Quoted 3 lines

Hi Heiko,

Happy New Year!

a happy new year to you too

Quoted 1 line

Basically, looks OK but will look at in this weekend :-)

cool :-)

Quoted 3 lines

BTW, I have no idea why you want to keep the irq.c in plat-s3c24xx. As I said, I'm cleaning up the plat-s3c24xx directory and it will be going away.

As you might have seen I tried to move it to drivers/irqchip in the past and it seems only drivers using the new irqchip init stuff should go there now.

So I left it where it is for now, to see how far I get with the modifications first. So, as drivers/irqchip is out of the question for now, should we move it to mach-s3c24xx in the meantime?

As I still need to also send the redone devicetree patches on top of this series, I could do the move there to a location you prefer :-)

Heiko