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 resource dec_dz_resources[] = {
42 { .name = "dz", .flags = IORESOURCE_MEM, },
43 { .name = "dz", .flags = IORESOURCE_IRQ, },
44 };
45
46 static struct platform_device dec_dz_device = {
47 .name = "dz",
48 .id = PLATFORM_DEVID_NONE,
49 .resource = dec_dz_resources,
50 .num_resources = ARRAY_SIZE(dec_dz_resources),
51 };
52
53 static struct platform_device *dec_dz_devices[] __initdata = {
54 &dec_dz_device,
55 };
56
57 static struct resource dec_zs_resources[][2] = {
58 {
59 { .name = "scc0", .flags = IORESOURCE_MEM, },
60 { .name = "scc0", .flags = IORESOURCE_IRQ, },
61 },
62 {
63 { .name = "scc1", .flags = IORESOURCE_MEM, },
64 { .name = "scc1", .flags = IORESOURCE_IRQ, },
65 },
66 };
67
68 static struct platform_device dec_zs_device[] = {
69 {
70 .name = "zs",
71 .id = 0,
72 .resource = dec_zs_resources[0],
73 .num_resources = ARRAY_SIZE(dec_zs_resources[0]),
74 },
75 {
76 .name = "zs",
77 .id = 1,
78 .resource = dec_zs_resources[1],
79 .num_resources = ARRAY_SIZE(dec_zs_resources[1]),
80 },
81 };
82
dec_add_devices(void)83 static int __init dec_add_devices(void)
84 {
85 struct platform_device *dec_zs_devices[ARRAY_SIZE(dec_zs_device)];
86 int ret1, ret2, ret3;
87 int num_dz, num_zs;
88 int irq, i;
89
90 dec_rtc_resources[0].start = RTC_PORT(0);
91 dec_rtc_resources[0].end = RTC_PORT(0) + dec_kn_slot_size - 1;
92
93 i = 0;
94 irq = dec_interrupt[DEC_IRQ_DZ11];
95 if (IS_ENABLED(CONFIG_32BIT) && irq >= 0) {
96 resource_size_t base;
97
98 switch (mips_machtype) {
99 case MACH_DS23100:
100 case MACH_DS5100:
101 base = dec_kn_slot_base + KN01_DZ11;
102 break;
103 default:
104 base = dec_kn_slot_base + KN02_DZ11;
105 break;
106 }
107 dec_dz_device.resource[0].start = base;
108 dec_dz_device.resource[0].end = base + dec_kn_slot_size - 1;
109 dec_dz_device.resource[1].start = irq;
110 dec_dz_device.resource[1].end = irq;
111 i++;
112 }
113 num_dz = i;
114
115 i = 0;
116 irq = dec_interrupt[DEC_IRQ_SCC0];
117 if (irq >= 0) {
118 resource_size_t base = dec_kn_slot_base + IOASIC_SCC0;
119
120 dec_zs_device[i].resource[0].start = base;
121 dec_zs_device[i].resource[0].end = base + dec_kn_slot_size - 1;
122 dec_zs_device[i].resource[1].start = irq;
123 dec_zs_device[i].resource[1].end = irq;
124 dec_zs_devices[i] = &dec_zs_device[i];
125 i++;
126 }
127 irq = dec_interrupt[DEC_IRQ_SCC1];
128 if (irq >= 0) {
129 resource_size_t base = dec_kn_slot_base + IOASIC_SCC1;
130
131 dec_zs_device[i].resource[0].start = base;
132 dec_zs_device[i].resource[0].end = base + dec_kn_slot_size - 1;
133 dec_zs_device[i].resource[1].start = irq;
134 dec_zs_device[i].resource[1].end = irq;
135 dec_zs_devices[i] = &dec_zs_device[i];
136 i++;
137 }
138 num_zs = i;
139
140 ret1 = platform_device_register(&dec_rtc_device);
141 ret2 = IS_ENABLED(CONFIG_32BIT) ?
142 platform_add_devices(dec_dz_devices, num_dz) : 0;
143 ret3 = platform_add_devices(dec_zs_devices, num_zs);
144 return ret1 ? ret1 : ret2 ? ret2 : ret3;
145 }
146
147 device_initcall(dec_add_devices);
148