aboutsummaryrefslogtreecommitdiffstats
path: root/arch/m68knommu/platform/coldfire
diff options
context:
space:
mode:
authorGreg Ungerer <gerg@uclinux.org>2009-05-21 23:33:35 -0400
committerGreg Ungerer <gerg@uclinux.org>2009-09-15 19:43:52 -0400
commit39f0fb6a3448cfc316e0d5295ed1b121db50037e (patch)
tree657db8073835e8d499708a898a36f1d3a1e39a32 /arch/m68knommu/platform/coldfire
parentf6a66276f5fdc018d2a9378c71de3bae13c588d7 (diff)
m68knommu: map ColdFire interrupts to correct masking bits
The older simple ColdFire interrupt controller has no one-to-one mapping of interrupt numbers to bits in the interrupt mask register. Create a mapping array that each ColdFire CPU type can populate with its available interrupts and the bits that each use in the interrupt mask register. Signed-off-by: Greg Ungerer <gerg@uclinux.org>
Diffstat (limited to 'arch/m68knommu/platform/coldfire')
-rw-r--r--arch/m68knommu/platform/coldfire/intc.c44
1 files changed, 27 insertions, 17 deletions
diff --git a/arch/m68knommu/platform/coldfire/intc.c b/arch/m68knommu/platform/coldfire/intc.c
index 14db26bf6e2f..a4560c86db71 100644
--- a/arch/m68knommu/platform/coldfire/intc.c
+++ b/arch/m68knommu/platform/coldfire/intc.c
@@ -19,9 +19,17 @@
19#include <asm/mcfsim.h> 19#include <asm/mcfsim.h>
20 20
21/* 21/*
22 * Define the vector numbers for the basic 7 interrupt sources. 22 * The mapping of irq number to a mask register bit is not one-to-one.
23 * These are often referred to as the "external" interrupts in 23 * The irq numbers are either based on "level" of interrupt or fixed
24 * the ColdFire documentation (for the early ColdFire cores at least). 24 * for an autovector-able interrupt. So we keep a local data structure
25 * that maps from irq to mask register. Not all interrupts will have
26 * an IMR bit.
27 */
28unsigned char mcf_irq2imr[NR_IRQS];
29
30/*
31 * Define the miniumun and maximum external interrupt numbers.
32 * This is also used as the "level" interrupt numbers.
25 */ 33 */
26#define EIRQ1 25 34#define EIRQ1 25
27#define EIRQ7 31 35#define EIRQ7 31
@@ -36,22 +44,22 @@
36 44
37void mcf_setimr(int index) 45void mcf_setimr(int index)
38{ 46{
39 u16 imr; 47 u16 imr;
40 imr = __raw_readw(MCF_MBAR + MCFSIM_IMR); 48 imr = __raw_readw(MCF_MBAR + MCFSIM_IMR);
41 __raw_writew(imr | (0x1 << index), MCF_MBAR + MCFSIM_IMR); 49 __raw_writew(imr | (0x1 << index), MCF_MBAR + MCFSIM_IMR);
42} 50}
43 51
44void mcf_clrimr(int index) 52void mcf_clrimr(int index)
45{ 53{
46 u16 imr; 54 u16 imr;
47 imr = __raw_readw(MCF_MBAR + MCFSIM_IMR); 55 imr = __raw_readw(MCF_MBAR + MCFSIM_IMR);
48 __raw_writew(imr & ~(0x1 << index), MCF_MBAR + MCFSIM_IMR); 56 __raw_writew(imr & ~(0x1 << index), MCF_MBAR + MCFSIM_IMR);
49} 57}
50 58
51void mcf_maskimr(unsigned int mask) 59void mcf_maskimr(unsigned int mask)
52{ 60{
53 u16 imr; 61 u16 imr;
54 imr = __raw_readw(MCF_MBAR + MCFSIM_IMR); 62 imr = __raw_readw(MCF_MBAR + MCFSIM_IMR);
55 imr |= mask; 63 imr |= mask;
56 __raw_writew(imr, MCF_MBAR + MCFSIM_IMR); 64 __raw_writew(imr, MCF_MBAR + MCFSIM_IMR);
57} 65}
@@ -60,22 +68,22 @@ void mcf_maskimr(unsigned int mask)
60 68
61void mcf_setimr(int index) 69void mcf_setimr(int index)
62{ 70{
63 u32 imr; 71 u32 imr;
64 imr = __raw_readl(MCF_MBAR + MCFSIM_IMR); 72 imr = __raw_readl(MCF_MBAR + MCFSIM_IMR);
65 __raw_writel(imr | (0x1 << index), MCF_MBAR + MCFSIM_IMR); 73 __raw_writel(imr | (0x1 << index), MCF_MBAR + MCFSIM_IMR);
66} 74}
67 75
68void mcf_clrimr(int index) 76void mcf_clrimr(int index)
69{ 77{
70 u32 imr; 78 u32 imr;
71 imr = __raw_readl(MCF_MBAR + MCFSIM_IMR); 79 imr = __raw_readl(MCF_MBAR + MCFSIM_IMR);
72 __raw_writel(imr & ~(0x1 << index), MCF_MBAR + MCFSIM_IMR); 80 __raw_writel(imr & ~(0x1 << index), MCF_MBAR + MCFSIM_IMR);
73} 81}
74 82
75void mcf_maskimr(unsigned int mask) 83void mcf_maskimr(unsigned int mask)
76{ 84{
77 u32 imr; 85 u32 imr;
78 imr = __raw_readl(MCF_MBAR + MCFSIM_IMR); 86 imr = __raw_readl(MCF_MBAR + MCFSIM_IMR);
79 imr |= mask; 87 imr |= mask;
80 __raw_writel(imr, MCF_MBAR + MCFSIM_IMR); 88 __raw_writel(imr, MCF_MBAR + MCFSIM_IMR);
81} 89}
@@ -93,24 +101,26 @@ void mcf_maskimr(unsigned int mask)
93 */ 101 */
94void mcf_autovector(int irq) 102void mcf_autovector(int irq)
95{ 103{
104#ifdef MCFSIM_AVR
96 if ((irq >= EIRQ1) && (irq <= EIRQ7)) { 105 if ((irq >= EIRQ1) && (irq <= EIRQ7)) {
97 u8 avec; 106 u8 avec;
98 avec = __raw_readb(MCF_MBAR + MCFSIM_AVR); 107 avec = __raw_readb(MCF_MBAR + MCFSIM_AVR);
99 avec |= (0x1 << (irq - EIRQ1 + 1)); 108 avec |= (0x1 << (irq - EIRQ1 + 1));
100 __raw_writeb(avec, MCF_MBAR + MCFSIM_AVR); 109 __raw_writeb(avec, MCF_MBAR + MCFSIM_AVR);
101 } 110 }
111#endif
102} 112}
103 113
104static void intc_irq_mask(unsigned int irq) 114static void intc_irq_mask(unsigned int irq)
105{ 115{
106 if ((irq >= EIRQ1) && (irq <= EIRQ7)) 116 if (mcf_irq2imr[irq])
107 mcf_setimr(irq - EIRQ1 + 1); 117 mcf_setimr(mcf_irq2imr[irq]);
108} 118}
109 119
110static void intc_irq_unmask(unsigned int irq) 120static void intc_irq_unmask(unsigned int irq)
111{ 121{
112 if ((irq >= EIRQ1) && (irq <= EIRQ7)) 122 if (mcf_irq2imr[irq])
113 mcf_clrimr(irq - EIRQ1 + 1); 123 mcf_clrimr(mcf_irq2imr[irq]);
114} 124}
115 125
116static int intc_irq_set_type(unsigned int irq, unsigned int type) 126static int intc_irq_set_type(unsigned int irq, unsigned int type)