1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Copyright (C) 2016 Linaro.
4 * Viresh Kumar <viresh.kumar@linaro.org>
5 */
6
7 #include <linux/err.h>
8 #include <linux/of.h>
9 #include <linux/of_device.h>
10 #include <linux/platform_device.h>
11
12 #include "cpufreq-dt.h"
13
14 /*
15 * Machines for which the cpufreq device is *always* created, mostly used for
16 * platforms using "operating-points" (V1) property.
17 */
18 static const struct of_device_id whitelist[] __initconst = {{
19 .compatible = "allwinner,sun4i-a10",
20 },
21 {
22 .compatible = "allwinner,sun5i-a10s",
23 },
24 {
25 .compatible = "allwinner,sun5i-a13",
26 },
27 {
28 .compatible = "allwinner,sun5i-r8",
29 },
30 {
31 .compatible = "allwinner,sun6i-a31",
32 },
33 {
34 .compatible = "allwinner,sun6i-a31s",
35 },
36 {
37 .compatible = "allwinner,sun7i-a20",
38 },
39 {
40 .compatible = "allwinner,sun8i-a23",
41 },
42 {
43 .compatible = "allwinner,sun8i-a83t",
44 },
45 {
46 .compatible = "allwinner,sun8i-h3",
47 },
48
49 {
50 .compatible = "apm,xgene-shadowcat",
51 },
52
53 {
54 .compatible = "arm,integrator-ap",
55 },
56 {
57 .compatible = "arm,integrator-cp",
58 },
59
60 {
61 .compatible = "hisilicon,hi3660",
62 },
63
64 {
65 .compatible = "fsl,imx27",
66 },
67 {
68 .compatible = "fsl,imx51",
69 },
70 {
71 .compatible = "fsl,imx53",
72 },
73
74 {
75 .compatible = "marvell,berlin",
76 },
77 {
78 .compatible = "marvell,pxa250",
79 },
80 {
81 .compatible = "marvell,pxa270",
82 },
83
84 {
85 .compatible = "samsung,exynos3250",
86 },
87 {
88 .compatible = "samsung,exynos4210",
89 },
90 {
91 .compatible = "samsung,exynos5250",
92 },
93 #ifndef CONFIG_BL_SWITCHER
94 {
95 .compatible = "samsung,exynos5800",
96 },
97 #endif
98
99 {
100 .compatible = "renesas,emev2",
101 },
102 {
103 .compatible = "renesas,r7s72100",
104 },
105 {
106 .compatible = "renesas,r8a73a4",
107 },
108 {
109 .compatible = "renesas,r8a7740",
110 },
111 {
112 .compatible = "renesas,r8a7742",
113 },
114 {
115 .compatible = "renesas,r8a7743",
116 },
117 {
118 .compatible = "renesas,r8a7744",
119 },
120 {
121 .compatible = "renesas,r8a7745",
122 },
123 {
124 .compatible = "renesas,r8a7778",
125 },
126 {
127 .compatible = "renesas,r8a7779",
128 },
129 {
130 .compatible = "renesas,r8a7790",
131 },
132 {
133 .compatible = "renesas,r8a7791",
134 },
135 {
136 .compatible = "renesas,r8a7792",
137 },
138 {
139 .compatible = "renesas,r8a7793",
140 },
141 {
142 .compatible = "renesas,r8a7794",
143 },
144 {
145 .compatible = "renesas,sh73a0",
146 },
147
148 {
149 .compatible = "st-ericsson,u8500",
150 },
151 {
152 .compatible = "st-ericsson,u8540",
153 },
154 {
155 .compatible = "st-ericsson,u9500",
156 },
157 {
158 .compatible = "st-ericsson,u9540",
159 },
160
161 {
162 .compatible = "ti,omap2",
163 },
164 {
165 .compatible = "ti,omap4",
166 },
167 {
168 .compatible = "ti,omap5",
169 },
170
171 {
172 .compatible = "xlnx,zynq-7000",
173 },
174 {
175 .compatible = "xlnx,zynqmp",
176 },
177
178 {}};
179
180 /*
181 * Machines for which the cpufreq device is *not* created, mostly used for
182 * platforms using "operating-points-v2" property.
183 */
184 static const struct of_device_id blacklist[] __initconst = {{
185 .compatible = "allwinner,sun50i-h6",
186 },
187
188 {
189 .compatible = "arm,vexpress",
190 },
191
192 {
193 .compatible = "calxeda,highbank",
194 },
195 {
196 .compatible = "calxeda,ecx-2000",
197 },
198
199 {
200 .compatible = "fsl,imx7ulp",
201 },
202 {
203 .compatible = "fsl,imx7d",
204 },
205 {
206 .compatible = "fsl,imx8mq",
207 },
208 {
209 .compatible = "fsl,imx8mm",
210 },
211 {
212 .compatible = "fsl,imx8mn",
213 },
214 {
215 .compatible = "fsl,imx8mp",
216 },
217
218 {
219 .compatible = "marvell,armadaxp",
220 },
221
222 {
223 .compatible = "mediatek,mt2701",
224 },
225 {
226 .compatible = "mediatek,mt2712",
227 },
228 {
229 .compatible = "mediatek,mt7622",
230 },
231 {
232 .compatible = "mediatek,mt7623",
233 },
234 {
235 .compatible = "mediatek,mt817x",
236 },
237 {
238 .compatible = "mediatek,mt8173",
239 },
240 {
241 .compatible = "mediatek,mt8176",
242 },
243 {
244 .compatible = "mediatek,mt8183",
245 },
246
247 {
248 .compatible = "nvidia,tegra20",
249 },
250 {
251 .compatible = "nvidia,tegra30",
252 },
253 {
254 .compatible = "nvidia,tegra124",
255 },
256 {
257 .compatible = "nvidia,tegra210",
258 },
259
260 {
261 .compatible = "qcom,apq8096",
262 },
263 {
264 .compatible = "qcom,msm8996",
265 },
266 {
267 .compatible = "qcom,qcs404",
268 },
269 {
270 .compatible = "qcom,sc7180",
271 },
272 {
273 .compatible = "qcom,sdm845",
274 },
275 {
276 .compatible = "qcom,sm8150",
277 },
278 {
279 .compatible = "rockchip,px30",
280 },
281 {
282 .compatible = "rockchip,rk2928",
283 },
284 {
285 .compatible = "rockchip,rk3036",
286 },
287 {
288 .compatible = "rockchip,rk3066a",
289 },
290 {
291 .compatible = "rockchip,rk3066b",
292 },
293 {
294 .compatible = "rockchip,rk3126",
295 },
296 {
297 .compatible = "rockchip,rk3128",
298 },
299 {
300 .compatible = "rockchip,rk3188",
301 },
302 {
303 .compatible = "rockchip,rk3228",
304 },
305 {
306 .compatible = "rockchip,rk3229",
307 },
308 {
309 .compatible = "rockchip,rk3288",
310 },
311 {
312 .compatible = "rockchip,rk3288w",
313 },
314 {
315 .compatible = "rockchip,rk3326",
316 },
317 {
318 .compatible = "rockchip,rk3328",
319 },
320 {
321 .compatible = "rockchip,rk3366",
322 },
323 {
324 .compatible = "rockchip,rk3368",
325 },
326 {
327 .compatible = "rockchip,rk3399",
328 },
329 {
330 .compatible = "rockchip,rk3399pro",
331 },
332 {
333 .compatible = "rockchip,rk3566",
334 },
335 {
336 .compatible = "rockchip,rk3568",
337 },
338 {
339 .compatible = "rockchip,rv1109",
340 },
341 {
342 .compatible = "rockchip,rv1126",
343 },
344
345 {
346 .compatible = "st,stih407",
347 },
348 {
349 .compatible = "st,stih410",
350 },
351 {
352 .compatible = "st,stih418",
353 },
354
355 {
356 .compatible = "sigma,tango4",
357 },
358
359 {
360 .compatible = "ti,am33xx",
361 },
362 {
363 .compatible = "ti,am43",
364 },
365 {
366 .compatible = "ti,dra7",
367 },
368 {
369 .compatible = "ti,omap3",
370 },
371
372 {
373 .compatible = "qcom,ipq8064",
374 },
375 {
376 .compatible = "qcom,apq8064",
377 },
378 {
379 .compatible = "qcom,msm8974",
380 },
381 {
382 .compatible = "qcom,msm8960",
383 },
384
385 {}};
386
cpu0_node_has_opp_v2_prop(void)387 static bool __init cpu0_node_has_opp_v2_prop(void)
388 {
389 struct device_node *np = of_cpu_device_node_get(0);
390 bool ret = false;
391
392 if (of_get_property(np, "operating-points-v2", NULL)) {
393 ret = true;
394 }
395
396 of_node_put(np);
397 return ret;
398 }
399
cpufreq_dt_platdev_init(void)400 static int __init cpufreq_dt_platdev_init(void)
401 {
402 struct device_node *np = of_find_node_by_path("/");
403 const struct of_device_id *match;
404 const void *data = NULL;
405
406 if (!np) {
407 return -ENODEV;
408 }
409
410 match = of_match_node(whitelist, np);
411 if (match) {
412 data = match->data;
413 goto create_pdev;
414 }
415
416 if (cpu0_node_has_opp_v2_prop() && !of_match_node(blacklist, np)) {
417 goto create_pdev;
418 }
419
420 of_node_put(np);
421 return -ENODEV;
422
423 create_pdev:
424 of_node_put(np);
425 return PTR_ERR_OR_ZERO(
426 platform_device_register_data(NULL, "cpufreq-dt", -1, data, sizeof(struct cpufreq_dt_platform_data)));
427 }
428 core_initcall(cpufreq_dt_platdev_init);
429