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
8 * Copyright (C) 2006 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
11 #include <linux/init.h>
12 #include <linux/interrupt.h>
13 #include <linux/platform_device.h>
14 #include <linux/serial_8250.h>
18 #include <asm/ds1216.h>
19 #include <asm/irq_cpu.h>
21 #define PORT(_base,_irq) \
26 .iotype = UPIO_PORT, \
27 .flags = UPF_BOOT_AUTOCONF, \
30 static struct plat_serial8250_port rm200_data
[] = {
36 static struct platform_device rm200_serial8250_device
= {
38 .id
= PLAT8250_DEV_PLATFORM
,
40 .platform_data
= rm200_data
,
44 static struct resource snirm_82596_rm200_rsrc
[] = {
48 .flags
= IORESOURCE_MEM
53 .flags
= IORESOURCE_MEM
58 .flags
= IORESOURCE_MEM
63 .flags
= IORESOURCE_IRQ
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
[] = {
80 .flags
= IORESOURCE_MEM
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
);
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
= {
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();
150 if (pending
& C_IRQ5
)
151 do_IRQ (MIPS_CPU_IRQ_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);
159 do_IRQ (irq
+ SNI_RM200_INT_START
- 1);
160 set_c0_status (IE_IRQ0
);
164 void __init
sni_rm200_irq_init(void)
168 * (volatile u8
*)SNI_RM200_INT_ENA_REG
= 0x1f;
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
;