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
17static 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
35static 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
48static 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
61static 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
105err_free_device:
106	platform_device_put(pdev);
107
108	return retval;
109}
110device_initcall(vr41xx_giu_add);
111