linux-samsung-soc.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/5] ARM: S3C24XX: more fixes and enhancements for the s3c24xx irqs
@ 2013-02-26 22:57 Heiko Stübner
  2013-02-26 22:57 ` [PATCH 1/5] ARM: S3C24XX: fix redundant checks in the irq mapping function Heiko Stübner
                   ` (5 more replies)
  0 siblings, 6 replies; 8+ messages in thread
From: Heiko Stübner @ 2013-02-26 22:57 UTC (permalink / raw)
  To: Kukjin Kim; +Cc: Julia Lawall, linux-samsung-soc, linux-arm-kernel

Asorted fixes and enhancements for the recent redo of the s3c24xx
interrupt controllers.

The only real error that gets fixed is the handling of 0-hwirq as
parent_irq on s3c2412 in patch 2. No other of the s3c24xx platforms
uses the bit0 of the parent controller as parent_irq.

Heiko Stuebner (5):
  ARM: S3C24XX: fix redundant checks in the irq mapping function
  ARM: S3C24XX: fix irq parent check
  ARM: S3C24XX: move s3c24xx_init_irq to s3c2410_init_irq
  ARM: S3C24XX: make s3c24xx_init_intc static
  ARM: S3C24XX: add handle_irq function

 arch/arm/Kconfig                                 |    1 +
 arch/arm/mach-s3c24xx/common.h                   |    1 +
 arch/arm/mach-s3c24xx/include/mach/entry-macro.S |   70 ---------
 arch/arm/mach-s3c24xx/irq.c                      |  167 +++++++++++++--------
 arch/arm/mach-s3c24xx/mach-amlm5900.c            |    2 +-
 arch/arm/mach-s3c24xx/mach-bast.c                |    2 +-
 arch/arm/mach-s3c24xx/mach-h1940.c               |    7 +-
 arch/arm/mach-s3c24xx/mach-n30.c                 |    4 +-
 arch/arm/mach-s3c24xx/mach-otom.c                |    2 +-
 arch/arm/mach-s3c24xx/mach-qt2410.c              |    2 +-
 arch/arm/mach-s3c24xx/mach-smdk2410.c            |    2 +-
 arch/arm/mach-s3c24xx/mach-tct_hammer.c          |    2 +-
 arch/arm/mach-s3c24xx/mach-vr1000.c              |    2 +-
 arch/arm/plat-samsung/include/plat/cpu.h         |    1 -
 14 files changed, 115 insertions(+), 150 deletions(-)
 delete mode 100644 arch/arm/mach-s3c24xx/include/mach/entry-macro.S

-- 
1.7.2.3

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

* [PATCH 1/5] ARM: S3C24XX: fix redundant checks in the irq mapping function
  2013-02-26 22:57 [PATCH 0/5] ARM: S3C24XX: more fixes and enhancements for the s3c24xx irqs Heiko Stübner
@ 2013-02-26 22:57 ` Heiko Stübner
  2013-02-26 22:58 ` [PATCH 2/5] ARM: S3C24XX: fix irq parent check Heiko Stübner
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 8+ messages in thread
From: Heiko Stübner @ 2013-02-26 22:57 UTC (permalink / raw)
  To: Kukjin Kim; +Cc: Julia Lawall, linux-samsung-soc, linux-arm-kernel

The check during the parent handling itself was wrong, as it should have
checked for parent_irq_data.

The interrupt controller structs always contain an irq_data array with 32
entries and the only possible error could be a parent_irq assignment of >31.

As this would point to outside the irq_data array this could contain
anything including non-NULL values. Therefore correct this to check
the parent_irq value to be in the right range.

With the same explanation of a valid interrupt controller always having a
full irq_data array, the topmost irq_data check in s3c24xx_irq_map
can also go away.

Finally the mapping function is only called thru the irq_domain ops, in
which case the intc struct is already successfully created, so there is
no need to check for it again.

Reported-by: Julia Lawall <julia.lawall@lip6.fr>
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
 arch/arm/mach-s3c24xx/irq.c |   18 ++++--------------
 1 files changed, 4 insertions(+), 14 deletions(-)

diff --git a/arch/arm/mach-s3c24xx/irq.c b/arch/arm/mach-s3c24xx/irq.c
index 3f3de74..5257c9f 100644
--- a/arch/arm/mach-s3c24xx/irq.c
+++ b/arch/arm/mach-s3c24xx/irq.c
@@ -324,16 +324,6 @@ static int s3c24xx_irq_map(struct irq_domain *h, unsigned 
int virq,
 	struct s3c_irq_data *parent_irq_data;
 	unsigned int irqno;
 
-	if (!intc) {
-		pr_err("irq-s3c24xx: no controller found for hwirq %lu\n", hw);
-		return -EINVAL;
-	}
-
-	if (!irq_data) {
-		pr_err("irq-s3c24xx: no irq data found for hwirq %lu\n", hw);
-		return -EINVAL;
-	}
-
 	/* attach controller pointer to irq_data */
 	irq_data->intc = intc;
 
@@ -383,13 +373,13 @@ static int s3c24xx_irq_map(struct irq_domain *h, 
unsigned int virq,
 			goto err;
 		}
 
-		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);
+		if (irq_data->parent_irq > 31) {
+			pr_err("irq-s3c24xx: parent irq %lu is out of range\n",
+			       irq_data->parent_irq);
 			goto err;
 		}
 
+		parent_irq_data = &parent_intc->irqs[irq_data->parent_irq];
 		parent_irq_data->sub_intc = intc;
 		parent_irq_data->sub_bits |= (1UL << hw);
 
-- 
1.7.2.3

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

* [PATCH 2/5] ARM: S3C24XX: fix irq parent check
  2013-02-26 22:57 [PATCH 0/5] ARM: S3C24XX: more fixes and enhancements for the s3c24xx irqs Heiko Stübner
  2013-02-26 22:57 ` [PATCH 1/5] ARM: S3C24XX: fix redundant checks in the irq mapping function Heiko Stübner
@ 2013-02-26 22:58 ` Heiko Stübner
  2013-02-26 22:58 ` [PATCH 3/5] ARM: S3C24XX: move s3c24xx_init_irq to s3c2410_init_irq Heiko Stübner
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 8+ messages in thread
From: Heiko Stübner @ 2013-02-26 22:58 UTC (permalink / raw)
  To: Kukjin Kim; +Cc: Julia Lawall, linux-samsung-soc, linux-arm-kernel

The current parent_irq check checks for a value != 0. This does of course
not work when the parent irq sits in the bit 0 of the parent register.
This only affects the eint0 interrupt of the s3c2412.

To fix this behaviour, check for the presence of a parent_intc in the
structure. In an s3c24xx interrupt controller either all interrupts have
parent interrupts or none have, so if a parent controller is available
the parent_irq value always points to a parent_irq.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
 arch/arm/mach-s3c24xx/irq.c |   22 ++++++++--------------
 1 files changed, 8 insertions(+), 14 deletions(-)

diff --git a/arch/arm/mach-s3c24xx/irq.c b/arch/arm/mach-s3c24xx/irq.c
index 5257c9f..a6a7554 100644
--- a/arch/arm/mach-s3c24xx/irq.c
+++ b/arch/arm/mach-s3c24xx/irq.c
@@ -81,7 +81,7 @@ static void s3c_irq_mask(struct irq_data *data)
 	mask |= (1UL << data->hwirq);
 	__raw_writel(mask, intc->reg_mask);
 
-	if (parent_intc && irq_data->parent_irq) {
+	if (parent_intc) {
 		parent_data = &parent_intc->irqs[irq_data->parent_irq];
 
 		/* check to see if we need to mask the parent IRQ */
@@ -105,7 +105,7 @@ static void s3c_irq_unmask(struct irq_data *data)
 	mask &= ~(1UL << data->hwirq);
 	__raw_writel(mask, intc->reg_mask);
 
-	if (parent_intc && irq_data->parent_irq) {
+	if (parent_intc) {
 		irqno = irq_find_mapping(parent_intc->domain,
 					 irq_data->parent_irq);
 		s3c_irq_unmask(irq_get_irq_data(irqno));
@@ -327,6 +327,8 @@ static int s3c24xx_irq_map(struct irq_domain *h, unsigned int virq,
 	/* attach controller pointer to irq_data */
 	irq_data->intc = intc;
 
+	parent_intc = intc->parent;
+
 	/* set handler and flags */
 	switch (irq_data->type) {
 	case S3C_IRQTYPE_NONE:
@@ -335,7 +337,7 @@ static int s3c24xx_irq_map(struct irq_domain *h, unsigned int virq,
 		/* On the S3C2412, the EINT0to3 have a parent irq
 		 * but need the s3c_irq_eint0t4 chip
 		 */
-		if (irq_data->parent_irq && (!soc_is_s3c2412() || hw >= 4))
+		if (parent_intc && (!soc_is_s3c2412() || hw >= 4))
 			irq_set_chip_and_handler(virq, &s3c_irqext_chip,
 						 handle_edge_irq);
 		else
@@ -343,8 +345,7 @@ 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 ||
-		    intc->reg_pending == S3C2416_SRCPND2)
+		if (parent_intc || intc->reg_pending == S3C2416_SRCPND2)
 			irq_set_chip_and_handler(virq, &s3c_irq_level_chip,
 						 handle_edge_irq);
 		else
@@ -352,7 +353,7 @@ static int s3c24xx_irq_map(struct irq_domain *h, unsigned int virq,
 						 handle_edge_irq);
 		break;
 	case S3C_IRQTYPE_LEVEL:
-		if (irq_data->parent_irq)
+		if (parent_intc)
 			irq_set_chip_and_handler(virq, &s3c_irq_level_chip,
 						 handle_level_irq);
 		else
@@ -365,14 +366,7 @@ static int s3c24xx_irq_map(struct irq_domain *h, unsigned int virq,
 	}
 	set_irq_flags(virq, IRQF_VALID);
 
-	if (irq_data->parent_irq) {
-		parent_intc = intc->parent;
-		if (!parent_intc) {
-			pr_err("irq-s3c24xx: no parent controller found for hwirq %lu\n",
-			       hw);
-			goto err;
-		}
-
+	if (parent_intc && irq_data->type != S3C_IRQTYPE_NONE) {
 		if (irq_data->parent_irq > 31) {
 			pr_err("irq-s3c24xx: parent irq %lu is out of range\n",
 			       irq_data->parent_irq);
-- 
1.7.2.3

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

* [PATCH 3/5] ARM: S3C24XX: move s3c24xx_init_irq to s3c2410_init_irq
  2013-02-26 22:57 [PATCH 0/5] ARM: S3C24XX: more fixes and enhancements for the s3c24xx irqs Heiko Stübner
  2013-02-26 22:57 ` [PATCH 1/5] ARM: S3C24XX: fix redundant checks in the irq mapping function Heiko Stübner
  2013-02-26 22:58 ` [PATCH 2/5] ARM: S3C24XX: fix irq parent check Heiko Stübner
@ 2013-02-26 22:58 ` Heiko Stübner
  2013-02-26 22:59 ` [PATCH 4/5] ARM: S3C24XX: make s3c24xx_init_intc static Heiko Stübner
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 8+ messages in thread
From: Heiko Stübner @ 2013-02-26 22:58 UTC (permalink / raw)
  To: Kukjin Kim; +Cc: Julia Lawall, linux-samsung-soc, linux-arm-kernel

The s3c24xx_init_irq function that was the base for all irq inits
is now only used to initialize the real s3c2410 irqs.

Therefore rename it and also move its declaration from plat/cpu.h
to common.h

The eint declaration is used by the vast majority of the SoCs and
gets therefore placed outside any ifdefs.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
 arch/arm/mach-s3c24xx/common.h           |    1 +
 arch/arm/mach-s3c24xx/irq.c              |   69 ++++++++++++++---------------
 arch/arm/mach-s3c24xx/mach-amlm5900.c    |    2 +-
 arch/arm/mach-s3c24xx/mach-bast.c        |    2 +-
 arch/arm/mach-s3c24xx/mach-h1940.c       |    7 +---
 arch/arm/mach-s3c24xx/mach-n30.c         |    4 +-
 arch/arm/mach-s3c24xx/mach-otom.c        |    2 +-
 arch/arm/mach-s3c24xx/mach-qt2410.c      |    2 +-
 arch/arm/mach-s3c24xx/mach-smdk2410.c    |    2 +-
 arch/arm/mach-s3c24xx/mach-tct_hammer.c  |    2 +-
 arch/arm/mach-s3c24xx/mach-vr1000.c      |    2 +-
 arch/arm/plat-samsung/include/plat/cpu.h |    1 -
 12 files changed, 44 insertions(+), 52 deletions(-)

diff --git a/arch/arm/mach-s3c24xx/common.h b/arch/arm/mach-s3c24xx/common.h
index abefeb3..307c371 100644
--- a/arch/arm/mach-s3c24xx/common.h
+++ b/arch/arm/mach-s3c24xx/common.h
@@ -21,6 +21,7 @@ extern void s3c2410_map_io(void);
 extern void s3c2410_init_uarts(struct s3c2410_uartcfg *cfg, int no);
 extern void s3c2410_init_clocks(int xtal);
 extern void s3c2410_restart(char mode, const char *cmd);
+extern void s3c2410_init_irq(void);
 #else
 #define s3c2410_init_clocks NULL
 #define s3c2410_init_uarts NULL
diff --git a/arch/arm/mach-s3c24xx/irq.c b/arch/arm/mach-s3c24xx/irq.c
index a6a7554..ee47654 100644
--- a/arch/arm/mach-s3c24xx/irq.c
+++ b/arch/arm/mach-s3c24xx/irq.c
@@ -509,12 +509,35 @@ err:
 	return ERR_PTR(ret);
 }
 
-/* s3c24xx_init_irq
- *
- * Initialise S3C2410 IRQ system
-*/
+static 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_EINT, .parent_irq = 4 }, /* EINT4 */
+	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT5 */
+	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT6 */
+	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT7 */
+	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT8 */
+	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT9 */
+	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT10 */
+	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT11 */
+	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT12 */
+	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT13 */
+	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT14 */
+	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT15 */
+	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT16 */
+	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT17 */
+	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT18 */
+	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT19 */
+	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT20 */
+	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT21 */
+	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT22 */
+	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT23 */
+};
 
-static struct s3c_irq_data init_base[32] = {
+#ifdef CONFIG_CPU_S3C2410
+static struct s3c_irq_data init_s3c2410base[32] = {
 	{ .type = S3C_IRQTYPE_EINT, }, /* EINT0 */
 	{ .type = S3C_IRQTYPE_EINT, }, /* EINT1 */
 	{ .type = S3C_IRQTYPE_EINT, }, /* EINT2 */
@@ -549,34 +572,7 @@ static struct s3c_irq_data init_base[32] = {
 	{ .type = S3C_IRQTYPE_LEVEL, }, /* ADCPARENT */
 };
 
-static 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_EINT, .parent_irq = 4 }, /* EINT4 */
-	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT5 */
-	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT6 */
-	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT7 */
-	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT8 */
-	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT9 */
-	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT10 */
-	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT11 */
-	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT12 */
-	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT13 */
-	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT14 */
-	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT15 */
-	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT16 */
-	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT17 */
-	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT18 */
-	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT19 */
-	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT20 */
-	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT21 */
-	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT22 */
-	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT23 */
-};
-
-static struct s3c_irq_data init_subint[32] = {
+static struct s3c_irq_data init_s3c2410subint[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 */
@@ -590,7 +586,7 @@ static struct s3c_irq_data init_subint[32] = {
 	{ .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* ADC */
 };
 
-void __init s3c24xx_init_irq(void)
+void __init s3c2410_init_irq(void)
 {
 	struct s3c_irq_intc *main_intc;
 
@@ -598,15 +594,16 @@ void __init s3c24xx_init_irq(void)
 	init_FIQ(FIQ_START);
 #endif
 
-	main_intc = s3c24xx_init_intc(NULL, &init_base[0], NULL, 0x4a000000);
+	main_intc = s3c24xx_init_intc(NULL, &init_s3c2410base[0], NULL, 0x4a000000);
 	if (IS_ERR(main_intc)) {
 		pr_err("irq: could not create main interrupt controller\n");
 		return;
 	}
 
-	s3c24xx_init_intc(NULL, &init_subint[0], main_intc, 0x4a000018);
+	s3c24xx_init_intc(NULL, &init_s3c2410subint[0], main_intc, 0x4a000018);
 	s3c24xx_init_intc(NULL, &init_eint[0], main_intc, 0x560000a4);
 }
+#endif
 
 #ifdef CONFIG_CPU_S3C2412
 static struct s3c_irq_data init_s3c2412base[32] = {
diff --git a/arch/arm/mach-s3c24xx/mach-amlm5900.c b/arch/arm/mach-s3c24xx/mach-amlm5900.c
index 40d59de..dc720ad 100644
--- a/arch/arm/mach-s3c24xx/mach-amlm5900.c
+++ b/arch/arm/mach-s3c24xx/mach-amlm5900.c
@@ -238,7 +238,7 @@ static void __init amlm5900_init(void)
 MACHINE_START(AML_M5900, "AML_M5900")
 	.atag_offset	= 0x100,
 	.map_io		= amlm5900_map_io,
-	.init_irq	= s3c24xx_init_irq,
+	.init_irq	= s3c2410_init_irq,
 	.init_machine	= amlm5900_init,
 	.init_time	= samsung_timer_init,
 	.restart	= s3c2410_restart,
diff --git a/arch/arm/mach-s3c24xx/mach-bast.c b/arch/arm/mach-s3c24xx/mach-bast.c
index 8089156..82ed39e 100644
--- a/arch/arm/mach-s3c24xx/mach-bast.c
+++ b/arch/arm/mach-s3c24xx/mach-bast.c
@@ -605,7 +605,7 @@ MACHINE_START(BAST, "Simtec-BAST")
 	/* Maintainer: Ben Dooks <ben@simtec.co.uk> */
 	.atag_offset	= 0x100,
 	.map_io		= bast_map_io,
-	.init_irq	= s3c24xx_init_irq,
+	.init_irq	= s3c2410_init_irq,
 	.init_machine	= bast_init,
 	.init_time	= samsung_timer_init,
 	.restart	= s3c2410_restart,
diff --git a/arch/arm/mach-s3c24xx/mach-h1940.c b/arch/arm/mach-s3c24xx/mach-h1940.c
index 0872971..c0c24e9 100644
--- a/arch/arm/mach-s3c24xx/mach-h1940.c
+++ b/arch/arm/mach-s3c24xx/mach-h1940.c
@@ -667,11 +667,6 @@ static void __init h1940_reserve(void)
 	memblock_reserve(0x30081000, 0x1000);
 }
 
-static void __init h1940_init_irq(void)
-{
-	s3c24xx_init_irq();
-}
-
 static void __init h1940_init(void)
 {
 	u32 tmp;
@@ -740,7 +735,7 @@ MACHINE_START(H1940, "IPAQ-H1940")
 	.atag_offset	= 0x100,
 	.map_io		= h1940_map_io,
 	.reserve	= h1940_reserve,
-	.init_irq	= h1940_init_irq,
+	.init_irq	= s3c2410_init_irq,
 	.init_machine	= h1940_init,
 	.init_time	= samsung_timer_init,
 	.restart	= s3c2410_restart,
diff --git a/arch/arm/mach-s3c24xx/mach-n30.c b/arch/arm/mach-s3c24xx/mach-n30.c
index 55f52a5..c19e6a5 100644
--- a/arch/arm/mach-s3c24xx/mach-n30.c
+++ b/arch/arm/mach-s3c24xx/mach-n30.c
@@ -592,7 +592,7 @@ MACHINE_START(N30, "Acer-N30")
 	.atag_offset	= 0x100,
 	.init_time	= samsung_timer_init,
 	.init_machine	= n30_init,
-	.init_irq	= s3c24xx_init_irq,
+	.init_irq	= s3c2410_init_irq,
 	.map_io		= n30_map_io,
 	.restart	= s3c2410_restart,
 MACHINE_END
@@ -603,7 +603,7 @@ MACHINE_START(N35, "Acer-N35")
 	.atag_offset	= 0x100,
 	.init_time	= samsung_timer_init,
 	.init_machine	= n30_init,
-	.init_irq	= s3c24xx_init_irq,
+	.init_irq	= s3c2410_init_irq,
 	.map_io		= n30_map_io,
 	.restart	= s3c2410_restart,
 MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-otom.c b/arch/arm/mach-s3c24xx/mach-otom.c
index ebbd840..1491c6d 100644
--- a/arch/arm/mach-s3c24xx/mach-otom.c
+++ b/arch/arm/mach-s3c24xx/mach-otom.c
@@ -116,7 +116,7 @@ MACHINE_START(OTOM, "Nex Vision - Otom 1.1")
 	.atag_offset	= 0x100,
 	.map_io		= otom11_map_io,
 	.init_machine	= otom11_init,
-	.init_irq	= s3c24xx_init_irq,
+	.init_irq	= s3c2410_init_irq,
 	.init_time	= samsung_timer_init,
 	.restart	= s3c2410_restart,
 MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-qt2410.c b/arch/arm/mach-s3c24xx/mach-qt2410.c
index 18e1c5f..ef29d6a 100644
--- a/arch/arm/mach-s3c24xx/mach-qt2410.c
+++ b/arch/arm/mach-s3c24xx/mach-qt2410.c
@@ -343,7 +343,7 @@ static void __init qt2410_machine_init(void)
 MACHINE_START(QT2410, "QT2410")
 	.atag_offset	= 0x100,
 	.map_io		= qt2410_map_io,
-	.init_irq	= s3c24xx_init_irq,
+	.init_irq	= s3c2410_init_irq,
 	.init_machine	= qt2410_machine_init,
 	.init_time	= samsung_timer_init,
 	.restart	= s3c2410_restart,
diff --git a/arch/arm/mach-s3c24xx/mach-smdk2410.c b/arch/arm/mach-s3c24xx/mach-smdk2410.c
index d0fa44f..048553d 100644
--- a/arch/arm/mach-s3c24xx/mach-smdk2410.c
+++ b/arch/arm/mach-s3c24xx/mach-smdk2410.c
@@ -116,7 +116,7 @@ MACHINE_START(SMDK2410, "SMDK2410") /* @TODO: request a new identifier and switc
 	/* Maintainer: Jonas Dietsche */
 	.atag_offset	= 0x100,
 	.map_io		= smdk2410_map_io,
-	.init_irq	= s3c24xx_init_irq,
+	.init_irq	= s3c2410_init_irq,
 	.init_machine	= smdk2410_init,
 	.init_time	= samsung_timer_init,
 	.restart	= s3c2410_restart,
diff --git a/arch/arm/mach-s3c24xx/mach-tct_hammer.c b/arch/arm/mach-s3c24xx/mach-tct_hammer.c
index 5ad39d0..d67c14d 100644
--- a/arch/arm/mach-s3c24xx/mach-tct_hammer.c
+++ b/arch/arm/mach-s3c24xx/mach-tct_hammer.c
@@ -149,7 +149,7 @@ static void __init tct_hammer_init(void)
 MACHINE_START(TCT_HAMMER, "TCT_HAMMER")
 	.atag_offset	= 0x100,
 	.map_io		= tct_hammer_map_io,
-	.init_irq	= s3c24xx_init_irq,
+	.init_irq	= s3c2410_init_irq,
 	.init_machine	= tct_hammer_init,
 	.init_time	= samsung_timer_init,
 	.restart	= s3c2410_restart,
diff --git a/arch/arm/mach-s3c24xx/mach-vr1000.c b/arch/arm/mach-s3c24xx/mach-vr1000.c
index 0e2a215..c1cdd8c 100644
--- a/arch/arm/mach-s3c24xx/mach-vr1000.c
+++ b/arch/arm/mach-s3c24xx/mach-vr1000.c
@@ -355,7 +355,7 @@ MACHINE_START(VR1000, "Thorcom-VR1000")
 	.atag_offset	= 0x100,
 	.map_io		= vr1000_map_io,
 	.init_machine	= vr1000_init,
-	.init_irq	= s3c24xx_init_irq,
+	.init_irq	= s3c2410_init_irq,
 	.init_time	= samsung_timer_init,
 	.restart	= s3c2410_restart,
 MACHINE_END
diff --git a/arch/arm/plat-samsung/include/plat/cpu.h b/arch/arm/plat-samsung/include/plat/cpu.h
index 0f6c47a..989fefe 100644
--- a/arch/arm/plat-samsung/include/plat/cpu.h
+++ b/arch/arm/plat-samsung/include/plat/cpu.h
@@ -183,7 +183,6 @@ extern void s3c_init_cpu(unsigned long idcode,
 
 /* core initialisation functions */
 
-extern void s3c24xx_init_irq(void);
 extern void s5p_init_irq(u32 *vic, u32 num_vic);
 
 extern void s3c24xx_init_io(struct map_desc *mach_desc, int size);
-- 
1.7.2.3

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

* [PATCH 4/5] ARM: S3C24XX: make s3c24xx_init_intc static
  2013-02-26 22:57 [PATCH 0/5] ARM: S3C24XX: more fixes and enhancements for the s3c24xx irqs Heiko Stübner
                   ` (2 preceding siblings ...)
  2013-02-26 22:58 ` [PATCH 3/5] ARM: S3C24XX: move s3c24xx_init_irq to s3c2410_init_irq Heiko Stübner
@ 2013-02-26 22:59 ` Heiko Stübner
  2013-02-26 23:00 ` [PATCH 5/5] ARM: S3C24XX: add handle_irq function Heiko Stübner
  2013-03-09  9:14 ` [PATCH 0/5] ARM: S3C24XX: more fixes and enhancements for the s3c24xx irqs Kukjin Kim
  5 siblings, 0 replies; 8+ messages in thread
From: Heiko Stübner @ 2013-02-26 22:59 UTC (permalink / raw)
  To: Kukjin Kim; +Cc: Julia Lawall, linux-samsung-soc, linux-arm-kernel

It's not used anywhere else.

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

diff --git a/arch/arm/mach-s3c24xx/irq.c b/arch/arm/mach-s3c24xx/irq.c
index ee47654..8bc2931 100644
--- a/arch/arm/mach-s3c24xx/irq.c
+++ b/arch/arm/mach-s3c24xx/irq.c
@@ -428,7 +428,7 @@ static void s3c24xx_clear_intc(struct s3c_irq_intc *intc)
 	}
 }
 
-struct s3c_irq_intc *s3c24xx_init_intc(struct device_node *np,
+static struct s3c_irq_intc *s3c24xx_init_intc(struct device_node *np,
 				       struct s3c_irq_data *irq_data,
 				       struct s3c_irq_intc *parent,
 				       unsigned long address)
-- 
1.7.2.3

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

* [PATCH 5/5] ARM: S3C24XX: add handle_irq function
  2013-02-26 22:57 [PATCH 0/5] ARM: S3C24XX: more fixes and enhancements for the s3c24xx irqs Heiko Stübner
                   ` (3 preceding siblings ...)
  2013-02-26 22:59 ` [PATCH 4/5] ARM: S3C24XX: make s3c24xx_init_intc static Heiko Stübner
@ 2013-02-26 23:00 ` Heiko Stübner
  2013-03-09  9:14 ` [PATCH 0/5] ARM: S3C24XX: more fixes and enhancements for the s3c24xx irqs Kukjin Kim
  5 siblings, 0 replies; 8+ messages in thread
From: Heiko Stübner @ 2013-02-26 23:00 UTC (permalink / raw)
  To: Kukjin Kim; +Cc: Julia Lawall, linux-samsung-soc, linux-arm-kernel

This removes the dependency on static irq mappings for basic irq handling
and makes the s3c24xx entry-macro.S obsolete.

Also the interrupts of the second full interrupt controller on the s3c2416
are really handled now, which was forgotten when adding them.

The handling itself does the same as the previous assembler-code in that
it tries to get the interrupt offset from the offset register first and
if that produces wrong results manually searches for the interrupt bit
in the pending register value. It also saves the historic comment which
explains the reason behind this.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
 arch/arm/Kconfig                                 |    1 +
 arch/arm/mach-s3c24xx/include/mach/entry-macro.S |   70 ----------------------
 arch/arm/mach-s3c24xx/irq.c                      |   58 ++++++++++++++++++
 3 files changed, 59 insertions(+), 70 deletions(-)
 delete mode 100644 arch/arm/mach-s3c24xx/include/mach/entry-macro.S

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index aacea44..23e894e 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -777,6 +777,7 @@ config ARCH_S3C24XX
 	select HAVE_S3C2410_I2C if I2C
 	select HAVE_S3C2410_WATCHDOG if WATCHDOG
 	select HAVE_S3C_RTC if RTC_CLASS
+	select MULTI_IRQ_HANDLER
 	select NEED_MACH_GPIO_H
 	select NEED_MACH_IO_H
 	help
diff --git a/arch/arm/mach-s3c24xx/include/mach/entry-macro.S b/arch/arm/mach-s3c24xx/include/mach/entry-macro.S
deleted file mode 100644
index 6a21bee..0000000
--- a/arch/arm/mach-s3c24xx/include/mach/entry-macro.S
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * arch/arm/mach-s3c2410/include/mach/entry-macro.S
- *
- * Low-level IRQ helper macros for S3C2410-based platforms
- *
- * This file is licensed under  the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
-*/
-
-/* We have a problem that the INTOFFSET register does not always
- * show one interrupt. Occasionally we get two interrupts through
- * the prioritiser, and this causes the INTOFFSET register to show
- * what looks like the logical-or of the two interrupt numbers.
- *
- * Thanks to Klaus, Shannon, et al for helping to debug this problem
-*/
-
-#define INTPND		(0x10)
-#define INTOFFSET	(0x14)
-
-#include <mach/hardware.h>
-#include <asm/irq.h>
-
-	.macro  get_irqnr_preamble, base, tmp
-	.endm
-
-	.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
-
-		mov	\base, #S3C24XX_VA_IRQ
-
-		@@ try the interrupt offset register, since it is there
-
-		ldr	\irqstat, [\base, #INTPND ]
-		teq	\irqstat, #0
-		beq	1002f
-		ldr	\irqnr, [\base, #INTOFFSET ]
-		mov	\tmp, #1
-		tst	\irqstat, \tmp, lsl \irqnr
-		bne	1001f
-
-		@@ the number specified is not a valid irq, so try
-		@@ and work it out for ourselves
-
-		mov	\irqnr, #0		@@ start here
-
-		@@ work out which irq (if any) we got
-
-		movs	\tmp, \irqstat, lsl#16
-		addeq	\irqnr, \irqnr, #16
-		moveq	\irqstat, \irqstat, lsr#16
-		tst	\irqstat, #0xff
-		addeq	\irqnr, \irqnr, #8
-		moveq	\irqstat, \irqstat, lsr#8
-		tst	\irqstat, #0xf
-		addeq	\irqnr, \irqnr, #4
-		moveq	\irqstat, \irqstat, lsr#4
-		tst	\irqstat, #0x3
-		addeq	\irqnr, \irqnr, #2
-		moveq	\irqstat, \irqstat, lsr#2
-		tst	\irqstat, #0x1
-		addeq	\irqnr, \irqnr, #1
-
-		@@ we have the value
-1001:
-		adds	\irqnr, \irqnr, #IRQ_EINT0
-1002:
-		@@ exit here, Z flag unset if IRQ
-
-	.endm
diff --git a/arch/arm/mach-s3c24xx/irq.c b/arch/arm/mach-s3c24xx/irq.c
index 8bc2931..5c9f8b7 100644
--- a/arch/arm/mach-s3c24xx/irq.c
+++ b/arch/arm/mach-s3c24xx/irq.c
@@ -26,6 +26,7 @@
 #include <linux/device.h>
 #include <linux/irqdomain.h>
 
+#include <asm/exception.h>
 #include <asm/mach/irq.h>
 
 #include <mach/regs-irq.h>
@@ -282,6 +283,56 @@ static void s3c_irq_demux(unsigned int irq, struct irq_desc *desc)
 	chained_irq_exit(chip, desc);
 }
 
+static struct s3c_irq_intc *main_intc;
+static struct s3c_irq_intc *main_intc2;
+
+static inline int s3c24xx_handle_intc(struct s3c_irq_intc *intc,
+				      struct pt_regs *regs)
+{
+	int pnd;
+	int offset;
+	int irq;
+
+	pnd = __raw_readl(intc->reg_intpnd);
+	if (!pnd)
+		return false;
+
+	/* We have a problem that the INTOFFSET register does not always
+	 * show one interrupt. Occasionally we get two interrupts through
+	 * the prioritiser, and this causes the INTOFFSET register to show
+	 * what looks like the logical-or of the two interrupt numbers.
+	 *
+	 * Thanks to Klaus, Shannon, et al for helping to debug this problem
+	 */
+	offset = __raw_readl(intc->reg_intpnd + 4);
+
+	/* Find the bit manually, when the offset is wrong.
+	 * The pending register only ever contains the one bit of the next
+	 * interrupt to handle.
+	 */
+	if (!(pnd & (1 << offset)))
+		offset =  __ffs(pnd);
+
+	irq = irq_find_mapping(intc->domain, offset);
+	handle_IRQ(irq, regs);
+	return true;
+}
+
+asmlinkage void __exception_irq_entry s3c24xx_handle_irq(struct pt_regs *regs)
+{
+	do {
+		if (likely(main_intc))
+			if (s3c24xx_handle_intc(main_intc, regs))
+				continue;
+
+		if (main_intc2)
+			if (s3c24xx_handle_intc(main_intc2, regs))
+				continue;
+
+		break;
+	} while (1);
+}
+
 #ifdef CONFIG_FIQ
 /**
  * s3c24xx_set_fiq - set the FIQ routing
@@ -502,6 +553,13 @@ static struct s3c_irq_intc *s3c24xx_init_intc(struct device_node *np,
 		goto err;
 	}
 
+	if (address == 0x4a000000)
+		main_intc = intc;
+	else if (address == 0x4a000040)
+		main_intc2 = intc;
+
+	set_handle_irq(s3c24xx_handle_irq);
+
 	return intc;
 
 err:
-- 
1.7.2.3

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

* RE: [PATCH 0/5] ARM: S3C24XX: more fixes and enhancements for the s3c24xx irqs
  2013-02-26 22:57 [PATCH 0/5] ARM: S3C24XX: more fixes and enhancements for the s3c24xx irqs Heiko Stübner
                   ` (4 preceding siblings ...)
  2013-02-26 23:00 ` [PATCH 5/5] ARM: S3C24XX: add handle_irq function Heiko Stübner
@ 2013-03-09  9:14 ` Kukjin Kim
  5 siblings, 0 replies; 8+ messages in thread
From: Kukjin Kim @ 2013-03-09  9:14 UTC (permalink / raw)
  To: 'Heiko Stübner'
  Cc: 'Julia Lawall', linux-samsung-soc, linux-arm-kernel

Heiko Stübner wrote:
> 
> Asorted fixes and enhancements for the recent redo of the s3c24xx
> interrupt controllers.
> 
> The only real error that gets fixed is the handling of 0-hwirq as
> parent_irq on s3c2412 in patch 2. No other of the s3c24xx platforms
> uses the bit0 of the parent controller as parent_irq.
> 
> Heiko Stuebner (5):
>   ARM: S3C24XX: fix redundant checks in the irq mapping function
>   ARM: S3C24XX: fix irq parent check
>   ARM: S3C24XX: move s3c24xx_init_irq to s3c2410_init_irq
>   ARM: S3C24XX: make s3c24xx_init_intc static
>   ARM: S3C24XX: add handle_irq function
> 
>  arch/arm/Kconfig                                 |    1 +
>  arch/arm/mach-s3c24xx/common.h                   |    1 +
>  arch/arm/mach-s3c24xx/include/mach/entry-macro.S |   70 ---------
>  arch/arm/mach-s3c24xx/irq.c                      |  167 +++++++++++++--------
>  arch/arm/mach-s3c24xx/mach-amlm5900.c            |    2 +-
>  arch/arm/mach-s3c24xx/mach-bast.c                |    2 +-
>  arch/arm/mach-s3c24xx/mach-h1940.c               |    7 +-
>  arch/arm/mach-s3c24xx/mach-n30.c                 |    4 +-
>  arch/arm/mach-s3c24xx/mach-otom.c                |    2 +-
>  arch/arm/mach-s3c24xx/mach-qt2410.c              |    2 +-
>  arch/arm/mach-s3c24xx/mach-smdk2410.c            |    2 +-
>  arch/arm/mach-s3c24xx/mach-tct_hammer.c          |    2 +-
>  arch/arm/mach-s3c24xx/mach-vr1000.c              |    2 +-
>  arch/arm/plat-samsung/include/plat/cpu.h         |    1 -
>  14 files changed, 115 insertions(+), 150 deletions(-)
>  delete mode 100644 arch/arm/mach-s3c24xx/include/mach/entry-macro.S
> 
> --
> 1.7.2.3

Looks good to me, applied.

Thanks.

- Kukjin

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

* [PATCH 0/5] ARM: S3C24XX: more fixes and enhancements for the s3c24xx irqs
@ 2013-02-26 22:55 Heiko Stübner
  0 siblings, 0 replies; 8+ messages in thread
From: Heiko Stübner @ 2013-02-26 22:55 UTC (permalink / raw)
  To: Kukjin Kim; +Cc: Julia Lawall, linux-samsung-soc, linux-arm-kernel

Asorted fixes and enhancements for the recent redo of the s3c24xx
interrupt controllers.

The only real error that gets fixed is the handling of 0-hwirq as
parent_irq on s3c2412 in patch 2. No other of the s3c24xx platforms
uses the bit0 of the parent controller as parent_irq.

Heiko Stuebner (5):
  ARM: S3C24XX: fix redundant checks in the irq mapping function
  ARM: S3C24XX: fix irq parent check
  ARM: S3C24XX: move s3c24xx_init_irq to s3c2410_init_irq
  ARM: S3C24XX: make s3c24xx_init_intc static
  ARM: S3C24XX: add handle_irq function

 arch/arm/Kconfig                                 |    1 +
 arch/arm/mach-s3c24xx/common.h                   |    1 +
 arch/arm/mach-s3c24xx/include/mach/entry-macro.S |   70 ---------
 arch/arm/mach-s3c24xx/irq.c                      |  167 +++++++++++++--------
 arch/arm/mach-s3c24xx/mach-amlm5900.c            |    2 +-
 arch/arm/mach-s3c24xx/mach-bast.c                |    2 +-
 arch/arm/mach-s3c24xx/mach-h1940.c               |    7 +-
 arch/arm/mach-s3c24xx/mach-n30.c                 |    4 +-
 arch/arm/mach-s3c24xx/mach-otom.c                |    2 +-
 arch/arm/mach-s3c24xx/mach-qt2410.c              |    2 +-
 arch/arm/mach-s3c24xx/mach-smdk2410.c            |    2 +-
 arch/arm/mach-s3c24xx/mach-tct_hammer.c          |    2 +-
 arch/arm/mach-s3c24xx/mach-vr1000.c              |    2 +-
 arch/arm/plat-samsung/include/plat/cpu.h         |    1 -
 14 files changed, 115 insertions(+), 150 deletions(-)
 delete mode 100644 arch/arm/mach-s3c24xx/include/mach/entry-macro.S

-- 
1.7.2.3

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

end of thread, other threads:[~2013-03-09  9:14 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-02-26 22:57 [PATCH 0/5] ARM: S3C24XX: more fixes and enhancements for the s3c24xx irqs Heiko Stübner
2013-02-26 22:57 ` [PATCH 1/5] ARM: S3C24XX: fix redundant checks in the irq mapping function Heiko Stübner
2013-02-26 22:58 ` [PATCH 2/5] ARM: S3C24XX: fix irq parent check Heiko Stübner
2013-02-26 22:58 ` [PATCH 3/5] ARM: S3C24XX: move s3c24xx_init_irq to s3c2410_init_irq Heiko Stübner
2013-02-26 22:59 ` [PATCH 4/5] ARM: S3C24XX: make s3c24xx_init_intc static Heiko Stübner
2013-02-26 23:00 ` [PATCH 5/5] ARM: S3C24XX: add handle_irq function Heiko Stübner
2013-03-09  9:14 ` [PATCH 0/5] ARM: S3C24XX: more fixes and enhancements for the s3c24xx irqs Kukjin Kim
  -- strict thread matches above, loose matches on Subject: below --
2013-02-26 22:55 Heiko Stübner

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).