From baf4326e49801526e4516e4de7f37b5e51468c49 Mon Sep 17 00:00:00 2001
From: Paul Mundt <lethal@linux-sh.org>
Date: Thu, 12 Oct 2006 12:03:04 +0900
Subject: sh: interrupt exception handling rework

Kill off interrupt_table for all of the CPU subtypes, we now
default in to stepping in to do_IRQ() for _all_ IRQ exceptions
and counting the spurious ones, rather than simply flipping on
the ones we cared about. This and enabling the IRQ by default
automatically has already uncovered a couple of bugs and IRQs
that weren't being caught, as well as some that are being
generated far too often (SCI Tx Data Empty, for example).

The general rationale is to use a marker for interrupt exceptions,
test for it in the handle_exception() path, and skip out to
do_IRQ() if it's found. Everything else follows the same behaviour
of finding the cached EXPEVT value in r2/r2_bank, we just rip out
the INTEVT read from entry.S entirely (except for in the kGDB NMI
case, which is another matter).

Note that while this changes the do_IRQ() semantics regarding r4
handling, they were fundamentally broken anyways (relying entirely
on r2_bank for the cached code). With this, we do the INTEVT read
from do_IRQ() itself (in the CONFIG_CPU_HAS_INTEVT case), or fall
back on r4 for the muxed IRQ number, which should also be closer
to what SH-2 and SH-2A want anyways.

Signed-off-by: Paul Mundt <lethal@linux-sh.org>
---
 arch/sh/kernel/cpu/sh3/ex.S | 195 -----------------
 arch/sh/kernel/cpu/sh4/ex.S | 500 --------------------------------------------
 arch/sh/kernel/entry.S      |  43 +++-
 arch/sh/kernel/irq.c        |  23 +-
 4 files changed, 40 insertions(+), 721 deletions(-)

diff --git a/arch/sh/kernel/cpu/sh3/ex.S b/arch/sh/kernel/cpu/sh3/ex.S
index 44daf44833..6be46f0686 100644
--- a/arch/sh/kernel/cpu/sh3/ex.S
+++ b/arch/sh/kernel/cpu/sh3/ex.S
@@ -49,198 +49,3 @@ ENTRY(nmi_slot)
 #endif
 ENTRY(user_break_point_trap)
 	.long	break_point_trap	/* 1E0 */
-ENTRY(interrupt_table)
-	! external hardware
-	.long	do_IRQ	! 0000		/* 200 */
-	.long	do_IRQ	! 0001
-	.long	do_IRQ	! 0010
-	.long	do_IRQ	! 0011
-	.long	do_IRQ	! 0100
-	.long	do_IRQ	! 0101
-	.long	do_IRQ	! 0110
-	.long	do_IRQ	! 0111
-	.long	do_IRQ	! 1000		/* 300 */
-	.long	do_IRQ	! 1001
-	.long	do_IRQ	! 1010
-	.long	do_IRQ	! 1011
-	.long	do_IRQ	! 1100
-	.long	do_IRQ	! 1101
-	.long	do_IRQ	! 1110
-	.long	exception_error		
-	! Internal hardware
-	.long	do_IRQ	! TMU0 tuni0	/* 400 */
-	.long	do_IRQ	! TMU1 tuni1
-	.long	do_IRQ	! TMU2 tuni2
-	.long	do_IRQ	!      ticpi2
-	.long	do_IRQ	! RTC  ati
-	.long	do_IRQ	!      pri
-	.long	do_IRQ	!      cui
-	.long	do_IRQ	! SCI  eri
-	.long	do_IRQ	!      rxi	/* 500 */
-	.long	do_IRQ	!      txi
-	.long	do_IRQ	!      tei
-	.long	do_IRQ	! WDT  iti	/* 560 */
-	.long	do_IRQ	! REF  rcmi
-	.long	do_IRQ	!      rovi
-	.long	do_IRQ			
-	.long	do_IRQ			/* 5E0 */
-#if  defined(CONFIG_CPU_SUBTYPE_SH7707) || \
-     defined(CONFIG_CPU_SUBTYPE_SH7709) || \
-     defined(CONFIG_CPU_SUBTYPE_SH7706) || \
-     defined(CONFIG_CPU_SUBTYPE_SH7300) || \
-     defined(CONFIG_CPU_SUBTYPE_SH7705) || \
-     defined(CONFIG_CPU_SUBTYPE_SH7710)
-	.long	do_IRQ	! 32 IRQ  irq0	/* 600 */
-	.long	do_IRQ	! 33      irq1
-	.long	do_IRQ	! 34      irq2
-	.long	do_IRQ	! 35      irq3
-	.long	do_IRQ	! 36      irq4
-	.long	do_IRQ	! 37      irq5
-	.long	do_IRQ	! 38
-	.long	do_IRQ	! 39
-	.long	do_IRQ	! 40 PINT pint0-7	/* 700 */
-	.long	do_IRQ	! 41      pint8-15
-	.long	do_IRQ	! 42
-	.long	do_IRQ	! 43
-	.long	do_IRQ	! 44
-	.long	do_IRQ	! 45	
-	.long	do_IRQ	! 46
-	.long	do_IRQ	! 47
-	.long	do_IRQ	! 48 DMAC dei0	/* 800 */
-	.long	do_IRQ	! 49      dei1
-	.long	do_IRQ	! 50      dei2
-	.long	do_IRQ	! 51      dei3
-	.long	do_IRQ	! 52 IrDA eri1
-	.long	do_IRQ	! 53      rxi1
-	.long	do_IRQ	! 54      bri1
-	.long	do_IRQ	! 55      txi1
-	.long	do_IRQ	! 56 SCIF eri2
-	.long	do_IRQ	! 57      rxi2
-	.long	do_IRQ	! 58      bri2
-	.long	do_IRQ	! 59      txi2
-	.long	do_IRQ	! 60 ADC  adi	/* 980 */
-#if defined(CONFIG_CPU_SUBTYPE_SH7705)
-	.long	exception_none	! 61	/* 9A0 */
-	.long	exception_none	! 62
-	.long	exception_none	! 63
-	.long	exception_none	! 64	/* A00 */
-	.long	do_IRQ	! 65 USB  usi0
-	.long	do_IRQ	! 66      usi1
-	.long	exception_none	! 67
-	.long	exception_none	! 68
-	.long	exception_none	! 69
-	.long	exception_none	! 70
-	.long	exception_none	! 71
-	.long	exception_none	! 72	/* B00 */
-	.long	exception_none	! 73
-	.long	exception_none	! 74
-	.long	exception_none	! 75
-	.long	exception_none	! 76
-	.long	exception_none	! 77
-	.long	exception_none	! 78
-	.long	exception_none	! 79
-	.long	do_IRQ	! 80 TPU0 tpi0	/* C00 */
-	.long	do_IRQ	! 81 TPU1 tpi1
-	.long	exception_none	! 82
-	.long	exception_none	! 83
-	.long	do_IRQ	! 84 TPU2 tpi2
-	.long	do_IRQ	! 85 TPU3 tpi3	/* CA0 */
-#endif
-#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7300)
-	.long   do_IRQ	! 61 LCDC lcdi	/* 9A0 */
-	.long   do_IRQ	! 62 PCC  pcc0i
-	.long   do_IRQ	! 63      pcc1i	/* 9E0 */
-#endif
-#if defined(CONFIG_CPU_SUBTYPE_SH7710)
-	.long   exception_none	! 61 	/* 9A0 */
-	.long   exception_none	! 62
-	.long   exception_none	! 63
-	.long   exception_none	! 64	/* A00 */
-	.long   exception_none	! 65
-	.long   exception_none	! 66
-	.long   exception_none	! 67
-	.long   exception_none	! 68
-	.long   exception_none	! 69
-	.long   exception_none	! 70
-	.long   exception_none	! 71
-	.long   exception_none	! 72	/* B00 */
-	.long   exception_none	! 73
-	.long   exception_none	! 74
-	.long   exception_none	! 75
-	.long   do_IRQ	! 76 DMAC2 dei4	/* B80 */
-	.long   do_IRQ	! 77 DMAC2 dei5
-	.long   exception_none	! 78
-	.long   do_IRQ	! 79 IPSEC ipseci /* BE0 */
-	.long   do_IRQ	! 80 EDMAC eint0 /* C00 */
-	.long   do_IRQ	! 81 EDMAC eint1
-	.long   do_IRQ	! 82 EDMAC eint2
-	.long   exception_none	! 83	/* C60 */
-	.long   exception_none	! 84
-	.long   exception_none	! 85
-	.long   exception_none	! 86
-	.long   exception_none	! 87
-	.long   exception_none	! 88	/* D00 */
-	.long   exception_none	! 89
-	.long   exception_none	! 90
-	.long   exception_none	! 91
-	.long   exception_none	! 92
-	.long   exception_none	! 93
-	.long   exception_none	! 94
-	.long   exception_none	! 95
-	.long   do_IRQ	! 96 SIOF eri0	/* E00 */
-	.long   do_IRQ	! 97      txi0
-	.long   do_IRQ	! 98      rxi0
-	.long   do_IRQ	! 99      cci0
-	.long   do_IRQ	! 100     eri1	/* E80 */
-	.long   do_IRQ	! 101     txi1
-	.long   do_IRQ	! 102     rxi2
-	.long   do_IRQ	! 103     cci3
-#endif
-#if defined(CONFIG_CPU_SUBTYPE_SH7300)
-	.long   do_IRQ	! 64
-	.long   do_IRQ	! 65
-	.long   do_IRQ	! 66
-	.long   do_IRQ	! 67
-	.long   do_IRQ	! 68
-	.long   do_IRQ	! 69
-	.long   do_IRQ	! 70
-	.long   do_IRQ	! 71
-	.long   do_IRQ	! 72
-	.long   do_IRQ	! 73
-	.long   do_IRQ	! 74
-	.long   do_IRQ	! 75
-	.long   do_IRQ	! 76
-	.long   do_IRQ	! 77
-	.long   do_IRQ	! 78
-	.long   do_IRQ	! 79
-	.long   do_IRQ	! 80 SCIF0(SH7300)
-	.long   do_IRQ	! 81
-	.long   do_IRQ	! 82
-	.long   do_IRQ	! 83
-	.long   do_IRQ	! 84
-	.long   do_IRQ	! 85
-	.long   do_IRQ	! 86
-	.long   do_IRQ	! 87
-	.long   do_IRQ	! 88
-	.long   do_IRQ	! 89
-	.long   do_IRQ	! 90
-	.long   do_IRQ	! 91
-	.long   do_IRQ	! 92
-	.long   do_IRQ	! 93
-	.long   do_IRQ	! 94
-	.long   do_IRQ	! 95
-	.long   do_IRQ	! 96
-	.long   do_IRQ	! 97
-	.long   do_IRQ	! 98
-	.long   do_IRQ	! 99
-	.long   do_IRQ	! 100
-	.long   do_IRQ	! 101
-	.long   do_IRQ	! 102
-	.long   do_IRQ	! 103
-	.long   do_IRQ	! 104
-	.long   do_IRQ	! 105
-	.long   do_IRQ	! 106
-	.long   do_IRQ	! 107
-	.long   do_IRQ	! 108
-#endif
-#endif
diff --git a/arch/sh/kernel/cpu/sh4/ex.S b/arch/sh/kernel/cpu/sh4/ex.S
index 7146893a6c..3f4cd043e9 100644
--- a/arch/sh/kernel/cpu/sh4/ex.S
+++ b/arch/sh/kernel/cpu/sh4/ex.S
@@ -53,503 +53,3 @@ ENTRY(nmi_slot)
 #endif
 ENTRY(user_break_point_trap)
 	.long	break_point_trap	/* 1E0 */
-ENTRY(interrupt_table)
-	! external hardware
-	.long	do_IRQ	! 0000		/* 200 */
-	.long	do_IRQ	! 0001
-	.long	do_IRQ	! 0010
-	.long	do_IRQ	! 0011
-	.long	do_IRQ	! 0100
-	.long	do_IRQ	! 0101
-	.long	do_IRQ	! 0110
-	.long	do_IRQ	! 0111
-	.long	do_IRQ	! 1000		/* 300 */
-	.long	do_IRQ	! 1001
-	.long	do_IRQ	! 1010
-	.long	do_IRQ	! 1011
-	.long	do_IRQ	! 1100
-	.long	do_IRQ	! 1101
-	.long	do_IRQ	! 1110
-	.long	exception_error		
-	! Internal hardware
-#ifndef CONFIG_CPU_SUBTYPE_SH7780
-	.long	do_IRQ	! TMU0 tuni0	/* 400 */
-	.long	do_IRQ	! TMU1 tuni1
-	.long	do_IRQ	! TMU2 tuni2
-	.long	do_IRQ	!      ticpi2
-#if  defined(CONFIG_CPU_SUBTYPE_SH7760)
-	.long	exception_error
-	.long	exception_error
-	.long	exception_error
-	.long	exception_error
-	.long	exception_error			/* 500 */
-	.long	exception_error
-	.long	exception_error
-#else
-	.long	do_IRQ	! RTC  ati
-	.long	do_IRQ	!      pri
-	.long	do_IRQ	!      cui
-	.long	do_IRQ	! SCI  eri
-	.long	do_IRQ	!      rxi	/* 500 */
-	.long	do_IRQ	!      txi
-	.long	do_IRQ	!      tei
-#endif
-	.long	do_IRQ	! WDT  iti	/* 560 */
-	.long	do_IRQ	! REF  rcmi
-	.long	do_IRQ	!      rovi
-	.long	do_IRQ			
-	.long	do_IRQ			/* 5E0 */
-	.long	do_IRQ	! 32 Hitachi UDI	/* 600 */
-	.long	do_IRQ	! 33 GPIO
-	.long	do_IRQ	! 34 DMAC dmte0
-	.long	do_IRQ	! 35      dmte1
-	.long	do_IRQ	! 36      dmte2
-	.long	do_IRQ	! 37      dmte3
-	.long	do_IRQ	! 38      dmae
-	.long	exception_error			! 39	/* 6E0 */
-#if defined(CONFIG_CPU_SUBTYPE_SH7760)
-	.long	exception_error				/* 700 */
-	.long	exception_error
-	.long	exception_error
-	.long	exception_error				/* 760 */
-#else
-	.long	do_IRQ	! 40 SCIF eri		/* 700 */
-	.long	do_IRQ	! 41      rxi
-	.long	do_IRQ	! 42      bri
-	.long	do_IRQ	! 43      txi
-#endif
-#if CONFIG_NR_ONCHIP_DMA_CHANNELS == 8
-	.long	do_IRQ	! 44 DMAC dmte4		/* 780 */
-	.long	do_IRQ	! 45      dmte5
-	.long	do_IRQ	! 46      dmte6
-	.long	do_IRQ	! 47      dmte7		/* 7E0 */
-#elif defined(CONFIG_CPU_SUBTYPE_SH7343)
-	.long	do_IRQ	! 44 IIC1 ali		/* 780 */
-	.long	do_IRQ	! 45      tacki
-	.long	do_IRQ	! 46      waiti
-	.long	do_IRQ	! 47      dtei		/* 7E0 */
-	.long	do_IRQ	! 48 DMAC dei0		/* 800 */
-	.long	do_IRQ	! 49      dei1		/* 820 */
-#else
-	.long	exception_error			! 44	/* 780 */
-	.long	exception_error			! 45
-	.long	exception_error			! 46
-	.long	exception_error			! 47
-#endif
-#if defined(CONFIG_SH_FPU)
-	.long	do_fpu_state_restore	! 48	/* 800 */
-	.long	do_fpu_state_restore	! 49	/* 820 */
-#elif !defined(CONFIG_CPU_SUBTYPE_SH7343) && \
-      !defined(CONFIG_CPU_SUBTYPE_SH73180)
-	.long	exception_error
-	.long	exception_error
-#endif
-#if defined(CONFIG_CPU_SUBTYPE_SH7751)
-	.long	exception_error			/* 840 */
-	.long	exception_error
-	.long	exception_error
-	.long	exception_error
-	.long	exception_error
-	.long	exception_error
-	.long	exception_error			/* 900 */
-	.long	exception_error
-	.long	exception_error
-	.long	exception_error
-	.long	exception_error
-	.long	exception_error
-	.long	exception_error
-	.long	exception_error
-	.long	do_IRQ	! PCI serr	/* A00 */
-	.long	do_IRQ	!     dma3
-	.long	do_IRQ	!     dma2
-	.long	do_IRQ	!     dma1
-	.long	do_IRQ	!     dma0
-	.long	do_IRQ	!     pwon
-	.long	do_IRQ	!     pwdwn
-	.long	do_IRQ	!     err
-	.long	do_IRQ	! TMU3 tuni3	/* B00 */
-	.long	exception_error
-	.long	exception_error
-	.long	exception_error
-	.long	do_IRQ	! TMU4 tuni4	/* B80 */
-#elif defined(CONFIG_CPU_SUBTYPE_SH7760)
-	.long	do_IRQ	! IRQ	irq6	/* 840 */
-	.long	do_IRQ	!	irq7
-	.long	do_IRQ	! SCIF	eri0
-	.long	do_IRQ	!	rxi0
-	.long	do_IRQ	!	bri0
-	.long	do_IRQ	!	txi0
-	.long	do_IRQ	! HCAN2	cani0	/* 900 */
-	.long	do_IRQ	!	cani1
-	.long	do_IRQ	! SSI	ssii0
-	.long	do_IRQ	!	ssii1
-	.long	do_IRQ	! HAC	haci0
-	.long	do_IRQ	!	haci1
-	.long	do_IRQ	! IIC	iici0
-	.long	do_IRQ	!	iici1
-	.long	do_IRQ	! USB	usbi	/* A00 */
-	.long	do_IRQ	! LCDC	vint
-	.long	exception_error
-	.long	exception_error
-	.long	do_IRQ	! DMABRG dmabrgi0
-	.long	do_IRQ	!        dmabrgi1
-	.long	do_IRQ	!        dmabrgi2
-	.long	exception_error
-	.long	do_IRQ	! SCIF	eri1	/* B00 */
-	.long	do_IRQ	!	rxi1
-	.long	do_IRQ	!	bri1
-	.long	do_IRQ	!	txi1
-	.long	do_IRQ	!	eri2
-	.long	do_IRQ	!	rxi2
-	.long	do_IRQ	!	bri2
-	.long	do_IRQ  !	txi2
-	.long	do_IRQ	! SIM	simeri	/* C00 */
-	.long	do_IRQ	!	simrxi
-	.long	do_IRQ	!	simtxi
-	.long	do_IRQ	!	simtei
-	.long	do_IRQ	! HSPI	spii
-	.long	exception_error
-	.long	exception_error
-	.long	exception_error
-	.long	do_IRQ	! MMCIF	mmci0	/* D00 */
-	.long	do_IRQ	!	mmci1
-	.long	do_IRQ	!	mmci2
-	.long	do_IRQ	!	mmci3
-	.long	exception_error
-	.long	exception_error
-	.long	exception_error
-	.long	exception_error
-	.long	exception_error			/* E00 */
-	.long	exception_error
-	.long	exception_error
-	.long	exception_error
-	.long	do_IRQ	! MFI	mfii
-	.long	exception_error
-	.long	exception_error
-	.long	exception_error
-	.long	exception_error			/* F00 */
-	.long	exception_error
-	.long	exception_error
-	.long	exception_error
-	.long	do_IRQ	! ADC	adi
-	.long	do_IRQ	! CMT	cmti	/* FA0 */
-#elif defined(CONFIG_CPU_SUBTYPE_SH73180) || defined(CONFIG_CPU_SUBTYPE_SH7343)
-	.long	do_IRQ	!  50 0x840
-	.long	do_IRQ	!  51 0x860
-	.long	do_IRQ	!  52 0x880
-	.long	do_IRQ	!  53 0x8a0
-	.long	do_IRQ	!  54 0x8c0
-	.long	do_IRQ	!  55 0x8e0
-	.long	do_IRQ	!  56 0x900
-	.long	do_IRQ	!  57 0x920
-	.long	do_IRQ	!  58 0x940
-	.long	do_IRQ	!  59 0x960
-	.long	do_IRQ	!  60 0x980
-	.long	do_IRQ	!  61 0x9a0
-	.long	do_IRQ	!  62 0x9c0
-	.long	do_IRQ	!  63 0x9e0
-	.long	do_IRQ	!  64 0xa00
-	.long	do_IRQ	!  65 0xa20
-	.long	do_IRQ	!  66 0xa40
-	.long	do_IRQ	!  67 0xa60
-	.long	do_IRQ	!  68 0xa80
-	.long	do_IRQ	!  69 0xaa0
-	.long	do_IRQ	!  70 0xac0
-	.long	do_IRQ	!  71 0xae0
-	.long	do_IRQ	!  72 0xb00
-	.long	do_IRQ	!  73 0xb20
-	.long	do_IRQ	!  74 0xb40
-	.long	do_IRQ	!  75 0xb60
-	.long	do_IRQ	!  76 0xb80
-	.long	do_IRQ	!  77 0xba0
-	.long	do_IRQ	!  78 0xbc0
-	.long	do_IRQ	!  79 0xbe0
-	.long	do_IRQ	!  80 0xc00
-	.long	do_IRQ	!  81 0xc20
-	.long	do_IRQ	!  82 0xc40
-	.long	do_IRQ	!  83 0xc60
-	.long	do_IRQ	!  84 0xc80
-	.long	do_IRQ	!  85 0xca0
-	.long	do_IRQ	!  86 0xcc0
-	.long	do_IRQ	!  87 0xce0
-	.long	do_IRQ	!  88 0xd00
-	.long	do_IRQ	!  89 0xd20
-	.long	do_IRQ	!  90 0xd40
-	.long	do_IRQ	!  91 0xd60
-	.long	do_IRQ	!  92 0xd80
-	.long	do_IRQ	!  93 0xda0
-	.long	do_IRQ	!  94 0xdc0
-	.long	do_IRQ	!  95 0xde0
-	.long	do_IRQ	!  96 0xe00
-	.long	do_IRQ	!  97 0xe20
-	.long	do_IRQ	!  98 0xe40
-	.long	do_IRQ	!  99 0xe60
-	.long	do_IRQ	! 100 0xe80
-	.long	do_IRQ	! 101 0xea0
-	.long	do_IRQ	! 102 0xec0
-	.long	do_IRQ	! 103 0xee0
-	.long	do_IRQ	! 104 0xf00
-	.long	do_IRQ	! 105 0xf20
-	.long	do_IRQ	! 106 0xf40
-	.long	do_IRQ	! 107 0xf60
-	.long	do_IRQ	! 108 0xf80
-#elif defined(CONFIG_CPU_SUBTYPE_ST40STB1)
-	.long	exception_error			!  50 0x840
-	.long	exception_error			!  51 0x860
-	.long	exception_error			!  52 0x880
-	.long	exception_error			!  53 0x8a0
-	.long	exception_error			!  54 0x8c0
-	.long	exception_error			!  55 0x8e0
-	.long	exception_error			!  56 0x900
-	.long	exception_error			!  57 0x920
-	.long	exception_error			!  58 0x940
-	.long	exception_error			!  59 0x960
-	.long	exception_error			!  60 0x980
-	.long	exception_error			!  61 0x9a0
-	.long	exception_error			!  62 0x9c0
-	.long	exception_error			!  63 0x9e0
-	.long	do_IRQ	!  64 0xa00 PCI serr
-	.long	do_IRQ	!  65 0xa20     err
-	.long	do_IRQ	!  66 0xa40     ad
-	.long	do_IRQ	!  67 0xa60     pwr_dwn
-	.long	exception_error			!  68 0xa80
-	.long	exception_error			!  69 0xaa0
-	.long	exception_error			!  70 0xac0
-	.long	exception_error			!  71 0xae0
-	.long	do_IRQ	!  72 0xb00 DMA INT0
-	.long	do_IRQ	!  73 0xb20     INT1
-	.long	do_IRQ	!  74 0xb40     INT2
-	.long	do_IRQ	!  75 0xb60     INT3
-	.long	do_IRQ	!  76 0xb80     INT4
-	.long	exception_error			!  77 0xba0
-	.long	do_IRQ	!  78 0xbc0 DMA ERR
-	.long	exception_error			!  79 0xbe0
-	.long	do_IRQ	!  80 0xc00 PIO0
-	.long	do_IRQ	!  81 0xc20 PIO1
-	.long	do_IRQ	!  82 0xc40 PIO2
-	.long	exception_error			!  83 0xc60
-	.long	exception_error			!  84 0xc80
-	.long	exception_error			!  85 0xca0
-	.long	exception_error			!  86 0xcc0
-	.long	exception_error			!  87 0xce0
-	.long	exception_error			!  88 0xd00
-	.long	exception_error			!  89 0xd20
-	.long	exception_error			!  90 0xd40
-	.long	exception_error			!  91 0xd60
-	.long	exception_error			!  92 0xd80
-	.long	exception_error			!  93 0xda0
-	.long	exception_error			!  94 0xdc0
-	.long	exception_error			!  95 0xde0
-	.long	exception_error			!  96 0xe00
-	.long	exception_error			!  97 0xe20
-	.long	exception_error			!  98 0xe40
-	.long	exception_error			!  99 0xe60
-	.long	exception_error			! 100 0xe80
-	.long	exception_error			! 101 0xea0
-	.long	exception_error			! 102 0xec0
-	.long	exception_error			! 103 0xee0
-	.long	exception_error			! 104 0xf00
-	.long	exception_error			! 105 0xf20
-	.long	exception_error			! 106 0xf40
-	.long	exception_error			! 107 0xf60
-	.long	exception_error			! 108 0xf80
-	.long	exception_error			! 109 0xfa0
-	.long	exception_error			! 110 0xfc0
-	.long	exception_error			! 111 0xfe0
-	.long	do_IRQ	! 112 0x1000 Mailbox
-	.long	exception_error			! 113 0x1020
-	.long	exception_error			! 114 0x1040
-	.long	exception_error			! 115 0x1060
-	.long	exception_error			! 116 0x1080
-	.long	exception_error			! 117 0x10a0
-	.long	exception_error			! 118 0x10c0
-	.long	exception_error			! 119 0x10e0
-	.long	exception_error			! 120 0x1100
-	.long	exception_error			! 121 0x1120
-	.long	exception_error			! 122 0x1140
-	.long	exception_error			! 123 0x1160
-	.long	exception_error			! 124 0x1180
-	.long	exception_error			! 125 0x11a0
-	.long	exception_error			! 126 0x11c0
-	.long	exception_error			! 127 0x11e0
-	.long	exception_error			! 128 0x1200
-	.long	exception_error			! 129 0x1220
-	.long	exception_error			! 130 0x1240
-	.long	exception_error			! 131 0x1260
-	.long	exception_error			! 132 0x1280
-	.long	exception_error			! 133 0x12a0
-	.long	exception_error			! 134 0x12c0
-	.long	exception_error			! 135 0x12e0
-	.long	exception_error			! 136 0x1300
-	.long	exception_error			! 137 0x1320
-	.long	exception_error			! 138 0x1340
-	.long	exception_error			! 139 0x1360
-	.long	do_IRQ	! 140 0x1380 EMPI INV_ADDR
-	.long	exception_error			! 141 0x13a0
-	.long	exception_error			! 142 0x13c0
-	.long	exception_error			! 143 0x13e0
-#elif defined(CONFIG_CPU_SUBTYPE_SH7770)
-	.long	do_IRQ	!  50 0x840
-	.long	do_IRQ	!  51 0x860
-	.long	do_IRQ	!  52 0x880
-	.long	do_IRQ	!  53 0x8a0
-	.long	do_IRQ	!  54 0x8c0
-	.long	do_IRQ	!  55 0x8e0
-	.long	do_IRQ	!  56 0x900
-	.long	do_IRQ	!  57 0x920
-	.long	do_IRQ	!  58 0x940
-	.long	do_IRQ	!  59 0x960
-	.long	do_IRQ	!  60 0x980
-	.long	do_IRQ	!  61 0x9a0
-	.long	do_IRQ	!  62 0x9c0
-	.long	do_IRQ	!  63 0x9e0
-	.long	do_IRQ	!  64 0xa00
-	.long	do_IRQ	!  65 0xa20
-	.long	do_IRQ	!  66 0xa4d
-	.long	do_IRQ	!  67 0xa60
-	.long	do_IRQ	!  68 0xa80
-	.long	do_IRQ	!  69 0xaa0
-	.long	do_IRQ	!  70 0xac0
-	.long	do_IRQ	!  71 0xae0
-	.long	do_IRQ	!  72 0xb00
-	.long	do_IRQ	!  73 0xb20
-	.long	do_IRQ	!  74 0xb40
-	.long	do_IRQ	!  75 0xb60
-	.long	do_IRQ	!  76 0xb80
-	.long	do_IRQ	!  77 0xba0
-	.long	do_IRQ	!  78 0xbc0
-	.long	do_IRQ	!  79 0xbe0
-	.long	do_IRQ	!  80 0xc00
-	.long	do_IRQ	!  81 0xc20
-	.long	do_IRQ	!  82 0xc40
-	.long	do_IRQ	!  83 0xc60
-	.long	do_IRQ	!  84 0xc80
-	.long	do_IRQ	!  85 0xca0
-	.long	do_IRQ	!  86 0xcc0
-	.long	do_IRQ	!  87 0xce0
-	.long	do_IRQ	!  88 0xd00
-	.long	do_IRQ	!  89 0xd20
-	.long	do_IRQ	!  90 0xd40
-	.long	do_IRQ	!  91 0xd60
-	.long	do_IRQ	!  92 0xd80
-	.long	do_IRQ	!  93 0xda0
-	.long	do_IRQ	!  94 0xdc0
-	.long	do_IRQ	!  95 0xde0
-	.long	do_IRQ	!  96 0xe00
-	.long	do_IRQ	!  97 0xe20
-	.long	do_IRQ	!  98 0xe40
-	.long	do_IRQ	!  99 0xe60
-	.long	do_IRQ	! 100 0xe80
-	.long	do_IRQ	! 101 0xea0
-	.long	do_IRQ	! 102 0xec0
-	.long	do_IRQ	! 103 0xee0
-	.long	do_IRQ	! 104 0xf00
-	.long	do_IRQ	! 105 0xf20
-	.long	do_IRQ	! 106 0xf40
-	.long	do_IRQ	! 107 0xf60
-	.long	do_IRQ	! 108 0xf80
-#endif
-#else
-	.long	exception_error		/* 400 */
-	.long	exception_error
-	.long	exception_error
-	.long	exception_error
-	.long	do_IRQ	! RTC	ati
-	.long	do_IRQ	!	pri
-	.long	do_IRQ	!	cui
-	.long	exception_error
-	.long	exception_error		/* 500 */
-	.long	exception_error
-	.long	exception_error
-	.long	do_IRQ	! WDT	iti	/* 560 */
-	.long	do_IRQ	! TMU-ch0
-	.long	do_IRQ	! TMU-ch1
-	.long	do_IRQ	! TMU-ch2
-	.long	do_IRQ	! ticpi2	/* 5E0 */
-	.long	do_IRQ	! 32 Hitachi UDI	/* 600 */
-	.long	exception_error
-	.long	do_IRQ	! 34 DMAC dmte0
-	.long	do_IRQ	! 35	  dmte1
-	.long	do_IRQ	! 36	  dmte2
-	.long	do_IRQ	! 37	  dmte3
-	.long	do_IRQ	! 38	  dmae
-	.long	exception_error			! 39	/* 6E0 */
-	.long	do_IRQ	! 40 SCIF-ch0 eri		/* 700 */
-	.long	do_IRQ	! 41	      rxi
-	.long	do_IRQ	! 42	      bri
-	.long	do_IRQ	! 43	      txi
-	.long	do_IRQ	! 44 DMAC dmte4		/* 780 */
-	.long	do_IRQ	! 45	  dmte5
-	.long	do_IRQ	! 46	  dmte6
-	.long	do_IRQ	! 47	  dmte7		/* 7E0 */
-#if defined(CONFIG_SH_FPU)
-	.long	do_fpu_state_restore	! 48	/* 800 */
-	.long	do_fpu_state_restore	! 49	/* 820 */
-#else
-	.long	exception_error
-	.long	exception_error
-#endif
-	.long	exception_error			/* 840 */
-	.long	exception_error
-	.long	exception_error
-	.long	exception_error
-	.long	exception_error
-	.long	exception_error
-	.long	do_IRQ	! 56 CMT	/* 900 */
-	.long	exception_error
-	.long	exception_error
-	.long	exception_error
-	.long	do_IRQ	! 60 HAC
-	.long	exception_error
-	.long	exception_error
-	.long	exception_error
-	.long	do_IRQ	! PCI serr	/* A00 */
-	.long	do_IRQ	!     INTA
-	.long	do_IRQ	!     INTB
-	.long	do_IRQ	!     INTC
-	.long	do_IRQ	!     INTD
-	.long	do_IRQ	!     err
-	.long	do_IRQ	!     pwd3
-	.long	do_IRQ	!     pwd2
-	.long	do_IRQ	!     pwd1	/* B00 */
-	.long	do_IRQ	!     pwd0
-	.long	exception_error
-	.long	exception_error
-	.long	do_IRQ	! SCIF-ch1 eri	/* B80 */
-	.long	do_IRQ	!	   rxi
-	.long	do_IRQ	!	   bri
-	.long	do_IRQ	!	   txi
-	.long	do_IRQ	! SIOF		/* C00 */
-	.long	exception_error
-	.long	exception_error
-	.long	exception_error
-	.long	do_IRQ	! HSPI		/* C80 */
-	.long	exception_error
-	.long	exception_error
-	.long	exception_error
-	.long	do_IRQ	! MMCIF	fatat	/* D00 */
-	.long	do_IRQ	!	tran
-	.long	do_IRQ	!	err
-	.long	do_IRQ	!	frdy
-	.long	do_IRQ	! DMAC dmint8	/* D80 */
-	.long	do_IRQ	!      dmint9
-	.long	do_IRQ	!      dmint10
-	.long	do_IRQ	!      dmint11
-	.long	do_IRQ	! TMU-ch3	/* E00 */
-	.long	do_IRQ	! TMU-ch4
-	.long	do_IRQ	! TMU-ch5
-	.long	exception_error
-	.long	do_IRQ	! SSI
-	.long	exception_error
-	.long	exception_error
-	.long	exception_error
-	.long	do_IRQ	! FLCTL	flste	/* F00 */
-	.long	do_IRQ	!	fltend
-	.long	do_IRQ	!	fltrq0
-	.long	do_IRQ	!	fltrq1
-	.long	do_IRQ	! GPIO gpioi0	/* F80 */
-	.long	do_IRQ	!      gpioi1
-	.long	do_IRQ	!      gpioi2
-	.long	do_IRQ	!      gpioi3
-#endif
-
diff --git a/arch/sh/kernel/entry.S b/arch/sh/kernel/entry.S
index 97c571fbcd..39aaefb2d8 100644
--- a/arch/sh/kernel/entry.S
+++ b/arch/sh/kernel/entry.S
@@ -1,9 +1,8 @@
-/* $Id: entry.S,v 1.37 2004/06/11 13:02:46 doyu Exp $
- *
+/*
  *  linux/arch/sh/entry.S
  *
  *  Copyright (C) 1999, 2000, 2002  Niibe Yutaka
- *  Copyright (C) 2003  Paul Mundt
+ *  Copyright (C) 2003 - 2006  Paul Mundt
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
@@ -78,7 +77,6 @@ OFF_TRA	=  (16*4+6*4)
 #define k3	r3
 #define k4	r4
 
-#define k_ex_code	r2_bank	/* r2_bank1 */
 #define g_imask		r6	/* r6_bank1 */
 #define k_g_imask	r6_bank	/* r6_bank1 */
 #define current		r7	/* r7_bank1 */
@@ -691,7 +689,7 @@ interrupt:
 0:
 #endif /* defined(CONFIG_KGDB_NMI) */
 	bra	handle_exception
-	 mov.l	@k2, k2
+	 mov	#-1, k2		! interrupt exception marker
 
 	.align	2
 1:	.long	EXPEVT
@@ -717,8 +715,7 @@ ENTRY(handle_exception)
 	add	current, k1
 	mov	k1, r15		! change to kernel stack
 	!
-1:  	mov	#-1, k4
-	mov.l	2f, k1
+1:	mov.l	2f, k1
 	!
 #ifdef CONFIG_SH_DSP
 	mov.l	r2, @-r15		! Save r2, we need another reg
@@ -763,6 +760,8 @@ skip_save:
 #endif
 	! Save the user registers on the stack.
 	mov.l	k2, @-r15	! EXPEVT
+
+ 	mov	#-1, k4
 	mov.l	k4, @-r15	! set TRA (default: -1)
 	!
 	sts.l	macl, @-r15
@@ -797,8 +796,21 @@ skip_save:
 	mov.l	r2, @-r15
 	mov.l	r1, @-r15
 	mov.l	r0, @-r15
-	! Then, dispatch to the handler, according to the exception code.
-	stc	k_ex_code, r8
+
+	/*
+	 * This gets a bit tricky.. in the INTEVT case we don't want to use
+	 * the VBR offset as a destination in the jump call table, since all
+	 * of the destinations are the same. In this case, (interrupt) sets
+	 * a marker in r2 (now r2_bank since SR.RB changed), which we check
+	 * to determine the exception type. For all other exceptions, we
+	 * forcibly read EXPEVT from memory and fix up the jump address, in
+	 * the interrupt exception case we jump to do_IRQ() and defer the
+	 * INTEVT read until there. As a bonus, we can also clean up the SR.RB
+	 * checks that do_IRQ() was doing..
+	 */
+	stc	r2_bank, r8
+	cmp/pz	r8
+	bf	interrupt_exception
 	shlr2	r8
 	shlr	r8
 	mov.l	4f, r9
@@ -806,6 +818,8 @@ skip_save:
 	mov.l	@r9, r9
 	jmp	@r9
 	 nop
+	rts
+	 nop
 
 	.align	2
 1:	.long	0x00001000	! DSP=1
@@ -813,8 +827,17 @@ skip_save:
 3:	.long	0xcfffffff	! RB=0, BL=0
 4:	.long	exception_handling_table
 
+interrupt_exception:
+	mov.l	1f, r9
+	jmp	@r9
+	 nop
+	rts
+	 nop
+
+	.align 2
+1:	.long	do_IRQ
+
 	.align	2
 ENTRY(exception_none)
 	rts
 	 nop
-
diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c
index 3b93682bf1..acf2602569 100644
--- a/arch/sh/kernel/irq.c
+++ b/arch/sh/kernel/irq.c
@@ -11,6 +11,7 @@
 #include <linux/module.h>
 #include <linux/kernel_stat.h>
 #include <linux/seq_file.h>
+#include <linux/io.h>
 #include <asm/irq.h>
 #include <asm/processor.h>
 #include <asm/uaccess.h>
@@ -26,6 +27,7 @@ atomic_t irq_err_count;
  */
 void ack_bad_irq(unsigned int irq)
 {
+	atomic_inc(&irq_err_count);
 	printk("unexpected IRQ trap at vector %02x\n", irq);
 }
 
@@ -85,7 +87,7 @@ asmlinkage int do_IRQ(unsigned long r4, unsigned long r5,
 		      struct pt_regs regs)
 {
 	struct pt_regs *old_regs = set_irq_regs(&regs);
-	int irq = r4;
+	int irq;
 #ifdef CONFIG_4KSTACKS
 	union irq_ctx *curctx, *irqctx;
 #endif
@@ -109,20 +111,9 @@ asmlinkage int do_IRQ(unsigned long r4, unsigned long r5,
 #endif
 
 #ifdef CONFIG_CPU_HAS_INTEVT
-	__asm__ __volatile__ (
-#ifdef CONFIG_CPU_HAS_SR_RB
-		"stc	r2_bank, %0\n\t"
+	irq = (ctrl_inl(INTEVT) >> 5) - 16;
 #else
-		"mov.l	@%1, %0\n\t"
-#endif
-		"shlr2	%0\n\t"
-		"shlr2	%0\n\t"
-		"shlr	%0\n\t"
-		"add	#-16, %0\n\t"
-		: "=z" (irq), "=r" (r4)
-		: "1" (INTEVT)
-		: "memory"
-	);
+	irq = r4;
 #endif
 
 	irq = irq_demux(irq);
@@ -147,9 +138,9 @@ asmlinkage int do_IRQ(unsigned long r4, unsigned long r5,
 		__asm__ __volatile__ (
 			"mov	%0, r4		\n"
 			"mov	r15, r9		\n"
-			"jsr	@%2		\n"
+			"jsr	@%1		\n"
 			/* swith to the irq stack */
-			" mov	%3, r15		\n"
+			" mov	%2, r15		\n"
 			/* restore the stack (ring zero) */
 			"mov	r9, r15		\n"
 			: /* no outputs */
-- 
cgit v1.2.2