1
2
3
4
5
6
7
8
9
10
11#include <linux/types.h>
12#include <linux/init.h>
13#include <linux/kernel.h>
14#include <linux/interrupt.h>
15#include <linux/irq.h>
16#include <linux/io.h>
17#include <asm/coldfire.h>
18#include <asm/mcfsim.h>
19#include <asm/traps.h>
20
21
22
23
24
25
26
27
28
29
30
31
32
33struct irqmap {
34 unsigned char icr;
35 unsigned char index;
36 unsigned char ack;
37};
38
39static struct irqmap intc_irqmap[MCFINT_VECMAX - MCFINT_VECBASE] = {
40 { .icr = 0, .index = 0, .ack = 0, },
41 { .icr = MCFSIM_ICR1, .index = 28, .ack = 1, },
42 { .icr = MCFSIM_ICR1, .index = 24, .ack = 1, },
43 { .icr = MCFSIM_ICR1, .index = 20, .ack = 1, },
44 { .icr = MCFSIM_ICR1, .index = 16, .ack = 1, },
45 { .icr = MCFSIM_ICR1, .index = 12, .ack = 0, },
46 { .icr = MCFSIM_ICR1, .index = 8, .ack = 0, },
47 { .icr = MCFSIM_ICR1, .index = 4, .ack = 0, },
48 { .icr = MCFSIM_ICR1, .index = 0, .ack = 0, },
49 { .icr = MCFSIM_ICR2, .index = 28, .ack = 0, },
50 { .icr = MCFSIM_ICR2, .index = 24, .ack = 0, },
51 { .icr = MCFSIM_ICR2, .index = 20, .ack = 0, },
52 { .icr = MCFSIM_ICR2, .index = 16, .ack = 0, },
53 { .icr = MCFSIM_ICR2, .index = 12, .ack = 0, },
54 { .icr = MCFSIM_ICR2, .index = 8, .ack = 0, },
55 { .icr = MCFSIM_ICR2, .index = 4, .ack = 0, },
56 { .icr = MCFSIM_ICR2, .index = 0, .ack = 0, },
57 { .icr = MCFSIM_ICR3, .index = 28, .ack = 0, },
58 { .icr = MCFSIM_ICR3, .index = 24, .ack = 0, },
59 { .icr = MCFSIM_ICR3, .index = 20, .ack = 0, },
60 { .icr = MCFSIM_ICR3, .index = 16, .ack = 0, },
61 { .icr = MCFSIM_ICR3, .index = 12, .ack = 0, },
62 { .icr = MCFSIM_ICR3, .index = 8, .ack = 0, },
63 { .icr = MCFSIM_ICR3, .index = 4, .ack = 0, },
64 { .icr = MCFSIM_ICR3, .index = 0, .ack = 0, },
65 { .icr = MCFSIM_ICR4, .index = 28, .ack = 0, },
66 { .icr = MCFSIM_ICR4, .index = 24, .ack = 1, },
67 { .icr = MCFSIM_ICR4, .index = 20, .ack = 1, },
68 { .icr = MCFSIM_ICR4, .index = 16, .ack = 0, },
69};
70
71static void intc_irq_mask(unsigned int irq)
72{
73 if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECMAX)) {
74 u32 v;
75 irq -= MCFINT_VECBASE;
76 v = 0x8 << intc_irqmap[irq].index;
77 writel(v, MCF_MBAR + intc_irqmap[irq].icr);
78 }
79}
80
81static void intc_irq_unmask(unsigned int irq)
82{
83 if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECMAX)) {
84 u32 v;
85 irq -= MCFINT_VECBASE;
86 v = 0xd << intc_irqmap[irq].index;
87 writel(v, MCF_MBAR + intc_irqmap[irq].icr);
88 }
89}
90
91static void intc_irq_ack(unsigned int irq)
92{
93
94 if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECMAX)) {
95 irq -= MCFINT_VECBASE;
96 if (intc_irqmap[irq].ack) {
97 u32 v;
98 v = 0xd << intc_irqmap[irq].index;
99 writel(v, MCF_MBAR + intc_irqmap[irq].icr);
100 }
101 }
102}
103
104static int intc_irq_set_type(unsigned int irq, unsigned int type)
105{
106
107 return 0;
108}
109
110static struct irq_chip intc_irq_chip = {
111 .name = "CF-INTC",
112 .mask = intc_irq_mask,
113 .unmask = intc_irq_unmask,
114 .ack = intc_irq_ack,
115 .set_type = intc_irq_set_type,
116};
117
118void __init init_IRQ(void)
119{
120 int irq;
121
122 init_vectors();
123
124
125 writel(0x88888888, MCF_MBAR + MCFSIM_ICR1);
126 writel(0x88888888, MCF_MBAR + MCFSIM_ICR2);
127 writel(0x88888888, MCF_MBAR + MCFSIM_ICR3);
128 writel(0x88888888, MCF_MBAR + MCFSIM_ICR4);
129
130 for (irq = 0; (irq < NR_IRQS); irq++) {
131 irq_desc[irq].status = IRQ_DISABLED;
132 irq_desc[irq].action = NULL;
133 irq_desc[irq].depth = 1;
134 irq_desc[irq].chip = &intc_irq_chip;
135 intc_irq_set_type(irq, 0);
136 }
137}
138
139