diff options
author | Greg Ungerer <gerg@uclinux.org> | 2009-05-21 23:33:35 -0400 |
---|---|---|
committer | Greg Ungerer <gerg@uclinux.org> | 2009-09-15 19:43:52 -0400 |
commit | 39f0fb6a3448cfc316e0d5295ed1b121db50037e (patch) | |
tree | 657db8073835e8d499708a898a36f1d3a1e39a32 /arch/m68knommu/platform/coldfire | |
parent | f6a66276f5fdc018d2a9378c71de3bae13c588d7 (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.c | 44 |
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 | */ | ||
28 | unsigned 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 | ||
37 | void mcf_setimr(int index) | 45 | void 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 | ||
44 | void mcf_clrimr(int index) | 52 | void 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 | ||
51 | void mcf_maskimr(unsigned int mask) | 59 | void 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 | ||
61 | void mcf_setimr(int index) | 69 | void 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 | ||
68 | void mcf_clrimr(int index) | 76 | void 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 | ||
75 | void mcf_maskimr(unsigned int mask) | 83 | void 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 | */ |
94 | void mcf_autovector(int irq) | 102 | void 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 | ||
104 | static void intc_irq_mask(unsigned int irq) | 114 | static 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 | ||
110 | static void intc_irq_unmask(unsigned int irq) | 120 | static 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 | ||
116 | static int intc_irq_set_type(unsigned int irq, unsigned int type) | 126 | static int intc_irq_set_type(unsigned int irq, unsigned int type) |