linux-omap.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Re: ARM: OMAP3: Fix get_irqnr_and_base to clear spurious interrupt bits
@ 2008-10-23 18:13 Rick Bronson
  2008-10-23 18:21 ` Tony Lindgren
  0 siblings, 1 reply; 20+ messages in thread
From: Rick Bronson @ 2008-10-23 18:13 UTC (permalink / raw)
  To: linux-omap

Tony,

> Well we should let the generic irq handler to do the logging.. But I
> guess nothing will happen if adm_do_IRQ() does not get called.
> 
> We could have a dummy handler for some invented higher number that would
> capture the spurious interrupts I guess.
> 
> BTW, ideally we would do the ldr conditionally rather than every time,
> I guess that's the idea with the old way of doing things.

  Well, actually the ldr (I assume you mean this one):

		ldrne	\irqnr, [\base, #INTCPS_SIR_IRQ_OFFSET]

  was being done everytime, since presumably, at least one of the
"pending" bits would be set otherwise how would we get to this
interrupt?  Which bring up a point - why bother even checking the
pending bits at all?   Just grab the irqnr, check for spurious and
exit.

  Rick

^ permalink raw reply	[flat|nested] 20+ messages in thread
* Re: ARM: OMAP3: Fix get_irqnr_and_base to clear spurious interrupt bits
@ 2008-10-28 16:10 Rick Bronson
  2008-10-28 16:31 ` Tony Lindgren
  2008-10-31 19:27 ` Tony Lindgren
  0 siblings, 2 replies; 20+ messages in thread
From: Rick Bronson @ 2008-10-28 16:10 UTC (permalink / raw)
  To: linux-omap

Tony,

  The last patch I posted didn't work quite right.  It seems we do
actually come into this macro with none of the pending bits set.
Presumably, because the interrupt hasn't been ack'd yet.  Anyway, I've
tested this patch and I think it's golden.  It ack's spurious
interrupts and lets the user know that one has occured by setting irq
to NR_IRQS then arch/arm/kernel/irq.c will use bad_irq_desc when it
processes the interrupt.  This message get's printed upon spurious
interrupt:

->handle_irq():  c0073448, handle_bad_irq+0x0/0x228                             
->chip(): 00000000, 0x0                                                         
->action(): 00000000                                                            

  The only bad thing is that it doesn't notify the user WHICH spurious
interrupt happened.  Any ideas on solving that?

  Rick

--- linux-omap-2.6/arch/arm/plat-omap/include/mach/entry-macro.S.git	2008-10-22 20:01:33.000000000 -0700
+++ linux-omap-2.6/arch/arm/plat-omap/include/mach/entry-macro.S	2008-10-27 08:41:08.000000000 -0700
@@ -66,7 +66,11 @@
 #endif
 
 #define INTCPS_SIR_IRQ_OFFSET	0x0040		/* Active interrupt offset */
-#define	ACTIVEIRQ_MASK		0x7f		/* Active interrupt bits */
+#define INTCPS_CONTROL		0x0048		/* new interrupt agreement bits */
+#define INTCPS_PENDING_IRQ_1	0x0098		/* IRQ pending reg 1 */
+#define INTCPS_PENDING_IRQ_2	0x00b8		/* IRQ pending reg 2 */
+#define INTCPS_PENDING_IRQ_3	0x00d8		/* IRQ pending reg 3 */
+#define INTCPS_CONTROL_NEWIRQAGR 0x0001		/* Reset IRQ output and enable new IRQ generation */
 
 		.macro	disable_fiq
 		.endm
@@ -79,18 +83,19 @@
 
 		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
 		ldr	\base, =OMAP2_VA_IC_BASE
-		ldr	\irqnr, [\base, #0x98] /* IRQ pending reg 1 */
-		cmp	\irqnr, #0x0
-		bne	2222f
-		ldr	\irqnr, [\base, #0xb8] /* IRQ pending reg 2 */
-		cmp	\irqnr, #0x0
-		bne	2222f
-		ldr	\irqnr, [\base, #0xd8] /* IRQ pending reg 3 */
-		cmp	\irqnr, #0x0
+		ldr	\irqstat, [\base, #INTCPS_PENDING_IRQ_1] /* IRQ pending reg 1 */
+		ldr	\tmp, [\base, #INTCPS_PENDING_IRQ_2] /* IRQ pending reg 2 */
+		orr	\irqstat, \irqstat, \tmp  /* or them all together */
+		ldr	\tmp, [\base, #INTCPS_PENDING_IRQ_3] /* IRQ pending reg 3 */
+		orrs	\irqstat, \irqstat, \tmp  /* set condition code Z if interrupt */
+		beq	2222f  /* if there are no interrupt bits set, leave with Z=1 */
+		ldr	\irqnr, [\base, #INTCPS_SIR_IRQ_OFFSET]
+		adds	\tmp, \irqnr, #1 /* change from zero based to 1 based so we clear Z */
+		bpl	2222f  /* if no spurious interrupt */
+		mov	\tmp, #INTCPS_CONTROL_NEWIRQAGR /* Ack the spurious irq	*/
+		str	\tmp, [\base, #INTCPS_CONTROL]
+		movw	\irqnr, #NR_IRQS /* set to NR_IRQS so that bad_irq_desc() get's called */
 2222:
-		ldrne	\irqnr, [\base, #INTCPS_SIR_IRQ_OFFSET]
-		and	\irqnr, \irqnr, #ACTIVEIRQ_MASK /* Clear spurious bits */
-
 		.endm
 
 		.macro	irq_prio_table

^ permalink raw reply	[flat|nested] 20+ messages in thread
* Re: ARM: OMAP3: Fix get_irqnr_and_base to clear spurious interrupt bits
@ 2008-10-24  4:14 Rick Bronson
  0 siblings, 0 replies; 20+ messages in thread
From: Rick Bronson @ 2008-10-24  4:14 UTC (permalink / raw)
  To: linux-omap

Tony,

  How does this look?

  If we set irq to NR_IRQS then arch/arm/kernel/irq.c will use
bad_irq_desc when it processes the interrupt.  NOTE: I haven't tested
this yet.

  Rick


--- linux-omap-2.6/arch/arm/plat-omap/include/mach/entry-macro.S.git	2008-10-22 20:01:33.000000000 -0700
+++ linux-omap-2.6/arch/arm/plat-omap/include/mach/entry-macro.S	2008-10-23 21:12:29.000000000 -0700
@@ -66,7 +66,8 @@
 #endif
 
 #define INTCPS_SIR_IRQ_OFFSET	0x0040		/* Active interrupt offset */
-#define	ACTIVEIRQ_MASK		0x7f		/* Active interrupt bits */
+#define INTCPS_CONTROL		0x0048		/* new interrupt agreement bits */
+#define INTCPS_CONTROL_NEWIRQAGR 0x0001		/* Reset IRQ output and enable new IRQ generation */
 
 		.macro	disable_fiq
 		.endm
@@ -79,18 +80,13 @@
 
 		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
 		ldr	\base, =OMAP2_VA_IC_BASE
-		ldr	\irqnr, [\base, #0x98] /* IRQ pending reg 1 */
-		cmp	\irqnr, #0x0
-		bne	2222f
-		ldr	\irqnr, [\base, #0xb8] /* IRQ pending reg 2 */
-		cmp	\irqnr, #0x0
-		bne	2222f
-		ldr	\irqnr, [\base, #0xd8] /* IRQ pending reg 3 */
-		cmp	\irqnr, #0x0
+		ldr	\irqnr, [\base, #INTCPS_SIR_IRQ_OFFSET]  /* NOTE: range is 0-0x5f and 0ffffff80 to 0xffffffdf */
+		adds	\tmp, \irqnr, #1 /* change from zero based to 1 based so we clear Z */
+		bpl	2222f  /* if no spurious interrupt */
+		mov	\tmp, #INTCPS_CONTROL_NEWIRQAGR /* Ack the spurious irq */
+		str	\tmp, [\base, #INTCPS_CONTROL]
+		movw	\irqnr, #NR_IRQS /* set to NR_IRQS so that bad_irq_desc() get's called */
 2222:
-		ldrne	\irqnr, [\base, #INTCPS_SIR_IRQ_OFFSET]
-		and	\irqnr, \irqnr, #ACTIVEIRQ_MASK /* Clear spurious bits */
-
 		.endm
 
 		.macro	irq_prio_table

^ permalink raw reply	[flat|nested] 20+ messages in thread
* Re: ARM: OMAP3: Fix get_irqnr_and_base to clear spurious interrupt bits
@ 2008-10-23 17:54 Rick Bronson
  0 siblings, 0 replies; 20+ messages in thread
From: Rick Bronson @ 2008-10-23 17:54 UTC (permalink / raw)
  To: linux-omap

Tony,

  I checked out some other ARM spurious interrupt handling and it
seems that they ack the interrupt but left the macro with the Z bit
set which means that asm_do_IRQ() does not get called.  Seems to me we
should do the same, see the patch below.  Although, ideally, we should
be logging these.  Is there a mechanism for doing this?

> Are these defines above still needed?

  Yes.

  BTW, I haven't checked this patch so don't do anything with it, just
comment on it ;-)

 Rick

--- linux-omap-2.6/arch/arm/plat-omap/include/mach/entry-macro.S.git	2008-10-22 20:01:33.000000000 -0700
+++ linux-omap-2.6/arch/arm/plat-omap/include/mach/entry-macro.S	2008-10-23 10:25:57.000000000 -0700
@@ -66,7 +66,11 @@
 #endif
 
 #define INTCPS_SIR_IRQ_OFFSET	0x0040		/* Active interrupt offset */
-#define	ACTIVEIRQ_MASK		0x7f		/* Active interrupt bits */
+#define INTCPS_CONTROL		0x0048		/* new interrupt agreement bits offset */
+#define INTCPS_CONTROL_NEWIRQAGR 0x0001		/* Reset IRQ output and enable new IRQ generation */
+#define INTCPS_PENDING_IRQ_1	0x0098		/* IRQ pending reg 1 */
+#define INTCPS_PENDING_IRQ_2	0x00b8		/* IRQ pending reg 2 */
+#define INTCPS_PENDING_IRQ_3	0x00d8		/* IRQ pending reg 3 */
 
 		.macro	disable_fiq
 		.endm
@@ -79,18 +83,18 @@
 
 		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
 		ldr	\base, =OMAP2_VA_IC_BASE
-		ldr	\irqnr, [\base, #0x98] /* IRQ pending reg 1 */
-		cmp	\irqnr, #0x0
-		bne	2222f
-		ldr	\irqnr, [\base, #0xb8] /* IRQ pending reg 2 */
-		cmp	\irqnr, #0x0
-		bne	2222f
-		ldr	\irqnr, [\base, #0xd8] /* IRQ pending reg 3 */
-		cmp	\irqnr, #0x0
-2222:
-		ldrne	\irqnr, [\base, #INTCPS_SIR_IRQ_OFFSET]
-		and	\irqnr, \irqnr, #ACTIVEIRQ_MASK /* Clear spurious bits */
-
+		ldr	\irqnr, [\base, #INTCPS_SIR_IRQ_OFFSET]
+		mvn	\tmp, \irqnr  /* flip MSBit */
+		bics	\tmp, #0x80000000  /* test MSBit */
+		moveq	\tmp, #INTCPS_CONTROL_NEWIRQAGR /* Ack the spurious irq */
+		streq	\tmp, [\base, #INTCPS_CONTROL]
+		beq	2223f  /* if we got a spurious interrupt, ignore it */
+		ldr	\irqstat, [\base, #INTCPS_PENDING_IRQ_1] /* IRQ pending reg 1 */
+		ldr	\tmp, [\base, #INTCPS_PENDING_IRQ_2] /* IRQ pending reg 2 */
+		orr	\irqstat, \irqstat, \tmp  /* or them all together */
+		ldr	\tmp, [\base, #INTCPS_PENDING_IRQ_3] /* IRQ pending reg 3 */
+		orrs	\irqstat, \irqstat, \tmp  /* clear condition code Z if interrupt */
+2223:
 		.endm
 
 		.macro	irq_prio_table

^ permalink raw reply	[flat|nested] 20+ messages in thread
* Re: ARM: OMAP3: Fix get_irqnr_and_base to clear spurious interrupt bits
@ 2008-10-23  3:29 Rick Bronson
  2008-10-23 15:43 ` Tony Lindgren
  0 siblings, 1 reply; 20+ messages in thread
From: Rick Bronson @ 2008-10-23  3:29 UTC (permalink / raw)
  To: linux-omap

Tony,

  Here is the patch against the latest git.  I'm a little concerned
about masking the interrupt number so that the spurious bit are
ignored.  Do you really want to turn a spurious interrupt into a
normal (good) interrupt?

> Also, AFAIK we don't have infinitely repeating irqs any longer, it's
> just an occasional single spurious interrupt.

  That's correct.  And those disappeared when I applied the S-O patch.
Without the S-O patch I was seeing one spurious interrupt in about 15
reboots, after the patch I got zero in 350 reboots.

  Rick

--- linux-omap-2.6/arch/arm/plat-omap/include/mach/entry-macro.S.git	2008-10-22 20:01:33.000000000 -0700
+++ linux-omap-2.6/arch/arm/plat-omap/include/mach/entry-macro.S	2008-10-22 20:11:26.000000000 -0700
@@ -67,6 +67,10 @@
 
 #define INTCPS_SIR_IRQ_OFFSET	0x0040		/* Active interrupt offset */
 #define	ACTIVEIRQ_MASK		0x7f		/* Active interrupt bits */
+#define INTCPS_CONTROL		0x0048		/* new interrupt agreement bits */
+#define INTCPS_PENDING_IRQ_1	0x0098		/* IRQ pending reg 1 */
+#define INTCPS_PENDING_IRQ_2	0x00b8		/* IRQ pending reg 2 */
+#define INTCPS_PENDING_IRQ_3	0x00d8		/* IRQ pending reg 3 */
 
 		.macro	disable_fiq
 		.endm
@@ -79,18 +83,20 @@
 
 		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
 		ldr	\base, =OMAP2_VA_IC_BASE
-		ldr	\irqnr, [\base, #0x98] /* IRQ pending reg 1 */
-		cmp	\irqnr, #0x0
-		bne	2222f
-		ldr	\irqnr, [\base, #0xb8] /* IRQ pending reg 2 */
-		cmp	\irqnr, #0x0
-		bne	2222f
-		ldr	\irqnr, [\base, #0xd8] /* IRQ pending reg 3 */
-		cmp	\irqnr, #0x0
-2222:
-		ldrne	\irqnr, [\base, #INTCPS_SIR_IRQ_OFFSET]
+		ldr	\irqnr, [\base, #INTCPS_SIR_IRQ_OFFSET]
+		cmp	\irqnr, #0  /* check for negative */
+		movmi	\tmp, #0x1 /* Ack the spurious irq, this lets it
+					* generate a bad irq error message,
+					* but prevents infinitely repeating
+					* irq.
+					*/
+		strmi	\tmp, [\base, #INTCPS_CONTROL]
 		and	\irqnr, \irqnr, #ACTIVEIRQ_MASK /* Clear spurious bits */
-

^ permalink raw reply	[flat|nested] 20+ messages in thread
* Re: ARM: OMAP3: Fix get_irqnr_and_base to clear spurious interrupt bits
@ 2008-10-22 17:48 Rick Bronson
  2008-10-22 18:30 ` Tony Lindgren
  0 siblings, 1 reply; 20+ messages in thread
From: Rick Bronson @ 2008-10-22 17:48 UTC (permalink / raw)
  To: linux-omap


  Sorry if I'm late in the game for changes to entry-macro.S but I
worked on this code a bit ago and have been testing it.  What I have,
I think, is a little more straight forward.  Note that it doesn't have
the added mask for the spurious bits, but it does check for
spurious interrupts and handles them.

  Rick



--- linux-omap-2.6/arch/arm/plat-omap/include/mach/entry-macro.S.~1~	2008-10-16 13:33:31.000000000 -0700
+++ linux-omap-2.6/arch/arm/plat-omap/include/mach/entry-macro.S	2008-10-17 11:38:18.000000000 -0700
@@ -65,7 +65,11 @@
 #include <mach/omap34xx.h>
 #endif
 
-#define INTCPS_SIR_IRQ_OFFSET	0x0040		/* Active interrupt number */
+#define INTCPS_SIR_IRQ_OFFSET	0x0040	/* Active interrupt number */
+#define INTCPS_CONTROL		0x0048	/* new interrupt agreement bits */
+#define INTCPS_PENDING_IRQ_1	0x0098	/* IRQ pending reg 1 */
+#define INTCPS_PENDING_IRQ_2	0x00b8	/* IRQ pending reg 2 */
+#define INTCPS_PENDING_IRQ_3	0x00d8	/* IRQ pending reg 3 */
 
 		.macro	disable_fiq
 		.endm
@@ -78,17 +82,19 @@
 
 		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
 		ldr	\base, =OMAP2_VA_IC_BASE
-		ldr	\irqnr, [\base, #0x98] /* IRQ pending reg 1 */
-		cmp	\irqnr, #0x0
-		bne	2222f
-		ldr	\irqnr, [\base, #0xb8] /* IRQ pending reg 2 */
-		cmp	\irqnr, #0x0
-		bne	2222f
-		ldr	\irqnr, [\base, #0xd8] /* IRQ pending reg 3 */
-		cmp	\irqnr, #0x0
-2222:
-		ldrne	\irqnr, [\base, #INTCPS_SIR_IRQ_OFFSET]
-
+		ldr	\irqnr, [\base, #INTCPS_SIR_IRQ_OFFSET]
+		cmp	\irqnr, #0  /* check for negative */
+		movmi	\tmp, #0x1 /* Ack the spurious irq, this lets it
+					* generate a bad irq error message,
+					* but prevents infinitely repeating
+					* irq.
+					*/
+		strmi	\tmp, [\base, #INTCPS_CONTROL]
+		ldr	\irqstat, [\base, #INTCPS_PENDING_IRQ_1] /* IRQ pending reg 1 */
+		ldr	\tmp, [\base, #INTCPS_PENDING_IRQ_2] /* IRQ pending reg 2 */
+		orr	\irqstat, \irqstat, \tmp  /* or them all together */
+		ldr	\tmp, [\base, #INTCPS_PENDING_IRQ_3] /* IRQ pending reg 3 */
+		orrs	\irqstat, \irqstat, \tmp  /* set condition code Z if interrupt */
 		.endm
 
 		.macro	irq_prio_table

^ permalink raw reply	[flat|nested] 20+ messages in thread
* ARM: OMAP3: Fix get_irqnr_and_base to clear spurious interrupt bits
@ 2008-10-21  4:58 Tony Lindgren
  2008-10-21 20:09 ` Felipe Contreras
  0 siblings, 1 reply; 20+ messages in thread
From: Tony Lindgren @ 2008-10-21  4:58 UTC (permalink / raw)
  To: linux-omap
  Cc: Nathan Monson, lauri.leukkunen, Paul Walmsley, Richard Woodruff,
	Rick Bronson

[-- Attachment #1: Type: text/plain, Size: 337 bytes --]

Hi all,

Here's a bug fix for the irq -33 issue. So far it looks like the irq
spurious bits just tell that the irq sorting is invalid.

This patch applies after undoing Lauri's patch
5dc857b34441d5c0989b68bf3a488f89983b2645.

Looks like there are still occasional spurious GPT12 interrupts, so
I'm now looking into that.

Regards,

Tony

[-- Attachment #2: 0003-ARM-OMAP3-Fix-get_irqnr_and_base-to-clear-spurious-v2.patch --]
[-- Type: text/x-diff, Size: 1630 bytes --]

commit 3e4291d575f7d694ae1d974a17b4e077b7b721de
Author: Tony Lindgren <tony@atomide.com>
Date:   Mon Oct 20 14:04:52 2008 -0700

    ARM: OMAP3: Fix get_irqnr_and_base to clear spurious interrupt bits
    
    On omap24xx, INTCPS_SIR_IRQ_OFFSET bits [6:0] contains the current
    active interrupt number.
    
    However, on 34xx INTCPS_SIR_IRQ_OFFSET bits [31:7] also contains the
    SPURIOUSIRQFLAG, which gets set if the interrupt sorting information
    is invalid.
    
    If the SPURIOUSIRQFLAG bits are not ignored, the interrupt code will
    occasionally produce a bunch of confusing errors:
    
    irq -33, desc: c02ddcc8, depth: 0, count: 0, unhandled: 0
    ->handle_irq():  c006f23c, handle_bad_irq+0x0/0x22c
    ->chip(): 00000000, 0x0
    ->action(): 00000000
    
    Fix this by masking out only the ACTIVEIRQ bits. Also fix a
    confusing comment.
    
    Signed-off-by: Tony Lindgren <tony@atomide.com>

diff --git a/arch/arm/plat-omap/include/mach/entry-macro.S b/arch/arm/plat-omap/include/mach/entry-macro.S
index a8fca9d..47aa62c 100644
--- a/arch/arm/plat-omap/include/mach/entry-macro.S
+++ b/arch/arm/plat-omap/include/mach/entry-macro.S
@@ -65,7 +65,8 @@
 #include <mach/omap34xx.h>
 #endif
 
-#define INTCPS_SIR_IRQ_OFFSET	0x0040		/* Active interrupt number */
+#define INTCPS_SIR_IRQ_OFFSET	0x0040		/* Active interrupt offset */
+#define	ACTIVEIRQ_MASK		0x7f		/* Active interrupt bits */
 
 		.macro	disable_fiq
 		.endm
@@ -88,6 +89,7 @@
 		cmp	\irqnr, #0x0
 2222:
 		ldrne	\irqnr, [\base, #INTCPS_SIR_IRQ_OFFSET]
+		and	\irqnr, \irqnr, #ACTIVEIRQ_MASK /* Clear spurious bits */
 
 		.endm
 

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

end of thread, other threads:[~2008-10-31 19:27 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-10-23 18:13 ARM: OMAP3: Fix get_irqnr_and_base to clear spurious interrupt bits Rick Bronson
2008-10-23 18:21 ` Tony Lindgren
  -- strict thread matches above, loose matches on Subject: below --
2008-10-28 16:10 Rick Bronson
2008-10-28 16:31 ` Tony Lindgren
2008-10-31 19:27 ` Tony Lindgren
2008-10-24  4:14 Rick Bronson
2008-10-23 17:54 Rick Bronson
2008-10-23  3:29 Rick Bronson
2008-10-23 15:43 ` Tony Lindgren
2008-10-22 17:48 Rick Bronson
2008-10-22 18:30 ` Tony Lindgren
2008-10-21  4:58 Tony Lindgren
2008-10-21 20:09 ` Felipe Contreras
2008-10-21 20:37   ` Tony Lindgren
2008-10-21 21:34     ` Felipe Contreras
2008-10-21 22:02       ` Tony Lindgren
2008-10-21 23:25         ` Tony Lindgren
2008-10-22 14:46         ` Felipe Contreras
2008-10-22 21:30           ` Nathan Monson
2008-10-22 21:40             ` Felipe Contreras

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).