xref: /linux/arch/mips/dec/platform.c (revision ea7da3116015de801840f3e011dee907fb118f0c)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  *	DEC platform devices.
4  *
5  *	Copyright (c) 2014  Maciej W. Rozycki
6  */
7 
8 #include <linux/ioport.h>
9 #include <linux/kernel.h>
10 #include <linux/mc146818rtc.h>
11 #include <linux/platform_device.h>
12 
13 #include <asm/bootinfo.h>
14 
15 #include <asm/dec/interrupts.h>
16 #include <asm/dec/ioasic_addrs.h>
17 #include <asm/dec/kn01.h>
18 #include <asm/dec/kn02.h>
19 #include <asm/dec/system.h>
20 
21 static struct resource dec_rtc_resources[] = {
22 	{
23 		.name = "rtc",
24 		.flags = IORESOURCE_MEM,
25 	},
26 };
27 
28 static struct cmos_rtc_board_info dec_rtc_info = {
29 	.flags = CMOS_RTC_FLAGS_NOFREQ,
30 	.address_space = 64,
31 };
32 
33 static struct platform_device dec_rtc_device = {
34 	.name = "rtc_cmos",
35 	.id = PLATFORM_DEVID_NONE,
36 	.dev.platform_data = &dec_rtc_info,
37 	.resource = dec_rtc_resources,
38 	.num_resources = ARRAY_SIZE(dec_rtc_resources),
39 };
40 
41 static struct platform_device *dec_rtc_devices[] __initdata = {
42 	&dec_rtc_device,
43 };
44 
45 static struct resource dec_dz_resources[] = {
46 	{ .name = "dz", .flags = IORESOURCE_MEM, },
47 	{ .name = "dz", .flags = IORESOURCE_IRQ, },
48 };
49 
50 static struct platform_device dec_dz_device = {
51 	.name = "dz",
52 	.id = PLATFORM_DEVID_NONE,
53 	.resource = dec_dz_resources,
54 	.num_resources = ARRAY_SIZE(dec_dz_resources),
55 };
56 
57 static struct platform_device *dec_dz_devices[] __initdata = {
58 	&dec_dz_device,
59 };
60 
61 static struct resource dec_zs_resources[][2] = {
62 	{
63 		{ .name = "scc0", .flags = IORESOURCE_MEM, },
64 		{ .name = "scc0", .flags = IORESOURCE_IRQ, },
65 	},
66 	{
67 		{ .name = "scc1", .flags = IORESOURCE_MEM, },
68 		{ .name = "scc1", .flags = IORESOURCE_IRQ, },
69 	},
70 };
71 
72 static struct platform_device dec_zs_device[] = {
73 	{
74 		.name = "zs",
75 		.id = 0,
76 		.resource = dec_zs_resources[0],
77 		.num_resources = ARRAY_SIZE(dec_zs_resources[0]),
78 	},
79 	{
80 		.name = "zs",
81 		.id = 1,
82 		.resource = dec_zs_resources[1],
83 		.num_resources = ARRAY_SIZE(dec_zs_resources[1]),
84 	},
85 };
86 
87 static int __init dec_add_devices(void)
88 {
89 	struct platform_device *dec_zs_devices[ARRAY_SIZE(dec_zs_device)];
90 	int ret1, ret2, ret3;
91 	int num_dz, num_zs;
92 	int irq, i;
93 
94 	dec_rtc_resources[0].start = RTC_PORT(0);
95 	dec_rtc_resources[0].end = RTC_PORT(0) + dec_kn_slot_size - 1;
96 
97 	i = 0;
98 	irq = dec_interrupt[DEC_IRQ_DZ11];
99 	if (IS_ENABLED(CONFIG_32BIT) && irq >= 0) {
100 		resource_size_t base;
101 
102 		switch (mips_machtype) {
103 		case MACH_DS23100:
104 		case MACH_DS5100:
105 			base = dec_kn_slot_base + KN01_DZ11;
106 			break;
107 		default:
108 			base = dec_kn_slot_base + KN02_DZ11;
109 			break;
110 		}
111 		dec_dz_device.resource[0].start = base;
112 		dec_dz_device.resource[0].end = base + dec_kn_slot_size - 1;
113 		dec_dz_device.resource[1].start = irq;
114 		dec_dz_device.resource[1].end = irq;
115 		i++;
116 	}
117 	num_dz = i;
118 
119 	i = 0;
120 	irq = dec_interrupt[DEC_IRQ_SCC0];
121 	if (irq >= 0) {
122 		resource_size_t base = dec_kn_slot_base + IOASIC_SCC0;
123 
124 		dec_zs_device[i].resource[0].start = base;
125 		dec_zs_device[i].resource[0].end = base + dec_kn_slot_size - 1;
126 		dec_zs_device[i].resource[1].start = irq;
127 		dec_zs_device[i].resource[1].end = irq;
128 		dec_zs_devices[i] = &dec_zs_device[i];
129 		i++;
130 	}
131 	irq = dec_interrupt[DEC_IRQ_SCC1];
132 	if (irq >= 0) {
133 		resource_size_t base = dec_kn_slot_base + IOASIC_SCC1;
134 
135 		dec_zs_device[i].resource[0].start = base;
136 		dec_zs_device[i].resource[0].end = base + dec_kn_slot_size - 1;
137 		dec_zs_device[i].resource[1].start = irq;
138 		dec_zs_device[i].resource[1].end = irq;
139 		dec_zs_devices[i] = &dec_zs_device[i];
140 		i++;
141 	}
142 	num_zs = i;
143 
144 	ret1 = platform_add_devices(dec_rtc_devices, 1);
145 	ret2 = IS_ENABLED(CONFIG_32BIT) ?
146 	       platform_add_devices(dec_dz_devices, num_dz) : 0;
147 	ret3 = platform_add_devices(dec_zs_devices, num_zs);
148 	return ret1 ? ret1 : ret2 ? ret2 : ret3;
149 }
150 
151 device_initcall(dec_add_devices);
152