1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * NEC VR4100 series GIU platform device.
4 *
5 * Copyright (C) 2007 Yoichi Yuasa <yuasa@linux-mips.org>
6 */
7 #include <linux/errno.h>
8 #include <linux/init.h>
9 #include <linux/smp.h>
10 #include <linux/ioport.h>
11 #include <linux/platform_device.h>
12
13 #include <asm/cpu.h>
14 #include <asm/vr41xx/giu.h>
15 #include <asm/vr41xx/irq.h>
16
17 static struct resource giu_50pins_pullupdown_resource[] __initdata = {
18 {
19 .start = 0x0b000100,
20 .end = 0x0b00011f,
21 .flags = IORESOURCE_MEM,
22 },
23 {
24 .start = 0x0b0002e0,
25 .end = 0x0b0002e3,
26 .flags = IORESOURCE_MEM,
27 },
28 {
29 .start = GIUINT_IRQ,
30 .end = GIUINT_IRQ,
31 .flags = IORESOURCE_IRQ,
32 },
33 };
34
35 static struct resource giu_36pins_resource[] __initdata = {
36 {
37 .start = 0x0f000140,
38 .end = 0x0f00015f,
39 .flags = IORESOURCE_MEM,
40 },
41 {
42 .start = GIUINT_IRQ,
43 .end = GIUINT_IRQ,
44 .flags = IORESOURCE_IRQ,
45 },
46 };
47
48 static struct resource giu_48pins_resource[] __initdata = {
49 {
50 .start = 0x0f000140,
51 .end = 0x0f000167,
52 .flags = IORESOURCE_MEM,
53 },
54 {
55 .start = GIUINT_IRQ,
56 .end = GIUINT_IRQ,
57 .flags = IORESOURCE_IRQ,
58 },
59 };
60
vr41xx_giu_add(void)61 static int __init vr41xx_giu_add(void)
62 {
63 struct platform_device *pdev;
64 struct resource *res;
65 unsigned int num;
66 int retval;
67
68 pdev = platform_device_alloc("GIU", -1);
69 if (!pdev)
70 return -ENOMEM;
71
72 switch (current_cpu_type()) {
73 case CPU_VR4111:
74 case CPU_VR4121:
75 pdev->id = GPIO_50PINS_PULLUPDOWN;
76 res = giu_50pins_pullupdown_resource;
77 num = ARRAY_SIZE(giu_50pins_pullupdown_resource);
78 break;
79 case CPU_VR4122:
80 case CPU_VR4131:
81 pdev->id = GPIO_36PINS;
82 res = giu_36pins_resource;
83 num = ARRAY_SIZE(giu_36pins_resource);
84 break;
85 case CPU_VR4133:
86 pdev->id = GPIO_48PINS_EDGE_SELECT;
87 res = giu_48pins_resource;
88 num = ARRAY_SIZE(giu_48pins_resource);
89 break;
90 default:
91 retval = -ENODEV;
92 goto err_free_device;
93 }
94
95 retval = platform_device_add_resources(pdev, res, num);
96 if (retval)
97 goto err_free_device;
98
99 retval = platform_device_add(pdev);
100 if (retval)
101 goto err_free_device;
102
103 return 0;
104
105 err_free_device:
106 platform_device_put(pdev);
107
108 return retval;
109 }
110 device_initcall(vr41xx_giu_add);
111