1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * Copyright (C) 2015 Atmel |
4 | * |
5 | * Alexandre Belloni <alexandre.belloni@free-electrons.com |
6 | * Boris Brezillon <boris.brezillon@free-electrons.com |
7 | */ |
8 | |
9 | #define pr_fmt(fmt) "AT91: " fmt |
10 | |
11 | #include <linux/io.h> |
12 | #include <linux/of.h> |
13 | #include <linux/of_address.h> |
14 | #include <linux/of_platform.h> |
15 | #include <linux/slab.h> |
16 | #include <linux/sys_soc.h> |
17 | |
18 | #include "soc.h" |
19 | |
20 | #define AT91_DBGU_CIDR 0x40 |
21 | #define AT91_DBGU_EXID 0x44 |
22 | #define AT91_CHIPID_CIDR 0x00 |
23 | #define AT91_CHIPID_EXID 0x04 |
24 | #define AT91_CIDR_VERSION(x, m) ((x) & (m)) |
25 | #define AT91_CIDR_VERSION_MASK GENMASK(4, 0) |
26 | #define AT91_CIDR_VERSION_MASK_SAMA7G5 GENMASK(3, 0) |
27 | #define AT91_CIDR_EXT BIT(31) |
28 | #define AT91_CIDR_MATCH_MASK GENMASK(30, 5) |
29 | #define AT91_CIDR_MASK_SAMA7G5 GENMASK(27, 5) |
30 | |
31 | static const struct at91_soc socs[] __initconst = { |
32 | #ifdef CONFIG_SOC_AT91RM9200 |
33 | AT91_SOC(AT91RM9200_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
34 | AT91_CIDR_VERSION_MASK, 0, "at91rm9200 BGA" , "at91rm9200" ), |
35 | #endif |
36 | #ifdef CONFIG_SOC_AT91SAM9 |
37 | AT91_SOC(AT91SAM9260_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
38 | AT91_CIDR_VERSION_MASK, 0, "at91sam9260" , NULL), |
39 | AT91_SOC(AT91SAM9261_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
40 | AT91_CIDR_VERSION_MASK, 0, "at91sam9261" , NULL), |
41 | AT91_SOC(AT91SAM9263_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
42 | AT91_CIDR_VERSION_MASK, 0, "at91sam9263" , NULL), |
43 | AT91_SOC(AT91SAM9G20_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
44 | AT91_CIDR_VERSION_MASK, 0, "at91sam9g20" , NULL), |
45 | AT91_SOC(AT91SAM9RL64_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
46 | AT91_CIDR_VERSION_MASK, 0, "at91sam9rl64" , NULL), |
47 | AT91_SOC(AT91SAM9G45_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
48 | AT91_CIDR_VERSION_MASK, AT91SAM9M11_EXID_MATCH, |
49 | "at91sam9m11" , "at91sam9g45" ), |
50 | AT91_SOC(AT91SAM9G45_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
51 | AT91_CIDR_VERSION_MASK, AT91SAM9M10_EXID_MATCH, |
52 | "at91sam9m10" , "at91sam9g45" ), |
53 | AT91_SOC(AT91SAM9G45_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
54 | AT91_CIDR_VERSION_MASK, AT91SAM9G46_EXID_MATCH, |
55 | "at91sam9g46" , "at91sam9g45" ), |
56 | AT91_SOC(AT91SAM9G45_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
57 | AT91_CIDR_VERSION_MASK, AT91SAM9G45_EXID_MATCH, |
58 | "at91sam9g45" , "at91sam9g45" ), |
59 | AT91_SOC(AT91SAM9X5_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
60 | AT91_CIDR_VERSION_MASK, AT91SAM9G15_EXID_MATCH, |
61 | "at91sam9g15" , "at91sam9x5" ), |
62 | AT91_SOC(AT91SAM9X5_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
63 | AT91_CIDR_VERSION_MASK, AT91SAM9G35_EXID_MATCH, |
64 | "at91sam9g35" , "at91sam9x5" ), |
65 | AT91_SOC(AT91SAM9X5_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
66 | AT91_CIDR_VERSION_MASK, AT91SAM9X35_EXID_MATCH, |
67 | "at91sam9x35" , "at91sam9x5" ), |
68 | AT91_SOC(AT91SAM9X5_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
69 | AT91_CIDR_VERSION_MASK, AT91SAM9G25_EXID_MATCH, |
70 | "at91sam9g25" , "at91sam9x5" ), |
71 | AT91_SOC(AT91SAM9X5_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
72 | AT91_CIDR_VERSION_MASK, AT91SAM9X25_EXID_MATCH, |
73 | "at91sam9x25" , "at91sam9x5" ), |
74 | AT91_SOC(AT91SAM9N12_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
75 | AT91_CIDR_VERSION_MASK, AT91SAM9CN12_EXID_MATCH, |
76 | "at91sam9cn12" , "at91sam9n12" ), |
77 | AT91_SOC(AT91SAM9N12_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
78 | AT91_CIDR_VERSION_MASK, AT91SAM9N12_EXID_MATCH, |
79 | "at91sam9n12" , "at91sam9n12" ), |
80 | AT91_SOC(AT91SAM9N12_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
81 | AT91_CIDR_VERSION_MASK, AT91SAM9CN11_EXID_MATCH, |
82 | "at91sam9cn11" , "at91sam9n12" ), |
83 | AT91_SOC(AT91SAM9XE128_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
84 | AT91_CIDR_VERSION_MASK, 0, "at91sam9xe128" , "at91sam9xe128" ), |
85 | AT91_SOC(AT91SAM9XE256_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
86 | AT91_CIDR_VERSION_MASK, 0, "at91sam9xe256" , "at91sam9xe256" ), |
87 | AT91_SOC(AT91SAM9XE512_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
88 | AT91_CIDR_VERSION_MASK, 0, "at91sam9xe512" , "at91sam9xe512" ), |
89 | #endif |
90 | #ifdef CONFIG_SOC_SAM9X60 |
91 | AT91_SOC(SAM9X60_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
92 | AT91_CIDR_VERSION_MASK, SAM9X60_EXID_MATCH, |
93 | "sam9x60" , "sam9x60" ), |
94 | AT91_SOC(SAM9X60_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
95 | AT91_CIDR_VERSION_MASK, SAM9X60_D5M_EXID_MATCH, |
96 | "sam9x60 64MiB DDR2 SiP" , "sam9x60" ), |
97 | AT91_SOC(SAM9X60_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
98 | AT91_CIDR_VERSION_MASK, SAM9X60_D1G_EXID_MATCH, |
99 | "sam9x60 128MiB DDR2 SiP" , "sam9x60" ), |
100 | AT91_SOC(SAM9X60_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
101 | AT91_CIDR_VERSION_MASK, SAM9X60_D6K_EXID_MATCH, |
102 | "sam9x60 8MiB SDRAM SiP" , "sam9x60" ), |
103 | #endif |
104 | #ifdef CONFIG_SOC_SAMA5 |
105 | AT91_SOC(SAMA5D2_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
106 | AT91_CIDR_VERSION_MASK, SAMA5D21CU_EXID_MATCH, |
107 | "sama5d21" , "sama5d2" ), |
108 | AT91_SOC(SAMA5D2_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
109 | AT91_CIDR_VERSION_MASK, SAMA5D22CU_EXID_MATCH, |
110 | "sama5d22" , "sama5d2" ), |
111 | AT91_SOC(SAMA5D2_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
112 | AT91_CIDR_VERSION_MASK, SAMA5D225C_D1M_EXID_MATCH, |
113 | "sama5d225c 16MiB SiP" , "sama5d2" ), |
114 | AT91_SOC(SAMA5D2_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
115 | AT91_CIDR_VERSION_MASK, SAMA5D23CU_EXID_MATCH, |
116 | "sama5d23" , "sama5d2" ), |
117 | AT91_SOC(SAMA5D2_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
118 | AT91_CIDR_VERSION_MASK, SAMA5D24CX_EXID_MATCH, |
119 | "sama5d24" , "sama5d2" ), |
120 | AT91_SOC(SAMA5D2_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
121 | AT91_CIDR_VERSION_MASK, SAMA5D24CU_EXID_MATCH, |
122 | "sama5d24" , "sama5d2" ), |
123 | AT91_SOC(SAMA5D2_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
124 | AT91_CIDR_VERSION_MASK, SAMA5D26CU_EXID_MATCH, |
125 | "sama5d26" , "sama5d2" ), |
126 | AT91_SOC(SAMA5D2_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
127 | AT91_CIDR_VERSION_MASK, SAMA5D27CU_EXID_MATCH, |
128 | "sama5d27" , "sama5d2" ), |
129 | AT91_SOC(SAMA5D2_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
130 | AT91_CIDR_VERSION_MASK, SAMA5D27CN_EXID_MATCH, |
131 | "sama5d27" , "sama5d2" ), |
132 | AT91_SOC(SAMA5D2_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
133 | AT91_CIDR_VERSION_MASK, SAMA5D27C_D1G_EXID_MATCH, |
134 | "sama5d27c 128MiB SiP" , "sama5d2" ), |
135 | AT91_SOC(SAMA5D2_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
136 | AT91_CIDR_VERSION_MASK, SAMA5D27C_D5M_EXID_MATCH, |
137 | "sama5d27c 64MiB SiP" , "sama5d2" ), |
138 | AT91_SOC(SAMA5D2_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
139 | AT91_CIDR_VERSION_MASK, SAMA5D27C_LD1G_EXID_MATCH, |
140 | "sama5d27c 128MiB LPDDR2 SiP" , "sama5d2" ), |
141 | AT91_SOC(SAMA5D2_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
142 | AT91_CIDR_VERSION_MASK, SAMA5D27C_LD2G_EXID_MATCH, |
143 | "sama5d27c 256MiB LPDDR2 SiP" , "sama5d2" ), |
144 | AT91_SOC(SAMA5D2_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
145 | AT91_CIDR_VERSION_MASK, SAMA5D28CU_EXID_MATCH, |
146 | "sama5d28" , "sama5d2" ), |
147 | AT91_SOC(SAMA5D2_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
148 | AT91_CIDR_VERSION_MASK, SAMA5D28CN_EXID_MATCH, |
149 | "sama5d28" , "sama5d2" ), |
150 | AT91_SOC(SAMA5D2_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
151 | AT91_CIDR_VERSION_MASK, SAMA5D28C_D1G_EXID_MATCH, |
152 | "sama5d28c 128MiB SiP" , "sama5d2" ), |
153 | AT91_SOC(SAMA5D2_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
154 | AT91_CIDR_VERSION_MASK, SAMA5D28C_LD1G_EXID_MATCH, |
155 | "sama5d28c 128MiB LPDDR2 SiP" , "sama5d2" ), |
156 | AT91_SOC(SAMA5D2_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
157 | AT91_CIDR_VERSION_MASK, SAMA5D28C_LD2G_EXID_MATCH, |
158 | "sama5d28c 256MiB LPDDR2 SiP" , "sama5d2" ), |
159 | AT91_SOC(SAMA5D2_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
160 | AT91_CIDR_VERSION_MASK, SAMA5D29CN_EXID_MATCH, |
161 | "sama5d29" , "sama5d2" ), |
162 | AT91_SOC(SAMA5D3_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
163 | AT91_CIDR_VERSION_MASK, SAMA5D31_EXID_MATCH, |
164 | "sama5d31" , "sama5d3" ), |
165 | AT91_SOC(SAMA5D3_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
166 | AT91_CIDR_VERSION_MASK, SAMA5D33_EXID_MATCH, |
167 | "sama5d33" , "sama5d3" ), |
168 | AT91_SOC(SAMA5D3_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
169 | AT91_CIDR_VERSION_MASK, SAMA5D34_EXID_MATCH, |
170 | "sama5d34" , "sama5d3" ), |
171 | AT91_SOC(SAMA5D3_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
172 | AT91_CIDR_VERSION_MASK, SAMA5D35_EXID_MATCH, |
173 | "sama5d35" , "sama5d3" ), |
174 | AT91_SOC(SAMA5D3_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
175 | AT91_CIDR_VERSION_MASK, SAMA5D36_EXID_MATCH, |
176 | "sama5d36" , "sama5d3" ), |
177 | AT91_SOC(SAMA5D4_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
178 | AT91_CIDR_VERSION_MASK, SAMA5D41_EXID_MATCH, |
179 | "sama5d41" , "sama5d4" ), |
180 | AT91_SOC(SAMA5D4_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
181 | AT91_CIDR_VERSION_MASK, SAMA5D42_EXID_MATCH, |
182 | "sama5d42" , "sama5d4" ), |
183 | AT91_SOC(SAMA5D4_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
184 | AT91_CIDR_VERSION_MASK, SAMA5D43_EXID_MATCH, |
185 | "sama5d43" , "sama5d4" ), |
186 | AT91_SOC(SAMA5D4_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
187 | AT91_CIDR_VERSION_MASK, SAMA5D44_EXID_MATCH, |
188 | "sama5d44" , "sama5d4" ), |
189 | #endif |
190 | #ifdef CONFIG_SOC_SAMV7 |
191 | AT91_SOC(SAME70Q21_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
192 | AT91_CIDR_VERSION_MASK, SAME70Q21_EXID_MATCH, |
193 | "same70q21" , "same7" ), |
194 | AT91_SOC(SAME70Q20_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
195 | AT91_CIDR_VERSION_MASK, SAME70Q20_EXID_MATCH, |
196 | "same70q20" , "same7" ), |
197 | AT91_SOC(SAME70Q19_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
198 | AT91_CIDR_VERSION_MASK, SAME70Q19_EXID_MATCH, |
199 | "same70q19" , "same7" ), |
200 | AT91_SOC(SAMS70Q21_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
201 | AT91_CIDR_VERSION_MASK, SAMS70Q21_EXID_MATCH, |
202 | "sams70q21" , "sams7" ), |
203 | AT91_SOC(SAMS70Q20_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
204 | AT91_CIDR_VERSION_MASK, SAMS70Q20_EXID_MATCH, |
205 | "sams70q20" , "sams7" ), |
206 | AT91_SOC(SAMS70Q19_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
207 | AT91_CIDR_VERSION_MASK, SAMS70Q19_EXID_MATCH, |
208 | "sams70q19" , "sams7" ), |
209 | AT91_SOC(SAMV71Q21_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
210 | AT91_CIDR_VERSION_MASK, SAMV71Q21_EXID_MATCH, |
211 | "samv71q21" , "samv7" ), |
212 | AT91_SOC(SAMV71Q20_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
213 | AT91_CIDR_VERSION_MASK, SAMV71Q20_EXID_MATCH, |
214 | "samv71q20" , "samv7" ), |
215 | AT91_SOC(SAMV71Q19_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
216 | AT91_CIDR_VERSION_MASK, SAMV71Q19_EXID_MATCH, |
217 | "samv71q19" , "samv7" ), |
218 | AT91_SOC(SAMV70Q20_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
219 | AT91_CIDR_VERSION_MASK, SAMV70Q20_EXID_MATCH, |
220 | "samv70q20" , "samv7" ), |
221 | AT91_SOC(SAMV70Q19_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
222 | AT91_CIDR_VERSION_MASK, SAMV70Q19_EXID_MATCH, |
223 | "samv70q19" , "samv7" ), |
224 | #endif |
225 | #ifdef CONFIG_SOC_SAMA7 |
226 | AT91_SOC(SAMA7G5_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
227 | AT91_CIDR_VERSION_MASK_SAMA7G5, SAMA7G51_EXID_MATCH, |
228 | "sama7g51" , "sama7g5" ), |
229 | AT91_SOC(SAMA7G5_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
230 | AT91_CIDR_VERSION_MASK_SAMA7G5, SAMA7G52_EXID_MATCH, |
231 | "sama7g52" , "sama7g5" ), |
232 | AT91_SOC(SAMA7G5_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
233 | AT91_CIDR_VERSION_MASK_SAMA7G5, SAMA7G53_EXID_MATCH, |
234 | "sama7g53" , "sama7g5" ), |
235 | AT91_SOC(SAMA7G5_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
236 | AT91_CIDR_VERSION_MASK_SAMA7G5, SAMA7G54_EXID_MATCH, |
237 | "sama7g54" , "sama7g5" ), |
238 | AT91_SOC(SAMA7G5_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
239 | AT91_CIDR_VERSION_MASK_SAMA7G5, SAMA7G54_D1G_EXID_MATCH, |
240 | "SAMA7G54 1Gb DDR3L SiP" , "sama7g5" ), |
241 | AT91_SOC(SAMA7G5_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
242 | AT91_CIDR_VERSION_MASK_SAMA7G5, SAMA7G54_D2G_EXID_MATCH, |
243 | "SAMA7G54 2Gb DDR3L SiP" , "sama7g5" ), |
244 | AT91_SOC(SAMA7G5_CIDR_MATCH, AT91_CIDR_MATCH_MASK, |
245 | AT91_CIDR_VERSION_MASK_SAMA7G5, SAMA7G54_D4G_EXID_MATCH, |
246 | "SAMA7G54 4Gb DDR3L SiP" , "sama7g5" ), |
247 | #endif |
248 | { /* sentinel */ }, |
249 | }; |
250 | |
251 | static int __init at91_get_cidr_exid_from_dbgu(u32 *cidr, u32 *exid) |
252 | { |
253 | struct device_node *np; |
254 | void __iomem *regs; |
255 | |
256 | np = of_find_compatible_node(NULL, NULL, compat: "atmel,at91rm9200-dbgu" ); |
257 | if (!np) |
258 | np = of_find_compatible_node(NULL, NULL, |
259 | compat: "atmel,at91sam9260-dbgu" ); |
260 | if (!np) |
261 | return -ENODEV; |
262 | |
263 | regs = of_iomap(node: np, index: 0); |
264 | of_node_put(node: np); |
265 | |
266 | if (!regs) { |
267 | pr_warn("Could not map DBGU iomem range" ); |
268 | return -ENXIO; |
269 | } |
270 | |
271 | *cidr = readl(addr: regs + AT91_DBGU_CIDR); |
272 | *exid = readl(addr: regs + AT91_DBGU_EXID); |
273 | |
274 | iounmap(addr: regs); |
275 | |
276 | return 0; |
277 | } |
278 | |
279 | static int __init at91_get_cidr_exid_from_chipid(u32 *cidr, u32 *exid) |
280 | { |
281 | struct device_node *np; |
282 | void __iomem *regs; |
283 | static const struct of_device_id chipids[] = { |
284 | { .compatible = "atmel,sama5d2-chipid" }, |
285 | { .compatible = "microchip,sama7g5-chipid" }, |
286 | { }, |
287 | }; |
288 | |
289 | np = of_find_matching_node(NULL, matches: chipids); |
290 | if (!np) |
291 | return -ENODEV; |
292 | |
293 | regs = of_iomap(node: np, index: 0); |
294 | of_node_put(node: np); |
295 | |
296 | if (!regs) { |
297 | pr_warn("Could not map DBGU iomem range" ); |
298 | return -ENXIO; |
299 | } |
300 | |
301 | *cidr = readl(addr: regs + AT91_CHIPID_CIDR); |
302 | *exid = readl(addr: regs + AT91_CHIPID_EXID); |
303 | |
304 | iounmap(addr: regs); |
305 | |
306 | return 0; |
307 | } |
308 | |
309 | struct soc_device * __init at91_soc_init(const struct at91_soc *socs) |
310 | { |
311 | struct soc_device_attribute *soc_dev_attr; |
312 | const struct at91_soc *soc; |
313 | struct soc_device *soc_dev; |
314 | u32 cidr, exid; |
315 | int ret; |
316 | |
317 | /* |
318 | * With SAMA5D2 and later SoCs, CIDR and EXID registers are no more |
319 | * in the dbgu device but in the chipid device whose purpose is only |
320 | * to expose these two registers. |
321 | */ |
322 | ret = at91_get_cidr_exid_from_dbgu(cidr: &cidr, exid: &exid); |
323 | if (ret) |
324 | ret = at91_get_cidr_exid_from_chipid(cidr: &cidr, exid: &exid); |
325 | if (ret) { |
326 | if (ret == -ENODEV) |
327 | pr_warn("Could not find identification node" ); |
328 | return NULL; |
329 | } |
330 | |
331 | for (soc = socs; soc->name; soc++) { |
332 | if (soc->cidr_match != (cidr & soc->cidr_mask)) |
333 | continue; |
334 | |
335 | if (!(cidr & AT91_CIDR_EXT) || soc->exid_match == exid) |
336 | break; |
337 | } |
338 | |
339 | if (!soc->name) { |
340 | pr_warn("Could not find matching SoC description\n" ); |
341 | return NULL; |
342 | } |
343 | |
344 | soc_dev_attr = kzalloc(size: sizeof(*soc_dev_attr), GFP_KERNEL); |
345 | if (!soc_dev_attr) |
346 | return NULL; |
347 | |
348 | soc_dev_attr->family = soc->family; |
349 | soc_dev_attr->soc_id = soc->name; |
350 | soc_dev_attr->revision = kasprintf(GFP_KERNEL, fmt: "%X" , |
351 | AT91_CIDR_VERSION(cidr, soc->version_mask)); |
352 | soc_dev = soc_device_register(soc_plat_dev_attr: soc_dev_attr); |
353 | if (IS_ERR(ptr: soc_dev)) { |
354 | kfree(objp: soc_dev_attr->revision); |
355 | kfree(objp: soc_dev_attr); |
356 | pr_warn("Could not register SoC device\n" ); |
357 | return NULL; |
358 | } |
359 | |
360 | if (soc->family) |
361 | pr_info("Detected SoC family: %s\n" , soc->family); |
362 | pr_info("Detected SoC: %s, revision %X\n" , soc->name, |
363 | AT91_CIDR_VERSION(cidr, soc->version_mask)); |
364 | |
365 | return soc_dev; |
366 | } |
367 | |
368 | static const struct of_device_id at91_soc_allowed_list[] __initconst = { |
369 | { .compatible = "atmel,at91rm9200" , }, |
370 | { .compatible = "atmel,at91sam9" , }, |
371 | { .compatible = "atmel,sama5" , }, |
372 | { .compatible = "atmel,samv7" , }, |
373 | { .compatible = "microchip,sama7g5" , }, |
374 | { } |
375 | }; |
376 | |
377 | static int __init atmel_soc_device_init(void) |
378 | { |
379 | struct device_node *np = of_find_node_by_path(path: "/" ); |
380 | |
381 | if (!of_match_node(matches: at91_soc_allowed_list, node: np)) |
382 | return 0; |
383 | |
384 | at91_soc_init(socs); |
385 | |
386 | return 0; |
387 | } |
388 | subsys_initcall(atmel_soc_device_init); |
389 | |