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/irq_cpu.h>
20 #define PORT(_base,_irq) \
25 .iotype = UPIO_PORT, \
26 .flags = UPF_BOOT_AUTOCONF, \
29 static struct plat_serial8250_port rm200_data
[] = {
35 static struct platform_device rm200_serial8250_device
= {
37 .id
= PLAT8250_DEV_PLATFORM
,
39 .platform_data
= rm200_data
,
43 static struct resource rm200_ds1216_rsrc
[] = {
47 .flags
= IORESOURCE_MEM
51 static struct platform_device rm200_ds1216_device
= {
53 .num_resources
= ARRAY_SIZE(rm200_ds1216_rsrc
),
54 .resource
= rm200_ds1216_rsrc
57 static struct resource snirm_82596_rm200_rsrc
[] = {
61 .flags
= IORESOURCE_MEM
66 .flags
= IORESOURCE_MEM
71 .flags
= IORESOURCE_MEM
76 .flags
= IORESOURCE_IRQ
83 static struct platform_device snirm_82596_rm200_pdev
= {
84 .name
= "snirm_82596",
85 .num_resources
= ARRAY_SIZE(snirm_82596_rm200_rsrc
),
86 .resource
= snirm_82596_rm200_rsrc
89 static struct resource snirm_53c710_rm200_rsrc
[] = {
93 .flags
= IORESOURCE_MEM
98 .flags
= IORESOURCE_IRQ
102 static struct platform_device snirm_53c710_rm200_pdev
= {
103 .name
= "snirm_53c710",
104 .num_resources
= ARRAY_SIZE(snirm_53c710_rm200_rsrc
),
105 .resource
= snirm_53c710_rm200_rsrc
108 static int __init
snirm_setup_devinit(void)
110 if (sni_brd_type
== SNI_BRD_RM200
) {
111 platform_device_register(&rm200_serial8250_device
);
112 platform_device_register(&rm200_ds1216_device
);
113 platform_device_register(&snirm_82596_rm200_pdev
);
114 platform_device_register(&snirm_53c710_rm200_pdev
);
119 device_initcall(snirm_setup_devinit
);
122 #define SNI_RM200_INT_STAT_REG 0xbc000000
123 #define SNI_RM200_INT_ENA_REG 0xbc080000
125 #define SNI_RM200_INT_START 24
126 #define SNI_RM200_INT_END 28
128 static void enable_rm200_irq(unsigned int irq
)
130 unsigned int mask
= 1 << (irq
- SNI_RM200_INT_START
);
132 *(volatile u8
*)SNI_RM200_INT_ENA_REG
&= ~mask
;
135 void disable_rm200_irq(unsigned int irq
)
137 unsigned int mask
= 1 << (irq
- SNI_RM200_INT_START
);
139 *(volatile u8
*)SNI_RM200_INT_ENA_REG
|= mask
;
142 void end_rm200_irq(unsigned int irq
)
144 if (!(irq_desc
[irq
].status
& (IRQ_DISABLED
|IRQ_INPROGRESS
)))
145 enable_rm200_irq(irq
);
148 static struct irq_chip rm200_irq_type
= {
150 .ack
= disable_rm200_irq
,
151 .mask
= disable_rm200_irq
,
152 .mask_ack
= disable_rm200_irq
,
153 .unmask
= enable_rm200_irq
,
154 .end
= end_rm200_irq
,
157 static void sni_rm200_hwint(void)
159 u32 pending
= read_c0_cause() & read_c0_status();
164 if (pending
& C_IRQ5
)
165 do_IRQ(MIPS_CPU_IRQ_BASE
+ 7);
166 else if (pending
& C_IRQ0
) {
167 clear_c0_status(IE_IRQ0
);
168 mask
= *(volatile u8
*)SNI_RM200_INT_ENA_REG
^ 0x1f;
169 stat
= *(volatile u8
*)SNI_RM200_INT_STAT_REG
^ 0x14;
170 irq
= ffs(stat
& mask
& 0x1f);
173 do_IRQ(irq
+ SNI_RM200_INT_START
- 1);
174 set_c0_status(IE_IRQ0
);
178 void __init
sni_rm200_irq_init(void)
182 * (volatile u8
*)SNI_RM200_INT_ENA_REG
= 0x1f;
185 /* Actually we've got more interrupts to handle ... */
186 for (i
= SNI_RM200_INT_START
; i
<= SNI_RM200_INT_END
; i
++)
187 set_irq_chip(i
, &rm200_irq_type
);
188 sni_hwint
= sni_rm200_hwint
;
189 change_c0_status(ST0_IM
, IE_IRQ0
);
190 setup_irq(SNI_RM200_INT_START
+ 0, &sni_isa_irq
);
193 void __init
sni_rm200_init(void)
195 set_io_port_base(SNI_PORT_BASE
+ 0x02000000);
196 ioport_resource
.end
+= 0x02000000;