ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / arch / arm / mach-clps7500 / core.c
1 /*
2  *  linux/arch/arm/mach-clps7500/core.c
3  *
4  *  Copyright (C) 1998 Russell King
5  *  Copyright (C) 1999 Nexus Electronics Ltd
6  *
7  * Extra MM routines for CL7500 architecture
8  */
9 #include <linux/kernel.h>
10 #include <linux/types.h>
11 #include <linux/interrupt.h>
12 #include <linux/list.h>
13 #include <linux/timer.h>
14 #include <linux/init.h>
15
16 #include <asm/mach/arch.h>
17 #include <asm/mach/map.h>
18 #include <asm/mach/irq.h>
19
20 #include <asm/hardware.h>
21 #include <asm/hardware/iomd.h>
22 #include <asm/io.h>
23 #include <asm/irq.h>
24 #include <asm/mach-types.h>
25
26 static void cl7500_ack_irq_a(unsigned int irq)
27 {
28         unsigned int val, mask;
29
30         mask = 1 << irq;
31         val = iomd_readb(IOMD_IRQMASKA);
32         iomd_writeb(val & ~mask, IOMD_IRQMASKA);
33         iomd_writeb(mask, IOMD_IRQCLRA);
34 }
35
36 static void cl7500_mask_irq_a(unsigned int irq)
37 {
38         unsigned int val, mask;
39
40         mask = 1 << irq;
41         val = iomd_readb(IOMD_IRQMASKA);
42         iomd_writeb(val & ~mask, IOMD_IRQMASKA);
43 }
44
45 static void cl7500_unmask_irq_a(unsigned int irq)
46 {
47         unsigned int val, mask;
48
49         mask = 1 << irq;
50         val = iomd_readb(IOMD_IRQMASKA);
51         iomd_writeb(val | mask, IOMD_IRQMASKA);
52 }
53
54 static struct irqchip clps7500_a_chip = {
55         .ack    = cl7500_ack_irq_a,
56         .mask   = cl7500_mask_irq_a,
57         .unmask = cl7500_unmask_irq_a,
58 };
59
60 static void cl7500_mask_irq_b(unsigned int irq)
61 {
62         unsigned int val, mask;
63
64         mask = 1 << (irq & 7);
65         val = iomd_readb(IOMD_IRQMASKB);
66         iomd_writeb(val & ~mask, IOMD_IRQMASKB);
67 }
68
69 static void cl7500_unmask_irq_b(unsigned int irq)
70 {
71         unsigned int val, mask;
72
73         mask = 1 << (irq & 7);
74         val = iomd_readb(IOMD_IRQMASKB);
75         iomd_writeb(val | mask, IOMD_IRQMASKB);
76 }
77
78 static struct irqchip clps7500_b_chip = {
79         .ack    = cl7500_mask_irq_b,
80         .mask   = cl7500_mask_irq_b,
81         .unmask = cl7500_unmask_irq_b,
82 };
83
84 static void cl7500_mask_irq_c(unsigned int irq)
85 {
86         unsigned int val, mask;
87
88         mask = 1 << (irq & 7);
89         val = iomd_readb(IOMD_IRQMASKC);
90         iomd_writeb(val & ~mask, IOMD_IRQMASKC);
91 }
92
93 static void cl7500_unmask_irq_c(unsigned int irq)
94 {
95         unsigned int val, mask;
96
97         mask = 1 << (irq & 7);
98         val = iomd_readb(IOMD_IRQMASKC);
99         iomd_writeb(val | mask, IOMD_IRQMASKC);
100 }
101
102 static struct irqchip clps7500_c_chip = {
103         .ack    = cl7500_mask_irq_c,
104         .mask   = cl7500_mask_irq_c,
105         .unmask = cl7500_unmask_irq_c,
106 };
107
108 static void cl7500_mask_irq_d(unsigned int irq)
109 {
110         unsigned int val, mask;
111
112         mask = 1 << (irq & 7);
113         val = iomd_readb(IOMD_IRQMASKD);
114         iomd_writeb(val & ~mask, IOMD_IRQMASKD);
115 }
116
117 static void cl7500_unmask_irq_d(unsigned int irq)
118 {
119         unsigned int val, mask;
120
121         mask = 1 << (irq & 7);
122         val = iomd_readb(IOMD_IRQMASKD);
123         iomd_writeb(val | mask, IOMD_IRQMASKD);
124 }
125
126 static struct irqchip clps7500_d_chip = {
127         .ack    = cl7500_mask_irq_d,
128         .mask   = cl7500_mask_irq_d,
129         .unmask = cl7500_unmask_irq_d,
130 };
131
132 static void cl7500_mask_irq_dma(unsigned int irq)
133 {
134         unsigned int val, mask;
135
136         mask = 1 << (irq & 7);
137         val = iomd_readb(IOMD_DMAMASK);
138         iomd_writeb(val & ~mask, IOMD_DMAMASK);
139 }
140
141 static void cl7500_unmask_irq_dma(unsigned int irq)
142 {
143         unsigned int val, mask;
144
145         mask = 1 << (irq & 7);
146         val = iomd_readb(IOMD_DMAMASK);
147         iomd_writeb(val | mask, IOMD_DMAMASK);
148 }
149
150 static struct irqchip clps7500_dma_chip = {
151         .ack    = cl7500_mask_irq_dma,
152         .mask   = cl7500_mask_irq_dma,
153         .unmask = cl7500_unmask_irq_dma,
154 };
155
156 static void cl7500_mask_irq_fiq(unsigned int irq)
157 {
158         unsigned int val, mask;
159
160         mask = 1 << (irq & 7);
161         val = iomd_readb(IOMD_FIQMASK);
162         iomd_writeb(val & ~mask, IOMD_FIQMASK);
163 }
164
165 static void cl7500_unmask_irq_fiq(unsigned int irq)
166 {
167         unsigned int val, mask;
168
169         mask = 1 << (irq & 7);
170         val = iomd_readb(IOMD_FIQMASK);
171         iomd_writeb(val | mask, IOMD_FIQMASK);
172 }
173
174 static struct irqchip clps7500_fiq_chip = {
175         .ack    = cl7500_mask_irq_fiq,
176         .mask   = cl7500_mask_irq_fiq,
177         .unmask = cl7500_unmask_irq_fiq,
178 };
179
180 static void cl7500_no_action(unsigned int irq)
181 {
182 }
183
184 static struct irqchip clps7500_no_chip = {
185         .ack    = cl7500_no_action,
186         .mask   = cl7500_no_action,
187         .unmask = cl7500_no_action,
188 };
189
190 static struct irqaction irq_isa = { no_action, 0, 0, "isa", NULL, NULL };
191
192 static void __init clps7500_init_irq(void)
193 {
194         unsigned int irq, flags;
195
196         iomd_writeb(0, IOMD_IRQMASKA);
197         iomd_writeb(0, IOMD_IRQMASKB);
198         iomd_writeb(0, IOMD_FIQMASK);
199         iomd_writeb(0, IOMD_DMAMASK);
200
201         for (irq = 0; irq < NR_IRQS; irq++) {
202                 flags = IRQF_VALID;
203
204                 if (irq <= 6 || (irq >= 9 && irq <= 15) ||
205                     (irq >= 48 && irq <= 55))
206                         flags |= IRQF_PROBE;
207
208                 switch (irq) {
209                 case 0 ... 7:
210                         set_irq_chip(irq, &clps7500_a_chip);
211                         set_irq_handler(irq, do_level_IRQ);
212                         set_irq_flags(irq, flags);
213                         break;
214
215                 case 8 ... 15:
216                         set_irq_chip(irq, &clps7500_b_chip);
217                         set_irq_handler(irq, do_level_IRQ);
218                         set_irq_flags(irq, flags);
219                         break;
220
221                 case 16 ... 22:
222                         set_irq_chip(irq, &clps7500_dma_chip);
223                         set_irq_handler(irq, do_level_IRQ);
224                         set_irq_flags(irq, flags);
225                         break;
226
227                 case 24 ... 31:
228                         set_irq_chip(irq, &clps7500_c_chip);
229                         set_irq_handler(irq, do_level_IRQ);
230                         set_irq_flags(irq, flags);
231                         break;
232
233                 case 40 ... 47:
234                         set_irq_chip(irq, &clps7500_d_chip);
235                         set_irq_handler(irq, do_level_IRQ);
236                         set_irq_flags(irq, flags);
237                         break;
238
239                 case 48 ... 55:
240                         set_irq_chip(irq, &clps7500_no_chip);
241                         set_irq_handler(irq, do_level_IRQ);
242                         set_irq_flags(irq, flags);
243                         break;
244
245                 case 64 ... 72:
246                         set_irq_chip(irq, &clps7500_fiq_chip);
247                         set_irq_handler(irq, do_level_IRQ);
248                         set_irq_flags(irq, flags);
249                         break;
250                 }
251         }
252
253         setup_irq(IRQ_ISA, &irq_isa);
254 }
255
256 static struct map_desc cl7500_io_desc[] __initdata = {
257         { IO_BASE,      IO_START,       IO_SIZE,    MT_DEVICE },        /* IO space     */
258         { ISA_BASE,     ISA_START,      ISA_SIZE,   MT_DEVICE },        /* ISA space    */
259         { FLASH_BASE,   FLASH_START,    FLASH_SIZE, MT_DEVICE },        /* Flash        */
260         { LED_BASE,     LED_START,      LED_SIZE,   MT_DEVICE }         /* LED          */
261 };
262
263 static void __init clps7500_map_io(void)
264 {
265         iotable_init(cl7500_io_desc, ARRAY_SIZE(cl7500_io_desc));
266 }
267
268 MACHINE_START(CLPS7500, "CL-PS7500")
269         MAINTAINER("Philip Blundell")
270         BOOT_MEM(0x10000000, 0x03000000, 0xe0000000)
271         MAPIO(clps7500_map_io)
272         INITIRQ(clps7500_init_irq)
273 MACHINE_END
274