2 * linux/arch/arm/mach-clps7500/core.c
4 * Copyright (C) 1998 Russell King
5 * Copyright (C) 1999 Nexus Electronics Ltd
7 * Extra MM routines for CL7500 architecture
9 #include <linux/kernel.h>
10 #include <linux/types.h>
11 #include <linux/interrupt.h>
12 #include <linux/list.h>
13 #include <linux/sched.h>
14 #include <linux/init.h>
16 #include <asm/mach/arch.h>
17 #include <asm/mach/map.h>
18 #include <asm/mach/irq.h>
19 #include <asm/mach/time.h>
21 #include <asm/hardware.h>
22 #include <asm/hardware/iomd.h>
25 #include <asm/mach-types.h>
27 static void cl7500_ack_irq_a(unsigned int irq)
29 unsigned int val, mask;
32 val = iomd_readb(IOMD_IRQMASKA);
33 iomd_writeb(val & ~mask, IOMD_IRQMASKA);
34 iomd_writeb(mask, IOMD_IRQCLRA);
37 static void cl7500_mask_irq_a(unsigned int irq)
39 unsigned int val, mask;
42 val = iomd_readb(IOMD_IRQMASKA);
43 iomd_writeb(val & ~mask, IOMD_IRQMASKA);
46 static void cl7500_unmask_irq_a(unsigned int irq)
48 unsigned int val, mask;
51 val = iomd_readb(IOMD_IRQMASKA);
52 iomd_writeb(val | mask, IOMD_IRQMASKA);
55 static struct irqchip clps7500_a_chip = {
56 .ack = cl7500_ack_irq_a,
57 .mask = cl7500_mask_irq_a,
58 .unmask = cl7500_unmask_irq_a,
61 static void cl7500_mask_irq_b(unsigned int irq)
63 unsigned int val, mask;
65 mask = 1 << (irq & 7);
66 val = iomd_readb(IOMD_IRQMASKB);
67 iomd_writeb(val & ~mask, IOMD_IRQMASKB);
70 static void cl7500_unmask_irq_b(unsigned int irq)
72 unsigned int val, mask;
74 mask = 1 << (irq & 7);
75 val = iomd_readb(IOMD_IRQMASKB);
76 iomd_writeb(val | mask, IOMD_IRQMASKB);
79 static struct irqchip clps7500_b_chip = {
80 .ack = cl7500_mask_irq_b,
81 .mask = cl7500_mask_irq_b,
82 .unmask = cl7500_unmask_irq_b,
85 static void cl7500_mask_irq_c(unsigned int irq)
87 unsigned int val, mask;
89 mask = 1 << (irq & 7);
90 val = iomd_readb(IOMD_IRQMASKC);
91 iomd_writeb(val & ~mask, IOMD_IRQMASKC);
94 static void cl7500_unmask_irq_c(unsigned int irq)
96 unsigned int val, mask;
98 mask = 1 << (irq & 7);
99 val = iomd_readb(IOMD_IRQMASKC);
100 iomd_writeb(val | mask, IOMD_IRQMASKC);
103 static struct irqchip clps7500_c_chip = {
104 .ack = cl7500_mask_irq_c,
105 .mask = cl7500_mask_irq_c,
106 .unmask = cl7500_unmask_irq_c,
109 static void cl7500_mask_irq_d(unsigned int irq)
111 unsigned int val, mask;
113 mask = 1 << (irq & 7);
114 val = iomd_readb(IOMD_IRQMASKD);
115 iomd_writeb(val & ~mask, IOMD_IRQMASKD);
118 static void cl7500_unmask_irq_d(unsigned int irq)
120 unsigned int val, mask;
122 mask = 1 << (irq & 7);
123 val = iomd_readb(IOMD_IRQMASKD);
124 iomd_writeb(val | mask, IOMD_IRQMASKD);
127 static struct irqchip clps7500_d_chip = {
128 .ack = cl7500_mask_irq_d,
129 .mask = cl7500_mask_irq_d,
130 .unmask = cl7500_unmask_irq_d,
133 static void cl7500_mask_irq_dma(unsigned int irq)
135 unsigned int val, mask;
137 mask = 1 << (irq & 7);
138 val = iomd_readb(IOMD_DMAMASK);
139 iomd_writeb(val & ~mask, IOMD_DMAMASK);
142 static void cl7500_unmask_irq_dma(unsigned int irq)
144 unsigned int val, mask;
146 mask = 1 << (irq & 7);
147 val = iomd_readb(IOMD_DMAMASK);
148 iomd_writeb(val | mask, IOMD_DMAMASK);
151 static struct irqchip clps7500_dma_chip = {
152 .ack = cl7500_mask_irq_dma,
153 .mask = cl7500_mask_irq_dma,
154 .unmask = cl7500_unmask_irq_dma,
157 static void cl7500_mask_irq_fiq(unsigned int irq)
159 unsigned int val, mask;
161 mask = 1 << (irq & 7);
162 val = iomd_readb(IOMD_FIQMASK);
163 iomd_writeb(val & ~mask, IOMD_FIQMASK);
166 static void cl7500_unmask_irq_fiq(unsigned int irq)
168 unsigned int val, mask;
170 mask = 1 << (irq & 7);
171 val = iomd_readb(IOMD_FIQMASK);
172 iomd_writeb(val | mask, IOMD_FIQMASK);
175 static struct irqchip clps7500_fiq_chip = {
176 .ack = cl7500_mask_irq_fiq,
177 .mask = cl7500_mask_irq_fiq,
178 .unmask = cl7500_unmask_irq_fiq,
181 static void cl7500_no_action(unsigned int irq)
185 static struct irqchip clps7500_no_chip = {
186 .ack = cl7500_no_action,
187 .mask = cl7500_no_action,
188 .unmask = cl7500_no_action,
191 static struct irqaction irq_isa = { no_action, 0, CPU_MASK_NONE, "isa", NULL, NULL };
193 static void __init clps7500_init_irq(void)
195 unsigned int irq, flags;
197 iomd_writeb(0, IOMD_IRQMASKA);
198 iomd_writeb(0, IOMD_IRQMASKB);
199 iomd_writeb(0, IOMD_FIQMASK);
200 iomd_writeb(0, IOMD_DMAMASK);
202 for (irq = 0; irq < NR_IRQS; irq++) {
205 if (irq <= 6 || (irq >= 9 && irq <= 15) ||
206 (irq >= 48 && irq <= 55))
211 set_irq_chip(irq, &clps7500_a_chip);
212 set_irq_handler(irq, do_level_IRQ);
213 set_irq_flags(irq, flags);
217 set_irq_chip(irq, &clps7500_b_chip);
218 set_irq_handler(irq, do_level_IRQ);
219 set_irq_flags(irq, flags);
223 set_irq_chip(irq, &clps7500_dma_chip);
224 set_irq_handler(irq, do_level_IRQ);
225 set_irq_flags(irq, flags);
229 set_irq_chip(irq, &clps7500_c_chip);
230 set_irq_handler(irq, do_level_IRQ);
231 set_irq_flags(irq, flags);
235 set_irq_chip(irq, &clps7500_d_chip);
236 set_irq_handler(irq, do_level_IRQ);
237 set_irq_flags(irq, flags);
241 set_irq_chip(irq, &clps7500_no_chip);
242 set_irq_handler(irq, do_level_IRQ);
243 set_irq_flags(irq, flags);
247 set_irq_chip(irq, &clps7500_fiq_chip);
248 set_irq_handler(irq, do_level_IRQ);
249 set_irq_flags(irq, flags);
254 setup_irq(IRQ_ISA, &irq_isa);
257 static struct map_desc cl7500_io_desc[] __initdata = {
258 { IO_BASE, IO_START, IO_SIZE, MT_DEVICE }, /* IO space */
259 { ISA_BASE, ISA_START, ISA_SIZE, MT_DEVICE }, /* ISA space */
260 { FLASH_BASE, FLASH_START, FLASH_SIZE, MT_DEVICE }, /* Flash */
261 { LED_BASE, LED_START, LED_SIZE, MT_DEVICE } /* LED */
264 static void __init clps7500_map_io(void)
266 iotable_init(cl7500_io_desc, ARRAY_SIZE(cl7500_io_desc));
269 extern void ioctime_init(void);
272 clps7500_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
276 /* Why not using do_leds interface?? */
278 /* Twinkle the lights. */
279 static int count, state = 0xff00;
283 *((volatile unsigned int *)LED_ADDRESS) = state;
289 static struct irqaction clps7500_timer_irq = {
290 .name = "CLPS7500 Timer Tick",
291 .flags = SA_INTERRUPT,
292 .handler = clps7500_timer_interrupt
296 * Set up timer interrupt.
298 void __init clps7500_init_time(void)
302 setup_irq(IRQ_TIMER, &clps7500_timer_irq);
305 MACHINE_START(CLPS7500, "CL-PS7500")
306 MAINTAINER("Philip Blundell")
307 BOOT_MEM(0x10000000, 0x03000000, 0xe0000000)
308 MAPIO(clps7500_map_io)
309 INITIRQ(clps7500_init_irq)
310 INITTIME(clps7500_init_time)