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/module.h> |
9 | #include <linux/of.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 allowlist[] __initconst = { |
19 | { .compatible = "allwinner,sun4i-a10" , }, |
20 | { .compatible = "allwinner,sun5i-a10s" , }, |
21 | { .compatible = "allwinner,sun5i-a13" , }, |
22 | { .compatible = "allwinner,sun5i-r8" , }, |
23 | { .compatible = "allwinner,sun6i-a31" , }, |
24 | { .compatible = "allwinner,sun6i-a31s" , }, |
25 | { .compatible = "allwinner,sun7i-a20" , }, |
26 | { .compatible = "allwinner,sun8i-a23" , }, |
27 | { .compatible = "allwinner,sun8i-a83t" , }, |
28 | { .compatible = "allwinner,sun8i-h3" , }, |
29 | |
30 | { .compatible = "apm,xgene-shadowcat" , }, |
31 | |
32 | { .compatible = "arm,integrator-ap" , }, |
33 | { .compatible = "arm,integrator-cp" , }, |
34 | |
35 | { .compatible = "hisilicon,hi3660" , }, |
36 | |
37 | { .compatible = "fsl,imx27" , }, |
38 | { .compatible = "fsl,imx51" , }, |
39 | { .compatible = "fsl,imx53" , }, |
40 | |
41 | { .compatible = "marvell,berlin" , }, |
42 | { .compatible = "marvell,pxa250" , }, |
43 | { .compatible = "marvell,pxa270" , }, |
44 | |
45 | { .compatible = "samsung,exynos3250" , }, |
46 | { .compatible = "samsung,exynos4210" , }, |
47 | { .compatible = "samsung,exynos5250" , }, |
48 | #ifndef CONFIG_BL_SWITCHER |
49 | { .compatible = "samsung,exynos5800" , }, |
50 | #endif |
51 | |
52 | { .compatible = "renesas,emev2" , }, |
53 | { .compatible = "renesas,r7s72100" , }, |
54 | { .compatible = "renesas,r8a73a4" , }, |
55 | { .compatible = "renesas,r8a7740" , }, |
56 | { .compatible = "renesas,r8a7742" , }, |
57 | { .compatible = "renesas,r8a7743" , }, |
58 | { .compatible = "renesas,r8a7744" , }, |
59 | { .compatible = "renesas,r8a7745" , }, |
60 | { .compatible = "renesas,r8a7778" , }, |
61 | { .compatible = "renesas,r8a7779" , }, |
62 | { .compatible = "renesas,r8a7790" , }, |
63 | { .compatible = "renesas,r8a7791" , }, |
64 | { .compatible = "renesas,r8a7792" , }, |
65 | { .compatible = "renesas,r8a7793" , }, |
66 | { .compatible = "renesas,r8a7794" , }, |
67 | { .compatible = "renesas,sh73a0" , }, |
68 | |
69 | { .compatible = "rockchip,rk2928" , }, |
70 | { .compatible = "rockchip,rk3036" , }, |
71 | { .compatible = "rockchip,rk3066a" , }, |
72 | { .compatible = "rockchip,rk3066b" , }, |
73 | { .compatible = "rockchip,rk3188" , }, |
74 | { .compatible = "rockchip,rk3228" , }, |
75 | { .compatible = "rockchip,rk3288" , }, |
76 | { .compatible = "rockchip,rk3328" , }, |
77 | { .compatible = "rockchip,rk3366" , }, |
78 | { .compatible = "rockchip,rk3368" , }, |
79 | { .compatible = "rockchip,rk3399" , |
80 | .data = &(struct cpufreq_dt_platform_data) |
81 | { .have_governor_per_policy = true, }, |
82 | }, |
83 | |
84 | { .compatible = "st-ericsson,u8500" , }, |
85 | { .compatible = "st-ericsson,u8540" , }, |
86 | { .compatible = "st-ericsson,u9500" , }, |
87 | { .compatible = "st-ericsson,u9540" , }, |
88 | |
89 | { .compatible = "starfive,jh7110" , }, |
90 | |
91 | { .compatible = "ti,omap2" , }, |
92 | { .compatible = "ti,omap4" , }, |
93 | { .compatible = "ti,omap5" , }, |
94 | |
95 | { .compatible = "xlnx,zynq-7000" , }, |
96 | { .compatible = "xlnx,zynqmp" , }, |
97 | |
98 | { } |
99 | }; |
100 | |
101 | /* |
102 | * Machines for which the cpufreq device is *not* created, mostly used for |
103 | * platforms using "operating-points-v2" property. |
104 | */ |
105 | static const struct of_device_id blocklist[] __initconst = { |
106 | { .compatible = "allwinner,sun50i-h6" , }, |
107 | |
108 | { .compatible = "apple,arm-platform" , }, |
109 | |
110 | { .compatible = "arm,vexpress" , }, |
111 | |
112 | { .compatible = "calxeda,highbank" , }, |
113 | { .compatible = "calxeda,ecx-2000" , }, |
114 | |
115 | { .compatible = "fsl,imx7ulp" , }, |
116 | { .compatible = "fsl,imx7d" , }, |
117 | { .compatible = "fsl,imx7s" , }, |
118 | { .compatible = "fsl,imx8mq" , }, |
119 | { .compatible = "fsl,imx8mm" , }, |
120 | { .compatible = "fsl,imx8mn" , }, |
121 | { .compatible = "fsl,imx8mp" , }, |
122 | |
123 | { .compatible = "marvell,armadaxp" , }, |
124 | |
125 | { .compatible = "mediatek,mt2701" , }, |
126 | { .compatible = "mediatek,mt2712" , }, |
127 | { .compatible = "mediatek,mt7622" , }, |
128 | { .compatible = "mediatek,mt7623" , }, |
129 | { .compatible = "mediatek,mt8167" , }, |
130 | { .compatible = "mediatek,mt817x" , }, |
131 | { .compatible = "mediatek,mt8173" , }, |
132 | { .compatible = "mediatek,mt8176" , }, |
133 | { .compatible = "mediatek,mt8183" , }, |
134 | { .compatible = "mediatek,mt8186" , }, |
135 | { .compatible = "mediatek,mt8365" , }, |
136 | { .compatible = "mediatek,mt8516" , }, |
137 | |
138 | { .compatible = "nvidia,tegra20" , }, |
139 | { .compatible = "nvidia,tegra30" , }, |
140 | { .compatible = "nvidia,tegra124" , }, |
141 | { .compatible = "nvidia,tegra210" , }, |
142 | { .compatible = "nvidia,tegra234" , }, |
143 | |
144 | { .compatible = "qcom,apq8096" , }, |
145 | { .compatible = "qcom,msm8909" , }, |
146 | { .compatible = "qcom,msm8996" , }, |
147 | { .compatible = "qcom,msm8998" , }, |
148 | { .compatible = "qcom,qcm2290" , }, |
149 | { .compatible = "qcom,qcm6490" , }, |
150 | { .compatible = "qcom,qcs404" , }, |
151 | { .compatible = "qcom,qdu1000" , }, |
152 | { .compatible = "qcom,sa8155p" }, |
153 | { .compatible = "qcom,sa8540p" }, |
154 | { .compatible = "qcom,sa8775p" }, |
155 | { .compatible = "qcom,sc7180" , }, |
156 | { .compatible = "qcom,sc7280" , }, |
157 | { .compatible = "qcom,sc8180x" , }, |
158 | { .compatible = "qcom,sc8280xp" , }, |
159 | { .compatible = "qcom,sdm670" , }, |
160 | { .compatible = "qcom,sdm845" , }, |
161 | { .compatible = "qcom,sdx75" , }, |
162 | { .compatible = "qcom,sm6115" , }, |
163 | { .compatible = "qcom,sm6350" , }, |
164 | { .compatible = "qcom,sm6375" , }, |
165 | { .compatible = "qcom,sm7225" , }, |
166 | { .compatible = "qcom,sm8150" , }, |
167 | { .compatible = "qcom,sm8250" , }, |
168 | { .compatible = "qcom,sm8350" , }, |
169 | { .compatible = "qcom,sm8450" , }, |
170 | { .compatible = "qcom,sm8550" , }, |
171 | |
172 | { .compatible = "st,stih407" , }, |
173 | { .compatible = "st,stih410" , }, |
174 | { .compatible = "st,stih418" , }, |
175 | |
176 | { .compatible = "ti,am33xx" , }, |
177 | { .compatible = "ti,am43" , }, |
178 | { .compatible = "ti,dra7" , }, |
179 | { .compatible = "ti,omap3" , }, |
180 | { .compatible = "ti,am625" , }, |
181 | { .compatible = "ti,am62a7" , }, |
182 | { .compatible = "ti,am62p5" , }, |
183 | |
184 | { .compatible = "qcom,ipq5332" , }, |
185 | { .compatible = "qcom,ipq6018" , }, |
186 | { .compatible = "qcom,ipq8064" , }, |
187 | { .compatible = "qcom,ipq8074" , }, |
188 | { .compatible = "qcom,ipq9574" , }, |
189 | { .compatible = "qcom,apq8064" , }, |
190 | { .compatible = "qcom,msm8974" , }, |
191 | { .compatible = "qcom,msm8960" , }, |
192 | |
193 | { } |
194 | }; |
195 | |
196 | static bool __init cpu0_node_has_opp_v2_prop(void) |
197 | { |
198 | struct device_node *np = of_cpu_device_node_get(cpu: 0); |
199 | bool ret = false; |
200 | |
201 | if (of_property_present(np, propname: "operating-points-v2" )) |
202 | ret = true; |
203 | |
204 | of_node_put(node: np); |
205 | return ret; |
206 | } |
207 | |
208 | static int __init cpufreq_dt_platdev_init(void) |
209 | { |
210 | struct device_node *np = of_find_node_by_path(path: "/" ); |
211 | const struct of_device_id *match; |
212 | const void *data = NULL; |
213 | |
214 | if (!np) |
215 | return -ENODEV; |
216 | |
217 | match = of_match_node(matches: allowlist, node: np); |
218 | if (match) { |
219 | data = match->data; |
220 | goto create_pdev; |
221 | } |
222 | |
223 | if (cpu0_node_has_opp_v2_prop() && !of_match_node(matches: blocklist, node: np)) |
224 | goto create_pdev; |
225 | |
226 | of_node_put(node: np); |
227 | return -ENODEV; |
228 | |
229 | create_pdev: |
230 | of_node_put(node: np); |
231 | return PTR_ERR_OR_ZERO(ptr: platform_device_register_data(NULL, name: "cpufreq-dt" , |
232 | id: -1, data, |
233 | size: sizeof(struct cpufreq_dt_platform_data))); |
234 | } |
235 | core_initcall(cpufreq_dt_platdev_init); |
236 | MODULE_LICENSE("GPL" ); |
237 | |