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>
15 #include <linux/device.h>
16 #include <linux/serial_8250.h>
18 #include <asm/mach/arch.h>
19 #include <asm/mach/map.h>
20 #include <asm/mach/irq.h>
21 #include <asm/mach/time.h>
23 #include <asm/hardware.h>
24 #include <asm/hardware/iomd.h>
27 #include <asm/mach-types.h>
29 static void cl7500_ack_irq_a(unsigned int irq
)
31 unsigned int val
, mask
;
34 val
= iomd_readb(IOMD_IRQMASKA
);
35 iomd_writeb(val
& ~mask
, IOMD_IRQMASKA
);
36 iomd_writeb(mask
, IOMD_IRQCLRA
);
39 static void cl7500_mask_irq_a(unsigned int irq
)
41 unsigned int val
, mask
;
44 val
= iomd_readb(IOMD_IRQMASKA
);
45 iomd_writeb(val
& ~mask
, IOMD_IRQMASKA
);
48 static void cl7500_unmask_irq_a(unsigned int irq
)
50 unsigned int val
, mask
;
53 val
= iomd_readb(IOMD_IRQMASKA
);
54 iomd_writeb(val
| mask
, IOMD_IRQMASKA
);
57 static struct irqchip clps7500_a_chip
= {
58 .ack
= cl7500_ack_irq_a
,
59 .mask
= cl7500_mask_irq_a
,
60 .unmask
= cl7500_unmask_irq_a
,
63 static void cl7500_mask_irq_b(unsigned int irq
)
65 unsigned int val
, mask
;
67 mask
= 1 << (irq
& 7);
68 val
= iomd_readb(IOMD_IRQMASKB
);
69 iomd_writeb(val
& ~mask
, IOMD_IRQMASKB
);
72 static void cl7500_unmask_irq_b(unsigned int irq
)
74 unsigned int val
, mask
;
76 mask
= 1 << (irq
& 7);
77 val
= iomd_readb(IOMD_IRQMASKB
);
78 iomd_writeb(val
| mask
, IOMD_IRQMASKB
);
81 static struct irqchip clps7500_b_chip
= {
82 .ack
= cl7500_mask_irq_b
,
83 .mask
= cl7500_mask_irq_b
,
84 .unmask
= cl7500_unmask_irq_b
,
87 static void cl7500_mask_irq_c(unsigned int irq
)
89 unsigned int val
, mask
;
91 mask
= 1 << (irq
& 7);
92 val
= iomd_readb(IOMD_IRQMASKC
);
93 iomd_writeb(val
& ~mask
, IOMD_IRQMASKC
);
96 static void cl7500_unmask_irq_c(unsigned int irq
)
98 unsigned int val
, mask
;
100 mask
= 1 << (irq
& 7);
101 val
= iomd_readb(IOMD_IRQMASKC
);
102 iomd_writeb(val
| mask
, IOMD_IRQMASKC
);
105 static struct irqchip clps7500_c_chip
= {
106 .ack
= cl7500_mask_irq_c
,
107 .mask
= cl7500_mask_irq_c
,
108 .unmask
= cl7500_unmask_irq_c
,
111 static void cl7500_mask_irq_d(unsigned int irq
)
113 unsigned int val
, mask
;
115 mask
= 1 << (irq
& 7);
116 val
= iomd_readb(IOMD_IRQMASKD
);
117 iomd_writeb(val
& ~mask
, IOMD_IRQMASKD
);
120 static void cl7500_unmask_irq_d(unsigned int irq
)
122 unsigned int val
, mask
;
124 mask
= 1 << (irq
& 7);
125 val
= iomd_readb(IOMD_IRQMASKD
);
126 iomd_writeb(val
| mask
, IOMD_IRQMASKD
);
129 static struct irqchip clps7500_d_chip
= {
130 .ack
= cl7500_mask_irq_d
,
131 .mask
= cl7500_mask_irq_d
,
132 .unmask
= cl7500_unmask_irq_d
,
135 static void cl7500_mask_irq_dma(unsigned int irq
)
137 unsigned int val
, mask
;
139 mask
= 1 << (irq
& 7);
140 val
= iomd_readb(IOMD_DMAMASK
);
141 iomd_writeb(val
& ~mask
, IOMD_DMAMASK
);
144 static void cl7500_unmask_irq_dma(unsigned int irq
)
146 unsigned int val
, mask
;
148 mask
= 1 << (irq
& 7);
149 val
= iomd_readb(IOMD_DMAMASK
);
150 iomd_writeb(val
| mask
, IOMD_DMAMASK
);
153 static struct irqchip clps7500_dma_chip
= {
154 .ack
= cl7500_mask_irq_dma
,
155 .mask
= cl7500_mask_irq_dma
,
156 .unmask
= cl7500_unmask_irq_dma
,
159 static void cl7500_mask_irq_fiq(unsigned int irq
)
161 unsigned int val
, mask
;
163 mask
= 1 << (irq
& 7);
164 val
= iomd_readb(IOMD_FIQMASK
);
165 iomd_writeb(val
& ~mask
, IOMD_FIQMASK
);
168 static void cl7500_unmask_irq_fiq(unsigned int irq
)
170 unsigned int val
, mask
;
172 mask
= 1 << (irq
& 7);
173 val
= iomd_readb(IOMD_FIQMASK
);
174 iomd_writeb(val
| mask
, IOMD_FIQMASK
);
177 static struct irqchip clps7500_fiq_chip
= {
178 .ack
= cl7500_mask_irq_fiq
,
179 .mask
= cl7500_mask_irq_fiq
,
180 .unmask
= cl7500_unmask_irq_fiq
,
183 static void cl7500_no_action(unsigned int irq
)
187 static struct irqchip clps7500_no_chip
= {
188 .ack
= cl7500_no_action
,
189 .mask
= cl7500_no_action
,
190 .unmask
= cl7500_no_action
,
193 static struct irqaction irq_isa
= { no_action
, 0, CPU_MASK_NONE
, "isa", NULL
, NULL
};
195 static void __init
clps7500_init_irq(void)
197 unsigned int irq
, flags
;
199 iomd_writeb(0, IOMD_IRQMASKA
);
200 iomd_writeb(0, IOMD_IRQMASKB
);
201 iomd_writeb(0, IOMD_FIQMASK
);
202 iomd_writeb(0, IOMD_DMAMASK
);
204 for (irq
= 0; irq
< NR_IRQS
; irq
++) {
207 if (irq
<= 6 || (irq
>= 9 && irq
<= 15) ||
208 (irq
>= 48 && irq
<= 55))
213 set_irq_chip(irq
, &clps7500_a_chip
);
214 set_irq_handler(irq
, do_level_IRQ
);
215 set_irq_flags(irq
, flags
);
219 set_irq_chip(irq
, &clps7500_b_chip
);
220 set_irq_handler(irq
, do_level_IRQ
);
221 set_irq_flags(irq
, flags
);
225 set_irq_chip(irq
, &clps7500_dma_chip
);
226 set_irq_handler(irq
, do_level_IRQ
);
227 set_irq_flags(irq
, flags
);
231 set_irq_chip(irq
, &clps7500_c_chip
);
232 set_irq_handler(irq
, do_level_IRQ
);
233 set_irq_flags(irq
, flags
);
237 set_irq_chip(irq
, &clps7500_d_chip
);
238 set_irq_handler(irq
, do_level_IRQ
);
239 set_irq_flags(irq
, flags
);
243 set_irq_chip(irq
, &clps7500_no_chip
);
244 set_irq_handler(irq
, do_level_IRQ
);
245 set_irq_flags(irq
, flags
);
249 set_irq_chip(irq
, &clps7500_fiq_chip
);
250 set_irq_handler(irq
, do_level_IRQ
);
251 set_irq_flags(irq
, flags
);
256 setup_irq(IRQ_ISA
, &irq_isa
);
259 static struct map_desc cl7500_io_desc
[] __initdata
= {
260 { IO_BASE
, IO_START
, IO_SIZE
, MT_DEVICE
}, /* IO space */
261 { ISA_BASE
, ISA_START
, ISA_SIZE
, MT_DEVICE
}, /* ISA space */
262 { FLASH_BASE
, FLASH_START
, FLASH_SIZE
, MT_DEVICE
}, /* Flash */
263 { LED_BASE
, LED_START
, LED_SIZE
, MT_DEVICE
} /* LED */
266 static void __init
clps7500_map_io(void)
268 iotable_init(cl7500_io_desc
, ARRAY_SIZE(cl7500_io_desc
));
271 extern void ioctime_init(void);
272 extern unsigned long ioc_timer_gettimeoffset(void);
275 clps7500_timer_interrupt(int irq
, void *dev_id
, struct pt_regs
*regs
)
277 write_seqlock(&xtime_lock
);
281 /* Why not using do_leds interface?? */
283 /* Twinkle the lights. */
284 static int count
, state
= 0xff00;
288 *((volatile unsigned int *)LED_ADDRESS
) = state
;
292 write_sequnlock(&xtime_lock
);
297 static struct irqaction clps7500_timer_irq
= {
298 .name
= "CLPS7500 Timer Tick",
299 .flags
= SA_INTERRUPT
,
300 .handler
= clps7500_timer_interrupt
304 * Set up timer interrupt.
306 static void __init
clps7500_timer_init(void)
309 setup_irq(IRQ_TIMER
, &clps7500_timer_irq
);
312 static struct sys_timer clps7500_timer
= {
313 .init
= clps7500_timer_init
,
314 .offset
= ioc_timer_gettimeoffset
,
317 static struct plat_serial8250_port serial_platform_data
[] = {
319 .mapbase
= 0x03010fe0,
324 .flags
= UPF_BOOT_AUTOCONF
| UPF_IOREMAP
| UPF_SKIP_TEST
,
327 .mapbase
= 0x03010be0,
332 .flags
= UPF_BOOT_AUTOCONF
| UPF_IOREMAP
| UPF_SKIP_TEST
,
335 .iobase
= ISASLOT_IO
+ 0x2e8,
340 .flags
= UPF_BOOT_AUTOCONF
| UPF_SKIP_TEST
,
343 .iobase
= ISASLOT_IO
+ 0x3e8,
348 .flags
= UPF_BOOT_AUTOCONF
| UPF_SKIP_TEST
,
353 static struct platform_device serial_device
= {
354 .name
= "serial8250",
357 .platform_data
= serial_platform_data
,
361 static void __init
clps7500_init(void)
363 platform_device_register(&serial_device
);
366 MACHINE_START(CLPS7500
, "CL-PS7500")
367 MAINTAINER("Philip Blundell")
368 BOOT_MEM(0x10000000, 0x03000000, 0xe0000000)
369 MAPIO(clps7500_map_io
)
370 INITIRQ(clps7500_init_irq
)
371 .init_machine
= clps7500_init
,
372 .timer
= &clps7500_timer
,