treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 1
[linux-2.6-microblaze.git] / arch / mips / vr41xx / common / siu.c
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
17 static unsigned int siu_type1_ports[SIU_PORTS_MAX] __initdata = {
18         PORT_VR41XX_SIU,
19         PORT_UNKNOWN,
20 };
21
22 static 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
35 static unsigned int siu_type2_ports[SIU_PORTS_MAX] __initdata = {
36         PORT_VR41XX_SIU,
37         PORT_VR41XX_DSIU,
38 };
39
40 static 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
63 static 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
103 err_free_device:
104         platform_device_put(pdev);
105
106         return retval;
107 }
108 device_initcall(vr41xx_siu_add);
109
110 void __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 }