Skip to contentSkip to conversation

MIPS: Mark Eins: Fix cascading interrupt dispatcher

PATCH In review Shinya Kuribayashi 2 participants 7 messages Mar 21, 2009 – Mar 23, 2009 MIPS

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 MIPS: Mark Eins: Fix cascading interrupt dispatcher

* Fix mis-calculated IRQ bitshift on cascading interrupts
* Prevent cascading interrupt bits being processed afterward

---
 arch/mips/emma/markeins/irq.c |   10 ++++++----
 1 files changed, 6 insertions(+), 4 deletions(-)
arch/mips/emma/markeins/irq.c +6 -4
index c2583ec..263132d 100644
@@ -213,8 +213,7 @@ void emma2rh_irq_dispatch(void)
 		    emma2rh_in32(EMMA2RH_BHIF_INT_EN_0);
 
 #ifdef EMMA2RH_SW_CASCADE
-	if (intStatus &
-	    (1 << ((EMMA2RH_SW_CASCADE - EMMA2RH_IRQ_INT0) & (32 - 1)))) {
+	if (intStatus & (1UL << EMMA2RH_SW_CASCADE)) {
 		u32 swIntStatus;
 		swIntStatus = emma2rh_in32(EMMA2RH_BHIF_SW_INT)
 		    & emma2rh_in32(EMMA2RH_BHIF_SW_INT_EN);
@@ -225,6 +224,8 @@ void emma2rh_irq_dispatch(void)
 			}
 		}
 	}
+	/* Skip S/W interrupt */
+	intStatus &= ~(1UL << EMMA2RH_SW_CASCADE);
 #endif
 
 	for (i = 0, bitmask = 1; i < 32; i++, bitmask <<= 1) {
@@ -238,8 +239,7 @@ void emma2rh_irq_dispatch(void)
 		    emma2rh_in32(EMMA2RH_BHIF_INT_EN_1);
 
 #ifdef EMMA2RH_GPIO_CASCADE
-	if (intStatus &
-	    (1 << ((EMMA2RH_GPIO_CASCADE - EMMA2RH_IRQ_INT0) & (32 - 1)))) {
+	if (intStatus & (1UL << (EMMA2RH_GPIO_CASCADE % 32))) {
 		u32 gpioIntStatus;
 		gpioIntStatus = emma2rh_in32(EMMA2RH_GPIO_INT_ST)
 		    & emma2rh_in32(EMMA2RH_GPIO_INT_MASK);
@@ -250,6 +250,8 @@ void emma2rh_irq_dispatch(void)
 			}
 		}
 	}
+	/* Skip GPIO interrupt */
+	intStatus &= ~(1UL << (EMMA2RH_GPIO_CASCADE % 32));
 #endif
 
 	for (i = 32, bitmask = 1; i < 64; i++, bitmask <<= 1) {
#1 lore raw

PATCH 1/1 MIPS: EMMA2RH: Use handle_edge_irq() handler for GPIO interrupts

EMMA's GPIO interrupts are latched by GPIO interrupt status register. In this case, we're encouraged to use handle_edge_irq() handler.

The following changes are made along with replacing set_irq_chip() with set_irq_chip_and_handler_name(,,handle_edge_irq,"edge"):

* Fix emma2rh_gpio_irq_ack not to disable interrupts

With handle_edge_irq(), we're not expected to disable interrupts when chip->ack is served, so fix it accordingly. We also add a new emma2rh_gpio_irq_mask_ack() for chip->mask_ack operation, instead.

* Remove emma2rh_gpio_irq_end(), as chip->end is no longer served.

---
 arch/mips/emma/markeins/irq.c |   28 ++++++++++------------------
 1 files changed, 10 insertions(+), 18 deletions(-)
arch/mips/emma/markeins/irq.c +10 -18
index 263132d..1e6457c 100644
@@ -149,37 +149,28 @@ static void emma2rh_gpio_irq_disable(unsigned int irq)
 
 static void emma2rh_gpio_irq_ack(unsigned int irq)
 {
-	u32 reg;
-
 	irq -= EMMA2RH_GPIO_IRQ_BASE;
 	emma2rh_out32(EMMA2RH_GPIO_INT_ST, ~(1 << irq));
-
-	reg = emma2rh_in32(EMMA2RH_GPIO_INT_MASK);
-	reg &= ~(1 << irq);
-	emma2rh_out32(EMMA2RH_GPIO_INT_MASK, reg);
 }
 
-static void emma2rh_gpio_irq_end(unsigned int irq)
+static void emma2rh_gpio_irq_mask_ack(unsigned int irq)
 {
 	u32 reg;
 
-	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
-
-		irq -= EMMA2RH_GPIO_IRQ_BASE;
+	irq -= EMMA2RH_GPIO_IRQ_BASE;
+	emma2rh_out32(EMMA2RH_GPIO_INT_ST, ~(1 << irq));
 
-		reg = emma2rh_in32(EMMA2RH_GPIO_INT_MASK);
-		reg |= 1 << irq;
-		emma2rh_out32(EMMA2RH_GPIO_INT_MASK, reg);
-	}
+	reg = emma2rh_in32(EMMA2RH_GPIO_INT_MASK);
+	reg &= ~(1 << irq);
+	emma2rh_out32(EMMA2RH_GPIO_INT_MASK, reg);
 }
 
 struct irq_chip emma2rh_gpio_irq_controller = {
 	.name = "emma2rh_gpio_irq",
 	.ack = emma2rh_gpio_irq_ack,
 	.mask = emma2rh_gpio_irq_disable,
-	.mask_ack = emma2rh_gpio_irq_ack,
+	.mask_ack = emma2rh_gpio_irq_mask_ack,
 	.unmask = emma2rh_gpio_irq_enable,
-	.end = emma2rh_gpio_irq_end,
 };
 
 void emma2rh_gpio_irq_init(void)
@@ -187,8 +178,9 @@ void emma2rh_gpio_irq_init(void)
 	u32 i;
 
 	for (i = 0; i < NUM_EMMA2RH_IRQ_GPIO; i++)
-		set_irq_chip(EMMA2RH_GPIO_IRQ_BASE + i,
-			     &emma2rh_gpio_irq_controller);
+		set_irq_chip_and_handler_name(EMMA2RH_GPIO_IRQ_BASE + i,
+					      &emma2rh_gpio_irq_controller,
+					      handle_edge_irq, "edge");
 }
 
 static struct irqaction irq_cascade = {
#2 lore raw

PATCH 1/1 MIPS: EMMA2RH: Use set_irq_chip_and_handler_name

Fix two remaining set_irq_chip_and_handler() users which are encourated to migrate to set_irq_chip_and_handler_name().

---
 arch/mips/emma/markeins/irq.c |   12 ++++++------
 1 files changed, 6 insertions(+), 6 deletions(-)
arch/mips/emma/markeins/irq.c +6 -6
index 1e6457c..2bbc41a 100644
@@ -80,9 +80,9 @@ void emma2rh_irq_init(void)
 	u32 i;
 
 	for (i = 0; i < NUM_EMMA2RH_IRQ; i++)
-		set_irq_chip_and_handler(EMMA2RH_IRQ_BASE + i,
-					 &emma2rh_irq_controller,
-					 handle_level_irq);
+		set_irq_chip_and_handler_name(EMMA2RH_IRQ_BASE + i,
+					      &emma2rh_irq_controller,
+					      handle_level_irq, "level");
 }
 
 static void emma2rh_sw_irq_enable(unsigned int irq)
@@ -120,9 +120,9 @@ void emma2rh_sw_irq_init(void)
 	u32 i;
 
 	for (i = 0; i < NUM_EMMA2RH_IRQ_SW; i++)
-		set_irq_chip_and_handler(EMMA2RH_SW_IRQ_BASE + i,
-					 &emma2rh_sw_irq_controller,
-					 handle_level_irq);
+		set_irq_chip_and_handler_name(EMMA2RH_SW_IRQ_BASE + i,
+					      &emma2rh_sw_irq_controller,
+					      handle_level_irq, "level");
 }
 
 static void emma2rh_gpio_irq_enable(unsigned int irq)
#3 lore raw

PATCH 1/1 MIPS: EMMA2RH: Set UART mapbase

---

 arch/mips/emma/markeins/platform.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)
arch/mips/emma/markeins/platform.c +3 -0
index d5f47e4..80ae12e 100644
@@ -110,6 +110,7 @@ struct platform_device i2c_emma_devices[] = {
 static struct  plat_serial8250_port platform_serial_ports[] = {
 	[0] = {
 		.membase= (void __iomem*)KSEG1ADDR(EMMA2RH_PFUR0_BASE + 3),
+		.mapbase = EMMA2RH_PFUR0_BASE + 3,
 		.irq = EMMA2RH_IRQ_PFUR0,
 		.uartclk = EMMA2RH_SERIAL_CLOCK,
 		.regshift = 4,
@@ -117,6 +118,7 @@ static struct  plat_serial8250_port platform_serial_ports[] = {
 		.flags = EMMA2RH_SERIAL_FLAGS,
        }, [1] = {
 		.membase = (void __iomem*)KSEG1ADDR(EMMA2RH_PFUR1_BASE + 3),
+		.mapbase = EMMA2RH_PFUR1_BASE + 3,
 		.irq = EMMA2RH_IRQ_PFUR1,
 		.uartclk = EMMA2RH_SERIAL_CLOCK,
 		.regshift = 4,
@@ -124,6 +126,7 @@ static struct  plat_serial8250_port platform_serial_ports[] = {
 		.flags = EMMA2RH_SERIAL_FLAGS,
        }, [2] = {
 		.membase = (void __iomem*)KSEG1ADDR(EMMA2RH_PFUR2_BASE + 3),
+		.mapbase = EMMA2RH_PFUR2_BASE + 3,
 		.irq = EMMA2RH_IRQ_PFUR2,
 		.uartclk = EMMA2RH_SERIAL_CLOCK,
 		.regshift = 4,
#5 lore raw
Quoted 5 lines · Ralf Baechle

Looks ok - but this patch series conflicts with your earlier patch

http://www.linux-mips.org/git?p=linux-queue.git;a=commit;h=45d0f39ad6ecc84fa5a3ca301497842ea68bd633

Let me know what to do. Thanks.

If possible, please drop the commit above, then apply new four patches. Or, apply three patches except for "MIPS: EMMA2RH: Use handle_edge_irq() handler". I hope they don't conflict with the commit above.

MIPS: Mark Eins: Fix cascading interrupt dispatcher
* MIPS: EMMA2RH: Use handle_edge_irq() handler for GPIO interrupts
MIPS: EMMA2RH: Use set_irq_chip_and_handler_name
MIPS: EMMA2RH: Set UART mapbase

Sorry for inconvenience,

P.S.

Quoted 1 line

* Prevent cascading interrupt bits being processed afterward

I would like to say `prevent A from B', of course...

Shinya

#6 lore raw
Quoted 10 lines · Shinya Kuribayashi
Quoted 5 lines · Ralf Baechle

Looks ok - but this patch series conflicts with your earlier patch

http://www.linux-mips.org/git?p=linux-queue.git;a=commit;h=45d0f39ad6ecc84fa5a3ca301497842ea68bd633

Let me know what to do. Thanks.

If possible, please drop the commit above, then apply new four patches. Or, apply three patches except for "MIPS: EMMA2RH: Use handle_edge_irq() handler". I hope they don't conflict with the commit above.

Okay, done.

Quoted 3 lines
Quoted 1 line

* Prevent cascading interrupt from bits being processed afterward

I would like to say `prevent A from B', of course...

Fixed.

Ralf