[MIPS] Support for several more SNI RM models.
[linux-2.6/linux-mips.git] / arch / mips / sni / rm200.c
blob517dc698c08302381b6a8bb6e5085e5105f23586
1 /*
2 * RM200 specific code
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
8 * Copyright (C) 2006 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
9 */
11 #include <linux/init.h>
12 #include <linux/interrupt.h>
13 #include <linux/platform_device.h>
14 #include <linux/serial_8250.h>
16 #include <asm/sni.h>
17 #include <asm/time.h>
18 #include <asm/ds1216.h>
19 #include <asm/irq_cpu.h>
21 #define PORT(_base,_irq) \
22 { \
23 .iobase = _base, \
24 .irq = _irq, \
25 .uartclk = 1843200, \
26 .iotype = UPIO_PORT, \
27 .flags = UPF_BOOT_AUTOCONF, \
30 static struct plat_serial8250_port rm200_data[] = {
31 PORT(0x3f8, 4),
32 PORT(0x2f8, 3),
33 { },
36 static struct platform_device rm200_serial8250_device = {
37 .name = "serial8250",
38 .id = PLAT8250_DEV_PLATFORM,
39 .dev = {
40 .platform_data = rm200_data,
44 static struct resource snirm_82596_rm200_rsrc[] = {
46 .start = 0xb8000000,
47 .end = 0xb80fffff,
48 .flags = IORESOURCE_MEM
51 .start = 0xbb000000,
52 .end = 0xbb000004,
53 .flags = IORESOURCE_MEM
56 .start = 0xbff00000,
57 .end = 0xbff00020,
58 .flags = IORESOURCE_MEM
61 .start = 27,
62 .end = 27,
63 .flags = IORESOURCE_IRQ
66 .flags = 0x00
70 static struct platform_device snirm_82596_rm200_pdev = {
71 .name = "snirm_82596",
72 .num_resources = ARRAY_SIZE(snirm_82596_rm200_rsrc),
73 .resource = snirm_82596_rm200_rsrc
76 static struct resource snirm_53c710_rm200_rsrc[] = {
78 .start = 0xb9000000,
79 .end = 0xb90fffff,
80 .flags = IORESOURCE_MEM
83 .start = 26,
84 .end = 26,
85 .flags = IORESOURCE_IRQ
89 static struct platform_device snirm_53c710_rm200_pdev = {
90 .name = "snirm_53c710",
91 .num_resources = ARRAY_SIZE(snirm_53c710_rm200_rsrc),
92 .resource = snirm_53c710_rm200_rsrc
95 static int __init snirm_setup_devinit(void)
97 if (sni_brd_type == SNI_BRD_RM200) {
98 platform_device_register(&rm200_serial8250_device);
99 platform_device_register(&snirm_82596_rm200_pdev);
100 platform_device_register(&snirm_53c710_rm200_pdev);
102 return 0;
105 device_initcall(snirm_setup_devinit);
108 #define SNI_RM200_INT_STAT_REG 0xbc000000
109 #define SNI_RM200_INT_ENA_REG 0xbc080000
111 #define SNI_RM200_INT_START 24
112 #define SNI_RM200_INT_END 28
114 static void enable_rm200_irq(unsigned int irq)
116 unsigned int mask = 1 << (irq - SNI_RM200_INT_START);
118 *(volatile u8 *)SNI_RM200_INT_ENA_REG &= ~mask;
121 void disable_rm200_irq(unsigned int irq)
123 unsigned int mask = 1 << (irq - SNI_RM200_INT_START);
125 *(volatile u8 *)SNI_RM200_INT_ENA_REG |= mask;
128 void end_rm200_irq(unsigned int irq)
130 if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
131 enable_rm200_irq(irq);
134 static struct irq_chip rm200_irq_type = {
135 .typename = "RM200",
136 .ack = disable_rm200_irq,
137 .mask = disable_rm200_irq,
138 .mask_ack = disable_rm200_irq,
139 .unmask = enable_rm200_irq,
140 .end = end_rm200_irq,
143 static void sni_rm200_hwint(void)
145 u32 pending = read_c0_cause() & read_c0_status();
146 u8 mask;
147 u8 stat;
148 int irq;
150 if (pending & C_IRQ5)
151 do_IRQ (SNI_MIPS_IRQ_CPU_BASE + 7);
152 else if (pending & C_IRQ0) {
153 clear_c0_status (IE_IRQ0);
154 mask = *(volatile u8 *)SNI_RM200_INT_ENA_REG ^ 0x1f;
155 stat = *(volatile u8 *)SNI_RM200_INT_STAT_REG ^ 0x14;
156 irq = ffs(stat & mask & 0x1f);
158 if (likely(irq > 0))
159 do_IRQ (irq + SNI_RM200_INT_START - 1);
160 set_c0_status (IE_IRQ0);
164 void __init sni_rm200_irq_init(void)
166 int i;
168 * (volatile u8 *)SNI_RM200_INT_ENA_REG = 0x1f;
170 mips_cpu_irq_init();
171 /* Actually we've got more interrupts to handle ... */
172 for (i = SNI_RM200_INT_START; i <= SNI_RM200_INT_END; i++)
173 set_irq_chip(i, &rm200_irq_type);
174 sni_hwint = sni_rm200_hwint;
175 change_c0_status(ST0_IM, IE_IRQ0);
176 setup_irq (SNI_RM200_INT_START + 0, &sni_isa_irq);
179 void sni_rm200_init(void)
181 set_io_port_base(SNI_PORT_BASE + 0x02000000);
182 ioport_resource.end += 0x02000000;
183 ds1216_base = (volatile unsigned char *) SNI_DS1216_RM200_BASE;
184 rtc_mips_get_time = ds1216_get_cmos_time;
185 board_time_init = sni_cpu_time_init;