aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/vr41xx/common/siu.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/vr41xx/common/siu.c')
-rw-r--r--arch/mips/vr41xx/common/siu.c142
1 files changed, 142 insertions, 0 deletions
diff --git a/arch/mips/vr41xx/common/siu.c b/arch/mips/vr41xx/common/siu.c
new file mode 100644
index 000000000..b37a79154
--- /dev/null
+++ b/arch/mips/vr41xx/common/siu.c
@@ -0,0 +1,142 @@
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * NEC VR4100 series SIU platform device.
4 *
5 * Copyright (C) 2007-2008 Yoichi Yuasa <yuasa@linux-mips.org>
6 */
7#include <linux/errno.h>
8#include <linux/init.h>
9#include <linux/ioport.h>
10#include <linux/platform_device.h>
11#include <linux/serial_core.h>
12#include <linux/irq.h>
13
14#include <asm/cpu.h>
15#include <asm/vr41xx/siu.h>
16
17static unsigned int siu_type1_ports[SIU_PORTS_MAX] __initdata = {
18 PORT_VR41XX_SIU,
19 PORT_UNKNOWN,
20};
21
22static struct resource siu_type1_resource[] __initdata = {
23 {
24 .start = 0x0c000000,
25 .end = 0x0c00000a,
26 .flags = IORESOURCE_MEM,
27 },
28 {
29 .start = SIU_IRQ,
30 .end = SIU_IRQ,
31 .flags = IORESOURCE_IRQ,
32 },
33};
34
35static unsigned int siu_type2_ports[SIU_PORTS_MAX] __initdata = {
36 PORT_VR41XX_SIU,
37 PORT_VR41XX_DSIU,
38};
39
40static struct resource siu_type2_resource[] __initdata = {
41 {
42 .start = 0x0f000800,
43 .end = 0x0f00080a,
44 .flags = IORESOURCE_MEM,
45 },
46 {
47 .start = 0x0f000820,
48 .end = 0x0f000829,
49 .flags = IORESOURCE_MEM,
50 },
51 {
52 .start = SIU_IRQ,
53 .end = SIU_IRQ,
54 .flags = IORESOURCE_IRQ,
55 },
56 {
57 .start = DSIU_IRQ,
58 .end = DSIU_IRQ,
59 .flags = IORESOURCE_IRQ,
60 },
61};
62
63static int __init vr41xx_siu_add(void)
64{
65 struct platform_device *pdev;
66 struct resource *res;
67 unsigned int num;
68 int retval;
69
70 pdev = platform_device_alloc("SIU", -1);
71 if (!pdev)
72 return -ENOMEM;
73
74 switch (current_cpu_type()) {
75 case CPU_VR4111:
76 case CPU_VR4121:
77 pdev->dev.platform_data = siu_type1_ports;
78 res = siu_type1_resource;
79 num = ARRAY_SIZE(siu_type1_resource);
80 break;
81 case CPU_VR4122:
82 case CPU_VR4131:
83 case CPU_VR4133:
84 pdev->dev.platform_data = siu_type2_ports;
85 res = siu_type2_resource;
86 num = ARRAY_SIZE(siu_type2_resource);
87 break;
88 default:
89 retval = -ENODEV;
90 goto err_free_device;
91 }
92
93 retval = platform_device_add_resources(pdev, res, num);
94 if (retval)
95 goto err_free_device;
96
97 retval = platform_device_add(pdev);
98 if (retval)
99 goto err_free_device;
100
101 return 0;
102
103err_free_device:
104 platform_device_put(pdev);
105
106 return retval;
107}
108device_initcall(vr41xx_siu_add);
109
110void __init vr41xx_siu_setup(void)
111{
112 struct uart_port port;
113 struct resource *res;
114 unsigned int *type;
115 int i;
116
117 switch (current_cpu_type()) {
118 case CPU_VR4111:
119 case CPU_VR4121:
120 type = siu_type1_ports;
121 res = siu_type1_resource;
122 break;
123 case CPU_VR4122:
124 case CPU_VR4131:
125 case CPU_VR4133:
126 type = siu_type2_ports;
127 res = siu_type2_resource;
128 break;
129 default:
130 return;
131 }
132
133 for (i = 0; i < SIU_PORTS_MAX; i++) {
134 port.line = i;
135 port.type = type[i];
136 if (port.type == PORT_UNKNOWN)
137 break;
138 port.mapbase = res[i].start;
139 port.membase = (unsigned char __iomem *)KSEG1ADDR(res[i].start);
140 vr41xx_siu_early_setup(&port);
141 }
142}