aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2018-06-04 04:40:57 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2018-06-04 04:40:57 -0400
commite27f84e163d2f03407e046b09a8f26ebd185a87f (patch)
tree6984d128d716e36ea6b6f6a7dfb371acfd1dd26d
parentd9fecca2efea004c617e01b9eb7a36ef407e7b28 (diff)
parent79383539eb2e6fbb913aaa914821444b919a7a29 (diff)
Merge branch 'pm-cpufreq'
* pm-cpufreq: (25 commits) dt-bindings: cpufreq: Document operating-points-v2-kryo-cpu cpufreq: Add Kryo CPU scaling driver cpufreq: Use static SRCU initializer kernel/SRCU: provide a static initializer cpufreq: Fix new policy initialization during limits updates via sysfs cpufreq: tegra20: Wrap cpufreq into platform driver cpufreq: tegra20: Allow cpufreq driver to be built as loadable module cpufreq: tegra20: Check if this is Tegra20 machine cpufreq: tegra20: Remove unneeded variable initialization cpufreq: tegra20: Remove unnecessary parentheses cpufreq: tegra20: Remove unneeded check in tegra_cpu_init cpufreq: tegra20: Release clocks properly cpufreq: tegra20: Remove EMC clock usage cpufreq: tegra20: Clean up included headers cpufreq: tegra20: Clean up whitespaces in the code cpufreq: tegra20: Change module description Revert "cpufreq: rcar: Add support for R8A7795 SoC" Revert "cpufreq: dt: Add r8a7796 support to to use generic cpufreq driver" cpufreq: intel_pstate: allow trace in passive mode cpufreq: optimize cpufreq_notify_transition() ...
-rw-r--r--Documentation/devicetree/bindings/opp/kryo-cpufreq.txt680
-rw-r--r--MAINTAINERS7
-rw-r--r--drivers/cpufreq/Kconfig.arm13
-rw-r--r--drivers/cpufreq/Makefile1
-rw-r--r--drivers/cpufreq/armada-37xx-cpufreq.c100
-rw-r--r--drivers/cpufreq/cpufreq-dt-platdev.c5
-rw-r--r--drivers/cpufreq/cpufreq-dt.c10
-rw-r--r--drivers/cpufreq/cpufreq-dt.h5
-rw-r--r--drivers/cpufreq/cpufreq.c78
-rw-r--r--drivers/cpufreq/intel_pstate.c46
-rw-r--r--drivers/cpufreq/qcom-cpufreq-kryo.c212
-rw-r--r--drivers/cpufreq/s3c2440-cpufreq.c2
-rw-r--r--drivers/cpufreq/speedstep-lib.c2
-rw-r--r--drivers/cpufreq/tegra20-cpufreq.c200
-rw-r--r--include/linux/notifier.h34
-rw-r--r--include/linux/srcutiny.h6
-rw-r--r--include/linux/srcutree.h6
17 files changed, 1241 insertions, 166 deletions
diff --git a/Documentation/devicetree/bindings/opp/kryo-cpufreq.txt b/Documentation/devicetree/bindings/opp/kryo-cpufreq.txt
new file mode 100644
index 000000000000..c2127b96805a
--- /dev/null
+++ b/Documentation/devicetree/bindings/opp/kryo-cpufreq.txt
@@ -0,0 +1,680 @@
1Qualcomm Technologies, Inc. KRYO CPUFreq and OPP bindings
2===================================
3
4In Certain Qualcomm Technologies, Inc. SoCs like apq8096 and msm8996
5that have KRYO processors, the CPU ferequencies subset and voltage value
6of each OPP varies based on the silicon variant in use.
7Qualcomm Technologies, Inc. Process Voltage Scaling Tables
8defines the voltage and frequency value based on the msm-id in SMEM
9and speedbin blown in the efuse combination.
10The qcom-cpufreq-kryo driver reads the msm-id and efuse value from the SoC
11to provide the OPP framework with required information (existing HW bitmap).
12This is used to determine the voltage and frequency value for each OPP of
13operating-points-v2 table when it is parsed by the OPP framework.
14
15Required properties:
16--------------------
17In 'cpus' nodes:
18- operating-points-v2: Phandle to the operating-points-v2 table to use.
19
20In 'operating-points-v2' table:
21- compatible: Should be
22 - 'operating-points-v2-kryo-cpu' for apq8096 and msm8996.
23- nvmem-cells: A phandle pointing to a nvmem-cells node representing the
24 efuse registers that has information about the
25 speedbin that is used to select the right frequency/voltage
26 value pair.
27 Please refer the for nvmem-cells
28 bindings Documentation/devicetree/bindings/nvmem/nvmem.txt
29 and also examples below.
30
31In every OPP node:
32- opp-supported-hw: A single 32 bit bitmap value, representing compatible HW.
33 Bitmap:
34 0: MSM8996 V3, speedbin 0
35 1: MSM8996 V3, speedbin 1
36 2: MSM8996 V3, speedbin 2
37 3: unused
38 4: MSM8996 SG, speedbin 0
39 5: MSM8996 SG, speedbin 1
40 6: MSM8996 SG, speedbin 2
41 7-31: unused
42
43Example 1:
44---------
45
46 cpus {
47 #address-cells = <2>;
48 #size-cells = <0>;
49
50 CPU0: cpu@0 {
51 device_type = "cpu";
52 compatible = "qcom,kryo";
53 reg = <0x0 0x0>;
54 enable-method = "psci";
55 clocks = <&kryocc 0>;
56 cpu-supply = <&pm8994_s11_saw>;
57 operating-points-v2 = <&cluster0_opp>;
58 #cooling-cells = <2>;
59 next-level-cache = <&L2_0>;
60 L2_0: l2-cache {
61 compatible = "cache";
62 cache-level = <2>;
63 };
64 };
65
66 CPU1: cpu@1 {
67 device_type = "cpu";
68 compatible = "qcom,kryo";
69 reg = <0x0 0x1>;
70 enable-method = "psci";
71 clocks = <&kryocc 0>;
72 cpu-supply = <&pm8994_s11_saw>;
73 operating-points-v2 = <&cluster0_opp>;
74 #cooling-cells = <2>;
75 next-level-cache = <&L2_0>;
76 };
77
78 CPU2: cpu@100 {
79 device_type = "cpu";
80 compatible = "qcom,kryo";
81 reg = <0x0 0x100>;
82 enable-method = "psci";
83 clocks = <&kryocc 1>;
84 cpu-supply = <&pm8994_s11_saw>;
85 operating-points-v2 = <&cluster1_opp>;
86 #cooling-cells = <2>;
87 next-level-cache = <&L2_1>;
88 L2_1: l2-cache {
89 compatible = "cache";
90 cache-level = <2>;
91 };
92 };
93
94 CPU3: cpu@101 {
95 device_type = "cpu";
96 compatible = "qcom,kryo";
97 reg = <0x0 0x101>;
98 enable-method = "psci";
99 clocks = <&kryocc 1>;
100 cpu-supply = <&pm8994_s11_saw>;
101 operating-points-v2 = <&cluster1_opp>;
102 #cooling-cells = <2>;
103 next-level-cache = <&L2_1>;
104 };
105
106 cpu-map {
107 cluster0 {
108 core0 {
109 cpu = <&CPU0>;
110 };
111
112 core1 {
113 cpu = <&CPU1>;
114 };
115 };
116
117 cluster1 {
118 core0 {
119 cpu = <&CPU2>;
120 };
121
122 core1 {
123 cpu = <&CPU3>;
124 };
125 };
126 };
127 };
128
129 cluster0_opp: opp_table0 {
130 compatible = "operating-points-v2-kryo-cpu";
131 nvmem-cells = <&speedbin_efuse>;
132 opp-shared;
133
134 opp-307200000 {
135 opp-hz = /bits/ 64 <307200000>;
136 opp-microvolt = <905000 905000 1140000>;
137 opp-supported-hw = <0x77>;
138 clock-latency-ns = <200000>;
139 };
140 opp-384000000 {
141 opp-hz = /bits/ 64 <384000000>;
142 opp-microvolt = <905000 905000 1140000>;
143 opp-supported-hw = <0x70>;
144 clock-latency-ns = <200000>;
145 };
146 opp-422400000 {
147 opp-hz = /bits/ 64 <422400000>;
148 opp-microvolt = <905000 905000 1140000>;
149 opp-supported-hw = <0x7>;
150 clock-latency-ns = <200000>;
151 };
152 opp-460800000 {
153 opp-hz = /bits/ 64 <460800000>;
154 opp-microvolt = <905000 905000 1140000>;
155 opp-supported-hw = <0x70>;
156 clock-latency-ns = <200000>;
157 };
158 opp-480000000 {
159 opp-hz = /bits/ 64 <480000000>;
160 opp-microvolt = <905000 905000 1140000>;
161 opp-supported-hw = <0x7>;
162 clock-latency-ns = <200000>;
163 };
164 opp-537600000 {
165 opp-hz = /bits/ 64 <537600000>;
166 opp-microvolt = <905000 905000 1140000>;
167 opp-supported-hw = <0x70>;
168 clock-latency-ns = <200000>;
169 };
170 opp-556800000 {
171 opp-hz = /bits/ 64 <556800000>;
172 opp-microvolt = <905000 905000 1140000>;
173 opp-supported-hw = <0x7>;
174 clock-latency-ns = <200000>;
175 };
176 opp-614400000 {
177 opp-hz = /bits/ 64 <614400000>;
178 opp-microvolt = <905000 905000 1140000>;
179 opp-supported-hw = <0x70>;
180 clock-latency-ns = <200000>;
181 };
182 opp-652800000 {
183 opp-hz = /bits/ 64 <652800000>;
184 opp-microvolt = <905000 905000 1140000>;
185 opp-supported-hw = <0x7>;
186 clock-latency-ns = <200000>;
187 };
188 opp-691200000 {
189 opp-hz = /bits/ 64 <691200000>;
190 opp-microvolt = <905000 905000 1140000>;
191 opp-supported-hw = <0x70>;
192 clock-latency-ns = <200000>;
193 };
194 opp-729600000 {
195 opp-hz = /bits/ 64 <729600000>;
196 opp-microvolt = <905000 905000 1140000>;
197 opp-supported-hw = <0x7>;
198 clock-latency-ns = <200000>;
199 };
200 opp-768000000 {
201 opp-hz = /bits/ 64 <768000000>;
202 opp-microvolt = <905000 905000 1140000>;
203 opp-supported-hw = <0x70>;
204 clock-latency-ns = <200000>;
205 };
206 opp-844800000 {
207 opp-hz = /bits/ 64 <844800000>;
208 opp-microvolt = <905000 905000 1140000>;
209 opp-supported-hw = <0x77>;
210 clock-latency-ns = <200000>;
211 };
212 opp-902400000 {
213 opp-hz = /bits/ 64 <902400000>;
214 opp-microvolt = <905000 905000 1140000>;
215 opp-supported-hw = <0x70>;
216 clock-latency-ns = <200000>;
217 };
218 opp-960000000 {
219 opp-hz = /bits/ 64 <960000000>;
220 opp-microvolt = <905000 905000 1140000>;
221 opp-supported-hw = <0x7>;
222 clock-latency-ns = <200000>;
223 };
224 opp-979200000 {
225 opp-hz = /bits/ 64 <979200000>;
226 opp-microvolt = <905000 905000 1140000>;
227 opp-supported-hw = <0x70>;
228 clock-latency-ns = <200000>;
229 };
230 opp-1036800000 {
231 opp-hz = /bits/ 64 <1036800000>;
232 opp-microvolt = <905000 905000 1140000>;
233 opp-supported-hw = <0x7>;
234 clock-latency-ns = <200000>;
235 };
236 opp-1056000000 {
237 opp-hz = /bits/ 64 <1056000000>;
238 opp-microvolt = <905000 905000 1140000>;
239 opp-supported-hw = <0x70>;
240 clock-latency-ns = <200000>;
241 };
242 opp-1113600000 {
243 opp-hz = /bits/ 64 <1113600000>;
244 opp-microvolt = <905000 905000 1140000>;
245 opp-supported-hw = <0x7>;
246 clock-latency-ns = <200000>;
247 };
248 opp-1132800000 {
249 opp-hz = /bits/ 64 <1132800000>;
250 opp-microvolt = <905000 905000 1140000>;
251 opp-supported-hw = <0x70>;
252 clock-latency-ns = <200000>;
253 };
254 opp-1190400000 {
255 opp-hz = /bits/ 64 <1190400000>;
256 opp-microvolt = <905000 905000 1140000>;
257 opp-supported-hw = <0x7>;
258 clock-latency-ns = <200000>;
259 };
260 opp-1209600000 {
261 opp-hz = /bits/ 64 <1209600000>;
262 opp-microvolt = <905000 905000 1140000>;
263 opp-supported-hw = <0x70>;
264 clock-latency-ns = <200000>;
265 };
266 opp-1228800000 {
267 opp-hz = /bits/ 64 <1228800000>;
268 opp-microvolt = <905000 905000 1140000>;
269 opp-supported-hw = <0x7>;
270 clock-latency-ns = <200000>;
271 };
272 opp-1286400000 {
273 opp-hz = /bits/ 64 <1286400000>;
274 opp-microvolt = <1140000 905000 1140000>;
275 opp-supported-hw = <0x70>;
276 clock-latency-ns = <200000>;
277 };
278 opp-1324800000 {
279 opp-hz = /bits/ 64 <1324800000>;
280 opp-microvolt = <1140000 905000 1140000>;
281 opp-supported-hw = <0x5>;
282 clock-latency-ns = <200000>;
283 };
284 opp-1363200000 {
285 opp-hz = /bits/ 64 <1363200000>;
286 opp-microvolt = <1140000 905000 1140000>;
287 opp-supported-hw = <0x72>;
288 clock-latency-ns = <200000>;
289 };
290 opp-1401600000 {
291 opp-hz = /bits/ 64 <1401600000>;
292 opp-microvolt = <1140000 905000 1140000>;
293 opp-supported-hw = <0x5>;
294 clock-latency-ns = <200000>;
295 };
296 opp-1440000000 {
297 opp-hz = /bits/ 64 <1440000000>;
298 opp-microvolt = <1140000 905000 1140000>;
299 opp-supported-hw = <0x70>;
300 clock-latency-ns = <200000>;
301 };
302 opp-1478400000 {
303 opp-hz = /bits/ 64 <1478400000>;
304 opp-microvolt = <1140000 905000 1140000>;
305 opp-supported-hw = <0x1>;
306 clock-latency-ns = <200000>;
307 };
308 opp-1497600000 {
309 opp-hz = /bits/ 64 <1497600000>;
310 opp-microvolt = <1140000 905000 1140000>;
311 opp-supported-hw = <0x4>;
312 clock-latency-ns = <200000>;
313 };
314 opp-1516800000 {
315 opp-hz = /bits/ 64 <1516800000>;
316 opp-microvolt = <1140000 905000 1140000>;
317 opp-supported-hw = <0x70>;
318 clock-latency-ns = <200000>;
319 };
320 opp-1593600000 {
321 opp-hz = /bits/ 64 <1593600000>;
322 opp-microvolt = <1140000 905000 1140000>;
323 opp-supported-hw = <0x71>;
324 clock-latency-ns = <200000>;
325 };
326 opp-1996800000 {
327 opp-hz = /bits/ 64 <1996800000>;
328 opp-microvolt = <1140000 905000 1140000>;
329 opp-supported-hw = <0x20>;
330 clock-latency-ns = <200000>;
331 };
332 opp-2188800000 {
333 opp-hz = /bits/ 64 <2188800000>;
334 opp-microvolt = <1140000 905000 1140000>;
335 opp-supported-hw = <0x10>;
336 clock-latency-ns = <200000>;
337 };
338 };
339
340 cluster1_opp: opp_table1 {
341 compatible = "operating-points-v2-kryo-cpu";
342 nvmem-cells = <&speedbin_efuse>;
343 opp-shared;
344
345 opp-307200000 {
346 opp-hz = /bits/ 64 <307200000>;
347 opp-microvolt = <905000 905000 1140000>;
348 opp-supported-hw = <0x77>;
349 clock-latency-ns = <200000>;
350 };
351 opp-384000000 {
352 opp-hz = /bits/ 64 <384000000>;
353 opp-microvolt = <905000 905000 1140000>;
354 opp-supported-hw = <0x70>;
355 clock-latency-ns = <200000>;
356 };
357 opp-403200000 {
358 opp-hz = /bits/ 64 <403200000>;
359 opp-microvolt = <905000 905000 1140000>;
360 opp-supported-hw = <0x7>;
361 clock-latency-ns = <200000>;
362 };
363 opp-460800000 {
364 opp-hz = /bits/ 64 <460800000>;
365 opp-microvolt = <905000 905000 1140000>;
366 opp-supported-hw = <0x70>;
367 clock-latency-ns = <200000>;
368 };
369 opp-480000000 {
370 opp-hz = /bits/ 64 <480000000>;
371 opp-microvolt = <905000 905000 1140000>;
372 opp-supported-hw = <0x7>;
373 clock-latency-ns = <200000>;
374 };
375 opp-537600000 {
376 opp-hz = /bits/ 64 <537600000>;
377 opp-microvolt = <905000 905000 1140000>;
378 opp-supported-hw = <0x70>;
379 clock-latency-ns = <200000>;
380 };
381 opp-556800000 {
382 opp-hz = /bits/ 64 <556800000>;
383 opp-microvolt = <905000 905000 1140000>;
384 opp-supported-hw = <0x7>;
385 clock-latency-ns = <200000>;
386 };
387 opp-614400000 {
388 opp-hz = /bits/ 64 <614400000>;
389 opp-microvolt = <905000 905000 1140000>;
390 opp-supported-hw = <0x70>;
391 clock-latency-ns = <200000>;
392 };
393 opp-652800000 {
394 opp-hz = /bits/ 64 <652800000>;
395 opp-microvolt = <905000 905000 1140000>;
396 opp-supported-hw = <0x7>;
397 clock-latency-ns = <200000>;
398 };
399 opp-691200000 {
400 opp-hz = /bits/ 64 <691200000>;
401 opp-microvolt = <905000 905000 1140000>;
402 opp-supported-hw = <0x70>;
403 clock-latency-ns = <200000>;
404 };
405 opp-729600000 {
406 opp-hz = /bits/ 64 <729600000>;
407 opp-microvolt = <905000 905000 1140000>;
408 opp-supported-hw = <0x7>;
409 clock-latency-ns = <200000>;
410 };
411 opp-748800000 {
412 opp-hz = /bits/ 64 <748800000>;
413 opp-microvolt = <905000 905000 1140000>;
414 opp-supported-hw = <0x70>;
415 clock-latency-ns = <200000>;
416 };
417 opp-806400000 {
418 opp-hz = /bits/ 64 <806400000>;
419 opp-microvolt = <905000 905000 1140000>;
420 opp-supported-hw = <0x7>;
421 clock-latency-ns = <200000>;
422 };
423 opp-825600000 {
424 opp-hz = /bits/ 64 <825600000>;
425 opp-microvolt = <905000 905000 1140000>;
426 opp-supported-hw = <0x70>;
427 clock-latency-ns = <200000>;
428 };
429 opp-883200000 {
430 opp-hz = /bits/ 64 <883200000>;
431 opp-microvolt = <905000 905000 1140000>;
432 opp-supported-hw = <0x7>;
433 clock-latency-ns = <200000>;
434 };
435 opp-902400000 {
436 opp-hz = /bits/ 64 <902400000>;
437 opp-microvolt = <905000 905000 1140000>;
438 opp-supported-hw = <0x70>;
439 clock-latency-ns = <200000>;
440 };
441 opp-940800000 {
442 opp-hz = /bits/ 64 <940800000>;
443 opp-microvolt = <905000 905000 1140000>;
444 opp-supported-hw = <0x7>;
445 clock-latency-ns = <200000>;
446 };
447 opp-979200000 {
448 opp-hz = /bits/ 64 <979200000>;
449 opp-microvolt = <905000 905000 1140000>;
450 opp-supported-hw = <0x70>;
451 clock-latency-ns = <200000>;
452 };
453 opp-1036800000 {
454 opp-hz = /bits/ 64 <1036800000>;
455 opp-microvolt = <905000 905000 1140000>;
456 opp-supported-hw = <0x7>;
457 clock-latency-ns = <200000>;
458 };
459 opp-1056000000 {
460 opp-hz = /bits/ 64 <1056000000>;
461 opp-microvolt = <905000 905000 1140000>;
462 opp-supported-hw = <0x70>;
463 clock-latency-ns = <200000>;
464 };
465 opp-1113600000 {
466 opp-hz = /bits/ 64 <1113600000>;
467 opp-microvolt = <905000 905000 1140000>;
468 opp-supported-hw = <0x7>;
469 clock-latency-ns = <200000>;
470 };
471 opp-1132800000 {
472 opp-hz = /bits/ 64 <1132800000>;
473 opp-microvolt = <905000 905000 1140000>;
474 opp-supported-hw = <0x70>;
475 clock-latency-ns = <200000>;
476 };
477 opp-1190400000 {
478 opp-hz = /bits/ 64 <1190400000>;
479 opp-microvolt = <905000 905000 1140000>;
480 opp-supported-hw = <0x7>;
481 clock-latency-ns = <200000>;
482 };
483 opp-1209600000 {
484 opp-hz = /bits/ 64 <1209600000>;
485 opp-microvolt = <905000 905000 1140000>;
486 opp-supported-hw = <0x70>;
487 clock-latency-ns = <200000>;
488 };
489 opp-1248000000 {
490 opp-hz = /bits/ 64 <1248000000>;
491 opp-microvolt = <905000 905000 1140000>;
492 opp-supported-hw = <0x7>;
493 clock-latency-ns = <200000>;
494 };
495 opp-1286400000 {
496 opp-hz = /bits/ 64 <1286400000>;
497 opp-microvolt = <905000 905000 1140000>;
498 opp-supported-hw = <0x70>;
499 clock-latency-ns = <200000>;
500 };
501 opp-1324800000 {
502 opp-hz = /bits/ 64 <1324800000>;
503 opp-microvolt = <1140000 905000 1140000>;
504 opp-supported-hw = <0x7>;
505 clock-latency-ns = <200000>;
506 };
507 opp-1363200000 {
508 opp-hz = /bits/ 64 <1363200000>;
509 opp-microvolt = <1140000 905000 1140000>;
510 opp-supported-hw = <0x70>;
511 clock-latency-ns = <200000>;
512 };
513 opp-1401600000 {
514 opp-hz = /bits/ 64 <1401600000>;
515 opp-microvolt = <1140000 905000 1140000>;
516 opp-supported-hw = <0x7>;
517 clock-latency-ns = <200000>;
518 };
519 opp-1440000000 {
520 opp-hz = /bits/ 64 <1440000000>;
521 opp-microvolt = <1140000 905000 1140000>;
522 opp-supported-hw = <0x70>;
523 clock-latency-ns = <200000>;
524 };
525 opp-1478400000 {
526 opp-hz = /bits/ 64 <1478400000>;
527 opp-microvolt = <1140000 905000 1140000>;
528 opp-supported-hw = <0x7>;
529 clock-latency-ns = <200000>;
530 };
531 opp-1516800000 {
532 opp-hz = /bits/ 64 <1516800000>;
533 opp-microvolt = <1140000 905000 1140000>;
534 opp-supported-hw = <0x70>;
535 clock-latency-ns = <200000>;
536 };
537 opp-1555200000 {
538 opp-hz = /bits/ 64 <1555200000>;
539 opp-microvolt = <1140000 905000 1140000>;
540 opp-supported-hw = <0x7>;
541 clock-latency-ns = <200000>;
542 };
543 opp-1593600000 {
544 opp-hz = /bits/ 64 <1593600000>;
545 opp-microvolt = <1140000 905000 1140000>;
546 opp-supported-hw = <0x70>;
547 clock-latency-ns = <200000>;
548 };
549 opp-1632000000 {
550 opp-hz = /bits/ 64 <1632000000>;
551 opp-microvolt = <1140000 905000 1140000>;
552 opp-supported-hw = <0x7>;
553 clock-latency-ns = <200000>;
554 };
555 opp-1670400000 {
556 opp-hz = /bits/ 64 <1670400000>;
557 opp-microvolt = <1140000 905000 1140000>;
558 opp-supported-hw = <0x70>;
559 clock-latency-ns = <200000>;
560 };
561 opp-1708800000 {
562 opp-hz = /bits/ 64 <1708800000>;
563 opp-microvolt = <1140000 905000 1140000>;
564 opp-supported-hw = <0x7>;
565 clock-latency-ns = <200000>;
566 };
567 opp-1747200000 {
568 opp-hz = /bits/ 64 <1747200000>;
569 opp-microvolt = <1140000 905000 1140000>;
570 opp-supported-hw = <0x70>;
571 clock-latency-ns = <200000>;
572 };
573 opp-1785600000 {
574 opp-hz = /bits/ 64 <1785600000>;
575 opp-microvolt = <1140000 905000 1140000>;
576 opp-supported-hw = <0x7>;
577 clock-latency-ns = <200000>;
578 };
579 opp-1804800000 {
580 opp-hz = /bits/ 64 <1804800000>;
581 opp-microvolt = <1140000 905000 1140000>;
582 opp-supported-hw = <0x6>;
583 clock-latency-ns = <200000>;
584 };
585 opp-1824000000 {
586 opp-hz = /bits/ 64 <1824000000>;
587 opp-microvolt = <1140000 905000 1140000>;
588 opp-supported-hw = <0x71>;
589 clock-latency-ns = <200000>;
590 };
591 opp-1900800000 {
592 opp-hz = /bits/ 64 <1900800000>;
593 opp-microvolt = <1140000 905000 1140000>;
594 opp-supported-hw = <0x74>;
595 clock-latency-ns = <200000>;
596 };
597 opp-1920000000 {
598 opp-hz = /bits/ 64 <1920000000>;
599 opp-microvolt = <1140000 905000 1140000>;
600 opp-supported-hw = <0x1>;
601 clock-latency-ns = <200000>;
602 };
603 opp-1977600000 {
604 opp-hz = /bits/ 64 <1977600000>;
605 opp-microvolt = <1140000 905000 1140000>;
606 opp-supported-hw = <0x30>;
607 clock-latency-ns = <200000>;
608 };
609 opp-1996800000 {
610 opp-hz = /bits/ 64 <1996800000>;
611 opp-microvolt = <1140000 905000 1140000>;
612 opp-supported-hw = <0x1>;
613 clock-latency-ns = <200000>;
614 };
615 opp-2054400000 {
616 opp-hz = /bits/ 64 <2054400000>;
617 opp-microvolt = <1140000 905000 1140000>;
618 opp-supported-hw = <0x30>;
619 clock-latency-ns = <200000>;
620 };
621 opp-2073600000 {
622 opp-hz = /bits/ 64 <2073600000>;
623 opp-microvolt = <1140000 905000 1140000>;
624 opp-supported-hw = <0x1>;
625 clock-latency-ns = <200000>;
626 };
627 opp-2150400000 {
628 opp-hz = /bits/ 64 <2150400000>;
629 opp-microvolt = <1140000 905000 1140000>;
630 opp-supported-hw = <0x31>;
631 clock-latency-ns = <200000>;
632 };
633 opp-2246400000 {
634 opp-hz = /bits/ 64 <2246400000>;
635 opp-microvolt = <1140000 905000 1140000>;
636 opp-supported-hw = <0x10>;
637 clock-latency-ns = <200000>;
638 };
639 opp-2342400000 {
640 opp-hz = /bits/ 64 <2342400000>;
641 opp-microvolt = <1140000 905000 1140000>;
642 opp-supported-hw = <0x10>;
643 clock-latency-ns = <200000>;
644 };
645 };
646
647....
648
649reserved-memory {
650 #address-cells = <2>;
651 #size-cells = <2>;
652 ranges;
653....
654 smem_mem: smem-mem@86000000 {
655 reg = <0x0 0x86000000 0x0 0x200000>;
656 no-map;
657 };
658....
659};
660
661smem {
662 compatible = "qcom,smem";
663 memory-region = <&smem_mem>;
664 hwlocks = <&tcsr_mutex 3>;
665};
666
667soc {
668....
669 qfprom: qfprom@74000 {
670 compatible = "qcom,qfprom";
671 reg = <0x00074000 0x8ff>;
672 #address-cells = <1>;
673 #size-cells = <1>;
674 ....
675 speedbin_efuse: speedbin@133 {
676 reg = <0x133 0x1>;
677 bits = <5 3>;
678 };
679 };
680};
diff --git a/MAINTAINERS b/MAINTAINERS
index 0d00b6c5370b..974b730cdd5b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11654,6 +11654,13 @@ F: Documentation/devicetree/bindings/media/qcom,camss.txt
11654F: Documentation/media/v4l-drivers/qcom_camss.rst 11654F: Documentation/media/v4l-drivers/qcom_camss.rst
11655F: drivers/media/platform/qcom/camss-8x16/ 11655F: drivers/media/platform/qcom/camss-8x16/
11656 11656
11657QUALCOMM CPUFREQ DRIVER MSM8996/APQ8096
11658M: Ilia Lin <ilia.lin@gmail.com>
11659L: linux-pm@vger.kernel.org
11660S: Maintained
11661F: Documentation/devicetree/bindings/opp/kryo-cpufreq.txt
11662F: drivers/cpufreq/qcom-cpufreq-kryo.c
11663
11657QUALCOMM EMAC GIGABIT ETHERNET DRIVER 11664QUALCOMM EMAC GIGABIT ETHERNET DRIVER
11658M: Timur Tabi <timur@codeaurora.org> 11665M: Timur Tabi <timur@codeaurora.org>
11659L: netdev@vger.kernel.org 11666L: netdev@vger.kernel.org
diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index 96b35b8b3606..c7ce928fbf1f 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -124,6 +124,17 @@ config ARM_OMAP2PLUS_CPUFREQ
124 depends on ARCH_OMAP2PLUS 124 depends on ARCH_OMAP2PLUS
125 default ARCH_OMAP2PLUS 125 default ARCH_OMAP2PLUS
126 126
127config ARM_QCOM_CPUFREQ_KRYO
128 bool "Qualcomm Kryo based CPUFreq"
129 depends on ARM64
130 depends on QCOM_QFPROM
131 depends on QCOM_SMEM
132 select PM_OPP
133 help
134 This adds the CPUFreq driver for Qualcomm Kryo SoC based boards.
135
136 If in doubt, say N.
137
127config ARM_S3C_CPUFREQ 138config ARM_S3C_CPUFREQ
128 bool 139 bool
129 help 140 help
@@ -264,7 +275,7 @@ config ARM_TANGO_CPUFREQ
264 default y 275 default y
265 276
266config ARM_TEGRA20_CPUFREQ 277config ARM_TEGRA20_CPUFREQ
267 bool "Tegra20 CPUFreq support" 278 tristate "Tegra20 CPUFreq support"
268 depends on ARCH_TEGRA 279 depends on ARCH_TEGRA
269 default y 280 default y
270 help 281 help
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index 8d24ade3bd02..fb4a2ecac43b 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -65,6 +65,7 @@ obj-$(CONFIG_MACH_MVEBU_V7) += mvebu-cpufreq.o
65obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ) += omap-cpufreq.o 65obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ) += omap-cpufreq.o
66obj-$(CONFIG_ARM_PXA2xx_CPUFREQ) += pxa2xx-cpufreq.o 66obj-$(CONFIG_ARM_PXA2xx_CPUFREQ) += pxa2xx-cpufreq.o
67obj-$(CONFIG_PXA3xx) += pxa3xx-cpufreq.o 67obj-$(CONFIG_PXA3xx) += pxa3xx-cpufreq.o
68obj-$(CONFIG_ARM_QCOM_CPUFREQ_KRYO) += qcom-cpufreq-kryo.o
68obj-$(CONFIG_ARM_S3C2410_CPUFREQ) += s3c2410-cpufreq.o 69obj-$(CONFIG_ARM_S3C2410_CPUFREQ) += s3c2410-cpufreq.o
69obj-$(CONFIG_ARM_S3C2412_CPUFREQ) += s3c2412-cpufreq.o 70obj-$(CONFIG_ARM_S3C2412_CPUFREQ) += s3c2412-cpufreq.o
70obj-$(CONFIG_ARM_S3C2416_CPUFREQ) += s3c2416-cpufreq.o 71obj-$(CONFIG_ARM_S3C2416_CPUFREQ) += s3c2416-cpufreq.o
diff --git a/drivers/cpufreq/armada-37xx-cpufreq.c b/drivers/cpufreq/armada-37xx-cpufreq.c
index 72a2975499db..739da90ff3f6 100644
--- a/drivers/cpufreq/armada-37xx-cpufreq.c
+++ b/drivers/cpufreq/armada-37xx-cpufreq.c
@@ -23,6 +23,8 @@
23#include <linux/regmap.h> 23#include <linux/regmap.h>
24#include <linux/slab.h> 24#include <linux/slab.h>
25 25
26#include "cpufreq-dt.h"
27
26/* Power management in North Bridge register set */ 28/* Power management in North Bridge register set */
27#define ARMADA_37XX_NB_L0L1 0x18 29#define ARMADA_37XX_NB_L0L1 0x18
28#define ARMADA_37XX_NB_L2L3 0x1C 30#define ARMADA_37XX_NB_L2L3 0x1C
@@ -56,6 +58,16 @@
56 */ 58 */
57#define LOAD_LEVEL_NR 4 59#define LOAD_LEVEL_NR 4
58 60
61struct armada37xx_cpufreq_state {
62 struct regmap *regmap;
63 u32 nb_l0l1;
64 u32 nb_l2l3;
65 u32 nb_dyn_mod;
66 u32 nb_cpu_load;
67};
68
69static struct armada37xx_cpufreq_state *armada37xx_cpufreq_state;
70
59struct armada_37xx_dvfs { 71struct armada_37xx_dvfs {
60 u32 cpu_freq_max; 72 u32 cpu_freq_max;
61 u8 divider[LOAD_LEVEL_NR]; 73 u8 divider[LOAD_LEVEL_NR];
@@ -136,7 +148,7 @@ static void __init armada37xx_cpufreq_dvfs_setup(struct regmap *base,
136 clk_set_parent(clk, parent); 148 clk_set_parent(clk, parent);
137} 149}
138 150
139static void __init armada37xx_cpufreq_disable_dvfs(struct regmap *base) 151static void armada37xx_cpufreq_disable_dvfs(struct regmap *base)
140{ 152{
141 unsigned int reg = ARMADA_37XX_NB_DYN_MOD, 153 unsigned int reg = ARMADA_37XX_NB_DYN_MOD,
142 mask = ARMADA_37XX_NB_DFS_EN; 154 mask = ARMADA_37XX_NB_DFS_EN;
@@ -162,10 +174,47 @@ static void __init armada37xx_cpufreq_enable_dvfs(struct regmap *base)
162 regmap_update_bits(base, reg, mask, mask); 174 regmap_update_bits(base, reg, mask, mask);
163} 175}
164 176
177static int armada37xx_cpufreq_suspend(struct cpufreq_policy *policy)
178{
179 struct armada37xx_cpufreq_state *state = armada37xx_cpufreq_state;
180
181 regmap_read(state->regmap, ARMADA_37XX_NB_L0L1, &state->nb_l0l1);
182 regmap_read(state->regmap, ARMADA_37XX_NB_L2L3, &state->nb_l2l3);
183 regmap_read(state->regmap, ARMADA_37XX_NB_CPU_LOAD,
184 &state->nb_cpu_load);
185 regmap_read(state->regmap, ARMADA_37XX_NB_DYN_MOD, &state->nb_dyn_mod);
186
187 return 0;
188}
189
190static int armada37xx_cpufreq_resume(struct cpufreq_policy *policy)
191{
192 struct armada37xx_cpufreq_state *state = armada37xx_cpufreq_state;
193
194 /* Ensure DVFS is disabled otherwise the following registers are RO */
195 armada37xx_cpufreq_disable_dvfs(state->regmap);
196
197 regmap_write(state->regmap, ARMADA_37XX_NB_L0L1, state->nb_l0l1);
198 regmap_write(state->regmap, ARMADA_37XX_NB_L2L3, state->nb_l2l3);
199 regmap_write(state->regmap, ARMADA_37XX_NB_CPU_LOAD,
200 state->nb_cpu_load);
201
202 /*
203 * NB_DYN_MOD register is the one that actually enable back DVFS if it
204 * was enabled before the suspend operation. This must be done last
205 * otherwise other registers are not writable.
206 */
207 regmap_write(state->regmap, ARMADA_37XX_NB_DYN_MOD, state->nb_dyn_mod);
208
209 return 0;
210}
211
165static int __init armada37xx_cpufreq_driver_init(void) 212static int __init armada37xx_cpufreq_driver_init(void)
166{ 213{
214 struct cpufreq_dt_platform_data pdata;
167 struct armada_37xx_dvfs *dvfs; 215 struct armada_37xx_dvfs *dvfs;
168 struct platform_device *pdev; 216 struct platform_device *pdev;
217 unsigned long freq;
169 unsigned int cur_frequency; 218 unsigned int cur_frequency;
170 struct regmap *nb_pm_base; 219 struct regmap *nb_pm_base;
171 struct device *cpu_dev; 220 struct device *cpu_dev;
@@ -207,33 +256,58 @@ static int __init armada37xx_cpufreq_driver_init(void)
207 } 256 }
208 257
209 dvfs = armada_37xx_cpu_freq_info_get(cur_frequency); 258 dvfs = armada_37xx_cpu_freq_info_get(cur_frequency);
210 if (!dvfs) 259 if (!dvfs) {
260 clk_put(clk);
211 return -EINVAL; 261 return -EINVAL;
262 }
263
264 armada37xx_cpufreq_state = kmalloc(sizeof(*armada37xx_cpufreq_state),
265 GFP_KERNEL);
266 if (!armada37xx_cpufreq_state) {
267 clk_put(clk);
268 return -ENOMEM;
269 }
270
271 armada37xx_cpufreq_state->regmap = nb_pm_base;
212 272
213 armada37xx_cpufreq_dvfs_setup(nb_pm_base, clk, dvfs->divider); 273 armada37xx_cpufreq_dvfs_setup(nb_pm_base, clk, dvfs->divider);
214 clk_put(clk); 274 clk_put(clk);
215 275
216 for (load_lvl = ARMADA_37XX_DVFS_LOAD_0; load_lvl < LOAD_LEVEL_NR; 276 for (load_lvl = ARMADA_37XX_DVFS_LOAD_0; load_lvl < LOAD_LEVEL_NR;
217 load_lvl++) { 277 load_lvl++) {
218 unsigned long freq = cur_frequency / dvfs->divider[load_lvl]; 278 freq = cur_frequency / dvfs->divider[load_lvl];
219 279
220 ret = dev_pm_opp_add(cpu_dev, freq, 0); 280 ret = dev_pm_opp_add(cpu_dev, freq, 0);
221 if (ret) { 281 if (ret)
222 /* clean-up the already added opp before leaving */ 282 goto remove_opp;
223 while (load_lvl-- > ARMADA_37XX_DVFS_LOAD_0) {
224 freq = cur_frequency / dvfs->divider[load_lvl];
225 dev_pm_opp_remove(cpu_dev, freq);
226 }
227 return ret;
228 }
229 } 283 }
230 284
231 /* Now that everything is setup, enable the DVFS at hardware level */ 285 /* Now that everything is setup, enable the DVFS at hardware level */
232 armada37xx_cpufreq_enable_dvfs(nb_pm_base); 286 armada37xx_cpufreq_enable_dvfs(nb_pm_base);
233 287
234 pdev = platform_device_register_simple("cpufreq-dt", -1, NULL, 0); 288 pdata.suspend = armada37xx_cpufreq_suspend;
289 pdata.resume = armada37xx_cpufreq_resume;
290
291 pdev = platform_device_register_data(NULL, "cpufreq-dt", -1, &pdata,
292 sizeof(pdata));
293 ret = PTR_ERR_OR_ZERO(pdev);
294 if (ret)
295 goto disable_dvfs;
296
297 return 0;
298
299disable_dvfs:
300 armada37xx_cpufreq_disable_dvfs(nb_pm_base);
301remove_opp:
302 /* clean-up the already added opp before leaving */
303 while (load_lvl-- > ARMADA_37XX_DVFS_LOAD_0) {
304 freq = cur_frequency / dvfs->divider[load_lvl];
305 dev_pm_opp_remove(cpu_dev, freq);
306 }
307
308 kfree(armada37xx_cpufreq_state);
235 309
236 return PTR_ERR_OR_ZERO(pdev); 310 return ret;
237} 311}
238/* late_initcall, to guarantee the driver is loaded after A37xx clock driver */ 312/* late_initcall, to guarantee the driver is loaded after A37xx clock driver */
239late_initcall(armada37xx_cpufreq_driver_init); 313late_initcall(armada37xx_cpufreq_driver_init);
diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c
index 3b585e4bfac5..fe14c57de6ca 100644
--- a/drivers/cpufreq/cpufreq-dt-platdev.c
+++ b/drivers/cpufreq/cpufreq-dt-platdev.c
@@ -66,8 +66,6 @@ static const struct of_device_id whitelist[] __initconst = {
66 { .compatible = "renesas,r8a7792", }, 66 { .compatible = "renesas,r8a7792", },
67 { .compatible = "renesas,r8a7793", }, 67 { .compatible = "renesas,r8a7793", },
68 { .compatible = "renesas,r8a7794", }, 68 { .compatible = "renesas,r8a7794", },
69 { .compatible = "renesas,r8a7795", },
70 { .compatible = "renesas,r8a7796", },
71 { .compatible = "renesas,sh73a0", }, 69 { .compatible = "renesas,sh73a0", },
72 70
73 { .compatible = "rockchip,rk2928", }, 71 { .compatible = "rockchip,rk2928", },
@@ -118,6 +116,9 @@ static const struct of_device_id blacklist[] __initconst = {
118 116
119 { .compatible = "nvidia,tegra124", }, 117 { .compatible = "nvidia,tegra124", },
120 118
119 { .compatible = "qcom,apq8096", },
120 { .compatible = "qcom,msm8996", },
121
121 { .compatible = "st,stih407", }, 122 { .compatible = "st,stih407", },
122 { .compatible = "st,stih410", }, 123 { .compatible = "st,stih410", },
123 124
diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c
index 190ea0dccb79..0a9ebf00be46 100644
--- a/drivers/cpufreq/cpufreq-dt.c
+++ b/drivers/cpufreq/cpufreq-dt.c
@@ -346,8 +346,14 @@ static int dt_cpufreq_probe(struct platform_device *pdev)
346 if (ret) 346 if (ret)
347 return ret; 347 return ret;
348 348
349 if (data && data->have_governor_per_policy) 349 if (data) {
350 dt_cpufreq_driver.flags |= CPUFREQ_HAVE_GOVERNOR_PER_POLICY; 350 if (data->have_governor_per_policy)
351 dt_cpufreq_driver.flags |= CPUFREQ_HAVE_GOVERNOR_PER_POLICY;
352
353 dt_cpufreq_driver.resume = data->resume;
354 if (data->suspend)
355 dt_cpufreq_driver.suspend = data->suspend;
356 }
351 357
352 ret = cpufreq_register_driver(&dt_cpufreq_driver); 358 ret = cpufreq_register_driver(&dt_cpufreq_driver);
353 if (ret) 359 if (ret)
diff --git a/drivers/cpufreq/cpufreq-dt.h b/drivers/cpufreq/cpufreq-dt.h
index 54d774e46c43..d5aeea13433e 100644
--- a/drivers/cpufreq/cpufreq-dt.h
+++ b/drivers/cpufreq/cpufreq-dt.h
@@ -12,8 +12,13 @@
12 12
13#include <linux/types.h> 13#include <linux/types.h>
14 14
15struct cpufreq_policy;
16
15struct cpufreq_dt_platform_data { 17struct cpufreq_dt_platform_data {
16 bool have_governor_per_policy; 18 bool have_governor_per_policy;
19
20 int (*suspend)(struct cpufreq_policy *policy);
21 int (*resume)(struct cpufreq_policy *policy);
17}; 22};
18 23
19#endif /* __CPUFREQ_DT_H__ */ 24#endif /* __CPUFREQ_DT_H__ */
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 075d18f6ba7a..b0dfd3222013 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -89,16 +89,7 @@ static void cpufreq_governor_limits(struct cpufreq_policy *policy);
89 * The mutex locks both lists. 89 * The mutex locks both lists.
90 */ 90 */
91static BLOCKING_NOTIFIER_HEAD(cpufreq_policy_notifier_list); 91static BLOCKING_NOTIFIER_HEAD(cpufreq_policy_notifier_list);
92static struct srcu_notifier_head cpufreq_transition_notifier_list; 92SRCU_NOTIFIER_HEAD_STATIC(cpufreq_transition_notifier_list);
93
94static bool init_cpufreq_transition_notifier_list_called;
95static int __init init_cpufreq_transition_notifier_list(void)
96{
97 srcu_init_notifier_head(&cpufreq_transition_notifier_list);
98 init_cpufreq_transition_notifier_list_called = true;
99 return 0;
100}
101pure_initcall(init_cpufreq_transition_notifier_list);
102 93
103static int off __read_mostly; 94static int off __read_mostly;
104static int cpufreq_disabled(void) 95static int cpufreq_disabled(void)
@@ -300,8 +291,19 @@ static void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci)
300#endif 291#endif
301} 292}
302 293
303static void __cpufreq_notify_transition(struct cpufreq_policy *policy, 294/**
304 struct cpufreq_freqs *freqs, unsigned int state) 295 * cpufreq_notify_transition - Notify frequency transition and adjust_jiffies.
296 * @policy: cpufreq policy to enable fast frequency switching for.
297 * @freqs: contain details of the frequency update.
298 * @state: set to CPUFREQ_PRECHANGE or CPUFREQ_POSTCHANGE.
299 *
300 * This function calls the transition notifiers and the "adjust_jiffies"
301 * function. It is called twice on all CPU frequency changes that have
302 * external effects.
303 */
304static void cpufreq_notify_transition(struct cpufreq_policy *policy,
305 struct cpufreq_freqs *freqs,
306 unsigned int state)
305{ 307{
306 BUG_ON(irqs_disabled()); 308 BUG_ON(irqs_disabled());
307 309
@@ -313,54 +315,44 @@ static void __cpufreq_notify_transition(struct cpufreq_policy *policy,
313 state, freqs->new); 315 state, freqs->new);
314 316
315 switch (state) { 317 switch (state) {
316
317 case CPUFREQ_PRECHANGE: 318 case CPUFREQ_PRECHANGE:
318 /* detect if the driver reported a value as "old frequency" 319 /*
320 * Detect if the driver reported a value as "old frequency"
319 * which is not equal to what the cpufreq core thinks is 321 * which is not equal to what the cpufreq core thinks is
320 * "old frequency". 322 * "old frequency".
321 */ 323 */
322 if (!(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) { 324 if (!(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) {
323 if ((policy) && (policy->cpu == freqs->cpu) && 325 if (policy->cur && (policy->cur != freqs->old)) {
324 (policy->cur) && (policy->cur != freqs->old)) {
325 pr_debug("Warning: CPU frequency is %u, cpufreq assumed %u kHz\n", 326 pr_debug("Warning: CPU frequency is %u, cpufreq assumed %u kHz\n",
326 freqs->old, policy->cur); 327 freqs->old, policy->cur);
327 freqs->old = policy->cur; 328 freqs->old = policy->cur;
328 } 329 }
329 } 330 }
330 srcu_notifier_call_chain(&cpufreq_transition_notifier_list, 331
331 CPUFREQ_PRECHANGE, freqs); 332 for_each_cpu(freqs->cpu, policy->cpus) {
333 srcu_notifier_call_chain(&cpufreq_transition_notifier_list,
334 CPUFREQ_PRECHANGE, freqs);
335 }
336
332 adjust_jiffies(CPUFREQ_PRECHANGE, freqs); 337 adjust_jiffies(CPUFREQ_PRECHANGE, freqs);
333 break; 338 break;
334 339
335 case CPUFREQ_POSTCHANGE: 340 case CPUFREQ_POSTCHANGE:
336 adjust_jiffies(CPUFREQ_POSTCHANGE, freqs); 341 adjust_jiffies(CPUFREQ_POSTCHANGE, freqs);
337 pr_debug("FREQ: %lu - CPU: %lu\n", 342 pr_debug("FREQ: %u - CPUs: %*pbl\n", freqs->new,
338 (unsigned long)freqs->new, (unsigned long)freqs->cpu); 343 cpumask_pr_args(policy->cpus));
339 trace_cpu_frequency(freqs->new, freqs->cpu); 344
345 for_each_cpu(freqs->cpu, policy->cpus) {
346 trace_cpu_frequency(freqs->new, freqs->cpu);
347 srcu_notifier_call_chain(&cpufreq_transition_notifier_list,
348 CPUFREQ_POSTCHANGE, freqs);
349 }
350
340 cpufreq_stats_record_transition(policy, freqs->new); 351 cpufreq_stats_record_transition(policy, freqs->new);
341 srcu_notifier_call_chain(&cpufreq_transition_notifier_list, 352 policy->cur = freqs->new;
342 CPUFREQ_POSTCHANGE, freqs);
343 if (likely(policy) && likely(policy->cpu == freqs->cpu))
344 policy->cur = freqs->new;
345 break;
346 } 353 }
347} 354}
348 355
349/**
350 * cpufreq_notify_transition - call notifier chain and adjust_jiffies
351 * on frequency transition.
352 *
353 * This function calls the transition notifiers and the "adjust_jiffies"
354 * function. It is called twice on all CPU frequency changes that have
355 * external effects.
356 */
357static void cpufreq_notify_transition(struct cpufreq_policy *policy,
358 struct cpufreq_freqs *freqs, unsigned int state)
359{
360 for_each_cpu(freqs->cpu, policy->cpus)
361 __cpufreq_notify_transition(policy, freqs, state);
362}
363
364/* Do post notifications when there are chances that transition has failed */ 356/* Do post notifications when there are chances that transition has failed */
365static void cpufreq_notify_post_transition(struct cpufreq_policy *policy, 357static void cpufreq_notify_post_transition(struct cpufreq_policy *policy,
366 struct cpufreq_freqs *freqs, int transition_failed) 358 struct cpufreq_freqs *freqs, int transition_failed)
@@ -696,6 +688,8 @@ static ssize_t store_##file_name \
696 struct cpufreq_policy new_policy; \ 688 struct cpufreq_policy new_policy; \
697 \ 689 \
698 memcpy(&new_policy, policy, sizeof(*policy)); \ 690 memcpy(&new_policy, policy, sizeof(*policy)); \
691 new_policy.min = policy->user_policy.min; \
692 new_policy.max = policy->user_policy.max; \
699 \ 693 \
700 ret = sscanf(buf, "%u", &new_policy.object); \ 694 ret = sscanf(buf, "%u", &new_policy.object); \
701 if (ret != 1) \ 695 if (ret != 1) \
@@ -1764,8 +1758,6 @@ int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list)
1764 if (cpufreq_disabled()) 1758 if (cpufreq_disabled())
1765 return -EINVAL; 1759 return -EINVAL;
1766 1760
1767 WARN_ON(!init_cpufreq_transition_notifier_list_called);
1768
1769 switch (list) { 1761 switch (list) {
1770 case CPUFREQ_TRANSITION_NOTIFIER: 1762 case CPUFREQ_TRANSITION_NOTIFIER:
1771 mutex_lock(&cpufreq_fast_switch_lock); 1763 mutex_lock(&cpufreq_fast_switch_lock);
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
index 17e566afbb41..08960a55eb27 100644
--- a/drivers/cpufreq/intel_pstate.c
+++ b/drivers/cpufreq/intel_pstate.c
@@ -1939,13 +1939,51 @@ static int intel_cpufreq_verify_policy(struct cpufreq_policy *policy)
1939 return 0; 1939 return 0;
1940} 1940}
1941 1941
1942/* Use of trace in passive mode:
1943 *
1944 * In passive mode the trace core_busy field (also known as the
1945 * performance field, and lablelled as such on the graphs; also known as
1946 * core_avg_perf) is not needed and so is re-assigned to indicate if the
1947 * driver call was via the normal or fast switch path. Various graphs
1948 * output from the intel_pstate_tracer.py utility that include core_busy
1949 * (or performance or core_avg_perf) have a fixed y-axis from 0 to 100%,
1950 * so we use 10 to indicate the the normal path through the driver, and
1951 * 90 to indicate the fast switch path through the driver.
1952 * The scaled_busy field is not used, and is set to 0.
1953 */
1954
1955#define INTEL_PSTATE_TRACE_TARGET 10
1956#define INTEL_PSTATE_TRACE_FAST_SWITCH 90
1957
1958static void intel_cpufreq_trace(struct cpudata *cpu, unsigned int trace_type, int old_pstate)
1959{
1960 struct sample *sample;
1961
1962 if (!trace_pstate_sample_enabled())
1963 return;
1964
1965 if (!intel_pstate_sample(cpu, ktime_get()))
1966 return;
1967
1968 sample = &cpu->sample;
1969 trace_pstate_sample(trace_type,
1970 0,
1971 old_pstate,
1972 cpu->pstate.current_pstate,
1973 sample->mperf,
1974 sample->aperf,
1975 sample->tsc,
1976 get_avg_frequency(cpu),
1977 fp_toint(cpu->iowait_boost * 100));
1978}
1979
1942static int intel_cpufreq_target(struct cpufreq_policy *policy, 1980static int intel_cpufreq_target(struct cpufreq_policy *policy,
1943 unsigned int target_freq, 1981 unsigned int target_freq,
1944 unsigned int relation) 1982 unsigned int relation)
1945{ 1983{
1946 struct cpudata *cpu = all_cpu_data[policy->cpu]; 1984 struct cpudata *cpu = all_cpu_data[policy->cpu];
1947 struct cpufreq_freqs freqs; 1985 struct cpufreq_freqs freqs;
1948 int target_pstate; 1986 int target_pstate, old_pstate;
1949 1987
1950 update_turbo_state(); 1988 update_turbo_state();
1951 1989
@@ -1965,12 +2003,14 @@ static int intel_cpufreq_target(struct cpufreq_policy *policy,
1965 break; 2003 break;
1966 } 2004 }
1967 target_pstate = intel_pstate_prepare_request(cpu, target_pstate); 2005 target_pstate = intel_pstate_prepare_request(cpu, target_pstate);
2006 old_pstate = cpu->pstate.current_pstate;
1968 if (target_pstate != cpu->pstate.current_pstate) { 2007 if (target_pstate != cpu->pstate.current_pstate) {
1969 cpu->pstate.current_pstate = target_pstate; 2008 cpu->pstate.current_pstate = target_pstate;
1970 wrmsrl_on_cpu(policy->cpu, MSR_IA32_PERF_CTL, 2009 wrmsrl_on_cpu(policy->cpu, MSR_IA32_PERF_CTL,
1971 pstate_funcs.get_val(cpu, target_pstate)); 2010 pstate_funcs.get_val(cpu, target_pstate));
1972 } 2011 }
1973 freqs.new = target_pstate * cpu->pstate.scaling; 2012 freqs.new = target_pstate * cpu->pstate.scaling;
2013 intel_cpufreq_trace(cpu, INTEL_PSTATE_TRACE_TARGET, old_pstate);
1974 cpufreq_freq_transition_end(policy, &freqs, false); 2014 cpufreq_freq_transition_end(policy, &freqs, false);
1975 2015
1976 return 0; 2016 return 0;
@@ -1980,13 +2020,15 @@ static unsigned int intel_cpufreq_fast_switch(struct cpufreq_policy *policy,
1980 unsigned int target_freq) 2020 unsigned int target_freq)
1981{ 2021{
1982 struct cpudata *cpu = all_cpu_data[policy->cpu]; 2022 struct cpudata *cpu = all_cpu_data[policy->cpu];
1983 int target_pstate; 2023 int target_pstate, old_pstate;
1984 2024
1985 update_turbo_state(); 2025 update_turbo_state();
1986 2026
1987 target_pstate = DIV_ROUND_UP(target_freq, cpu->pstate.scaling); 2027 target_pstate = DIV_ROUND_UP(target_freq, cpu->pstate.scaling);
1988 target_pstate = intel_pstate_prepare_request(cpu, target_pstate); 2028 target_pstate = intel_pstate_prepare_request(cpu, target_pstate);
2029 old_pstate = cpu->pstate.current_pstate;
1989 intel_pstate_update_pstate(cpu, target_pstate); 2030 intel_pstate_update_pstate(cpu, target_pstate);
2031 intel_cpufreq_trace(cpu, INTEL_PSTATE_TRACE_FAST_SWITCH, old_pstate);
1990 return target_pstate * cpu->pstate.scaling; 2032 return target_pstate * cpu->pstate.scaling;
1991} 2033}
1992 2034
diff --git a/drivers/cpufreq/qcom-cpufreq-kryo.c b/drivers/cpufreq/qcom-cpufreq-kryo.c
new file mode 100644
index 000000000000..d049fe4b80c4
--- /dev/null
+++ b/drivers/cpufreq/qcom-cpufreq-kryo.c
@@ -0,0 +1,212 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (c) 2018, The Linux Foundation. All rights reserved.
4 */
5
6/*
7 * In Certain QCOM SoCs like apq8096 and msm8996 that have KRYO processors,
8 * the CPU frequency subset and voltage value of each OPP varies
9 * based on the silicon variant in use. Qualcomm Process Voltage Scaling Tables
10 * defines the voltage and frequency value based on the msm-id in SMEM
11 * and speedbin blown in the efuse combination.
12 * The qcom-cpufreq-kryo driver reads the msm-id and efuse value from the SoC
13 * to provide the OPP framework with required information.
14 * This is used to determine the voltage and frequency value for each OPP of
15 * operating-points-v2 table when it is parsed by the OPP framework.
16 */
17
18#include <linux/cpu.h>
19#include <linux/err.h>
20#include <linux/init.h>
21#include <linux/kernel.h>
22#include <linux/module.h>
23#include <linux/nvmem-consumer.h>
24#include <linux/of.h>
25#include <linux/platform_device.h>
26#include <linux/pm_opp.h>
27#include <linux/slab.h>
28#include <linux/soc/qcom/smem.h>
29
30#define MSM_ID_SMEM 137
31
32enum _msm_id {
33 MSM8996V3 = 0xF6ul,
34 APQ8096V3 = 0x123ul,
35 MSM8996SG = 0x131ul,
36 APQ8096SG = 0x138ul,
37};
38
39enum _msm8996_version {
40 MSM8996_V3,
41 MSM8996_SG,
42 NUM_OF_MSM8996_VERSIONS,
43};
44
45static enum _msm8996_version __init qcom_cpufreq_kryo_get_msm_id(void)
46{
47 size_t len;
48 u32 *msm_id;
49 enum _msm8996_version version;
50
51 msm_id = qcom_smem_get(QCOM_SMEM_HOST_ANY, MSM_ID_SMEM, &len);
52 if (IS_ERR(msm_id))
53 return NUM_OF_MSM8996_VERSIONS;
54
55 /* The first 4 bytes are format, next to them is the actual msm-id */
56 msm_id++;
57
58 switch ((enum _msm_id)*msm_id) {
59 case MSM8996V3:
60 case APQ8096V3:
61 version = MSM8996_V3;
62 break;
63 case MSM8996SG:
64 case APQ8096SG:
65 version = MSM8996_SG;
66 break;
67 default:
68 version = NUM_OF_MSM8996_VERSIONS;
69 }
70
71 return version;
72}
73
74static int qcom_cpufreq_kryo_probe(struct platform_device *pdev)
75{
76 struct opp_table *opp_tables[NR_CPUS] = {0};
77 struct platform_device *cpufreq_dt_pdev;
78 enum _msm8996_version msm8996_version;
79 struct nvmem_cell *speedbin_nvmem;
80 struct device_node *np;
81 struct device *cpu_dev;
82 unsigned cpu;
83 u8 *speedbin;
84 u32 versions;
85 size_t len;
86 int ret;
87
88 cpu_dev = get_cpu_device(0);
89 if (NULL == cpu_dev)
90 ret = -ENODEV;
91
92 msm8996_version = qcom_cpufreq_kryo_get_msm_id();
93 if (NUM_OF_MSM8996_VERSIONS == msm8996_version) {
94 dev_err(cpu_dev, "Not Snapdragon 820/821!");
95 return -ENODEV;
96 }
97
98 np = dev_pm_opp_of_get_opp_desc_node(cpu_dev);
99 if (IS_ERR(np))
100 return PTR_ERR(np);
101
102 ret = of_device_is_compatible(np, "operating-points-v2-kryo-cpu");
103 if (!ret) {
104 of_node_put(np);
105 return -ENOENT;
106 }
107
108 speedbin_nvmem = of_nvmem_cell_get(np, NULL);
109 of_node_put(np);
110 if (IS_ERR(speedbin_nvmem)) {
111 dev_err(cpu_dev, "Could not get nvmem cell: %ld\n",
112 PTR_ERR(speedbin_nvmem));
113 return PTR_ERR(speedbin_nvmem);
114 }
115
116 speedbin = nvmem_cell_read(speedbin_nvmem, &len);
117 nvmem_cell_put(speedbin_nvmem);
118
119 switch (msm8996_version) {
120 case MSM8996_V3:
121 versions = 1 << (unsigned int)(*speedbin);
122 break;
123 case MSM8996_SG:
124 versions = 1 << ((unsigned int)(*speedbin) + 4);
125 break;
126 default:
127 BUG();
128 break;
129 }
130
131 for_each_possible_cpu(cpu) {
132 cpu_dev = get_cpu_device(cpu);
133 if (NULL == cpu_dev) {
134 ret = -ENODEV;
135 goto free_opp;
136 }
137
138 opp_tables[cpu] = dev_pm_opp_set_supported_hw(cpu_dev,
139 &versions, 1);
140 if (IS_ERR(opp_tables[cpu])) {
141 ret = PTR_ERR(opp_tables[cpu]);
142 dev_err(cpu_dev, "Failed to set supported hardware\n");
143 goto free_opp;
144 }
145 }
146
147 cpufreq_dt_pdev = platform_device_register_simple("cpufreq-dt", -1,
148 NULL, 0);
149 if (!IS_ERR(cpufreq_dt_pdev))
150 return 0;
151
152 ret = PTR_ERR(cpufreq_dt_pdev);
153 dev_err(cpu_dev, "Failed to register platform device\n");
154
155free_opp:
156 for_each_possible_cpu(cpu) {
157 if (IS_ERR_OR_NULL(opp_tables[cpu]))
158 break;
159 dev_pm_opp_put_supported_hw(opp_tables[cpu]);
160 }
161
162 return ret;
163}
164
165static struct platform_driver qcom_cpufreq_kryo_driver = {
166 .probe = qcom_cpufreq_kryo_probe,
167 .driver = {
168 .name = "qcom-cpufreq-kryo",
169 },
170};
171
172static const struct of_device_id qcom_cpufreq_kryo_match_list[] __initconst = {
173 { .compatible = "qcom,apq8096", },
174 { .compatible = "qcom,msm8996", },
175};
176
177/*
178 * Since the driver depends on smem and nvmem drivers, which may
179 * return EPROBE_DEFER, all the real activity is done in the probe,
180 * which may be defered as well. The init here is only registering
181 * the driver and the platform device.
182 */
183static int __init qcom_cpufreq_kryo_init(void)
184{
185 struct device_node *np = of_find_node_by_path("/");
186 const struct of_device_id *match;
187 int ret;
188
189 if (!np)
190 return -ENODEV;
191
192 match = of_match_node(qcom_cpufreq_kryo_match_list, np);
193 of_node_put(np);
194 if (!match)
195 return -ENODEV;
196
197 ret = platform_driver_register(&qcom_cpufreq_kryo_driver);
198 if (unlikely(ret < 0))
199 return ret;
200
201 ret = PTR_ERR_OR_ZERO(platform_device_register_simple(
202 "qcom-cpufreq-kryo", -1, NULL, 0));
203 if (0 == ret)
204 return 0;
205
206 platform_driver_unregister(&qcom_cpufreq_kryo_driver);
207 return ret;
208}
209module_init(qcom_cpufreq_kryo_init);
210
211MODULE_DESCRIPTION("Qualcomm Technologies, Inc. Kryo CPUfreq driver");
212MODULE_LICENSE("GPL v2");
diff --git a/drivers/cpufreq/s3c2440-cpufreq.c b/drivers/cpufreq/s3c2440-cpufreq.c
index d0d75b65ddd6..d2f67b7a20dd 100644
--- a/drivers/cpufreq/s3c2440-cpufreq.c
+++ b/drivers/cpufreq/s3c2440-cpufreq.c
@@ -143,7 +143,7 @@ static void s3c2440_cpufreq_setdivs(struct s3c_cpufreq_config *cfg)
143{ 143{
144 unsigned long clkdiv, camdiv; 144 unsigned long clkdiv, camdiv;
145 145
146 s3c_freq_dbg("%s: divsiors: h=%d, p=%d\n", __func__, 146 s3c_freq_dbg("%s: divisors: h=%d, p=%d\n", __func__,
147 cfg->divs.h_divisor, cfg->divs.p_divisor); 147 cfg->divs.h_divisor, cfg->divs.p_divisor);
148 148
149 clkdiv = __raw_readl(S3C2410_CLKDIVN); 149 clkdiv = __raw_readl(S3C2410_CLKDIVN);
diff --git a/drivers/cpufreq/speedstep-lib.c b/drivers/cpufreq/speedstep-lib.c
index e3a9962ee410..cabb6f48eb77 100644
--- a/drivers/cpufreq/speedstep-lib.c
+++ b/drivers/cpufreq/speedstep-lib.c
@@ -252,7 +252,7 @@ EXPORT_SYMBOL_GPL(speedstep_get_frequency);
252 *********************************************************************/ 252 *********************************************************************/
253 253
254/* Keep in sync with the x86_cpu_id tables in the different modules */ 254/* Keep in sync with the x86_cpu_id tables in the different modules */
255unsigned int speedstep_detect_processor(void) 255enum speedstep_processor speedstep_detect_processor(void)
256{ 256{
257 struct cpuinfo_x86 *c = &cpu_data(0); 257 struct cpuinfo_x86 *c = &cpu_data(0);
258 u32 ebx, msr_lo, msr_hi; 258 u32 ebx, msr_lo, msr_hi;
diff --git a/drivers/cpufreq/tegra20-cpufreq.c b/drivers/cpufreq/tegra20-cpufreq.c
index 2bd62845e9d5..05f57dcd5215 100644
--- a/drivers/cpufreq/tegra20-cpufreq.c
+++ b/drivers/cpufreq/tegra20-cpufreq.c
@@ -16,16 +16,13 @@
16 * 16 *
17 */ 17 */
18 18
19#include <linux/kernel.h> 19#include <linux/clk.h>
20#include <linux/module.h>
21#include <linux/types.h>
22#include <linux/sched.h>
23#include <linux/cpufreq.h> 20#include <linux/cpufreq.h>
24#include <linux/delay.h>
25#include <linux/init.h>
26#include <linux/err.h> 21#include <linux/err.h>
27#include <linux/clk.h> 22#include <linux/init.h>
28#include <linux/io.h> 23#include <linux/module.h>
24#include <linux/platform_device.h>
25#include <linux/types.h>
29 26
30static struct cpufreq_frequency_table freq_table[] = { 27static struct cpufreq_frequency_table freq_table[] = {
31 { .frequency = 216000 }, 28 { .frequency = 216000 },
@@ -39,25 +36,27 @@ static struct cpufreq_frequency_table freq_table[] = {
39 { .frequency = CPUFREQ_TABLE_END }, 36 { .frequency = CPUFREQ_TABLE_END },
40}; 37};
41 38
42#define NUM_CPUS 2 39struct tegra20_cpufreq {
43 40 struct device *dev;
44static struct clk *cpu_clk; 41 struct cpufreq_driver driver;
45static struct clk *pll_x_clk; 42 struct clk *cpu_clk;
46static struct clk *pll_p_clk; 43 struct clk *pll_x_clk;
47static struct clk *emc_clk; 44 struct clk *pll_p_clk;
48static bool pll_x_prepared; 45 bool pll_x_prepared;
46};
49 47
50static unsigned int tegra_get_intermediate(struct cpufreq_policy *policy, 48static unsigned int tegra_get_intermediate(struct cpufreq_policy *policy,
51 unsigned int index) 49 unsigned int index)
52{ 50{
53 unsigned int ifreq = clk_get_rate(pll_p_clk) / 1000; 51 struct tegra20_cpufreq *cpufreq = cpufreq_get_driver_data();
52 unsigned int ifreq = clk_get_rate(cpufreq->pll_p_clk) / 1000;
54 53
55 /* 54 /*
56 * Don't switch to intermediate freq if: 55 * Don't switch to intermediate freq if:
57 * - we are already at it, i.e. policy->cur == ifreq 56 * - we are already at it, i.e. policy->cur == ifreq
58 * - index corresponds to ifreq 57 * - index corresponds to ifreq
59 */ 58 */
60 if ((freq_table[index].frequency == ifreq) || (policy->cur == ifreq)) 59 if (freq_table[index].frequency == ifreq || policy->cur == ifreq)
61 return 0; 60 return 0;
62 61
63 return ifreq; 62 return ifreq;
@@ -66,6 +65,7 @@ static unsigned int tegra_get_intermediate(struct cpufreq_policy *policy,
66static int tegra_target_intermediate(struct cpufreq_policy *policy, 65static int tegra_target_intermediate(struct cpufreq_policy *policy,
67 unsigned int index) 66 unsigned int index)
68{ 67{
68 struct tegra20_cpufreq *cpufreq = cpufreq_get_driver_data();
69 int ret; 69 int ret;
70 70
71 /* 71 /*
@@ -78,47 +78,37 @@ static int tegra_target_intermediate(struct cpufreq_policy *policy,
78 * Also, we wouldn't be using pll_x anymore and must not take extra 78 * Also, we wouldn't be using pll_x anymore and must not take extra
79 * reference to it, as it can be disabled now to save some power. 79 * reference to it, as it can be disabled now to save some power.
80 */ 80 */
81 clk_prepare_enable(pll_x_clk); 81 clk_prepare_enable(cpufreq->pll_x_clk);
82 82
83 ret = clk_set_parent(cpu_clk, pll_p_clk); 83 ret = clk_set_parent(cpufreq->cpu_clk, cpufreq->pll_p_clk);
84 if (ret) 84 if (ret)
85 clk_disable_unprepare(pll_x_clk); 85 clk_disable_unprepare(cpufreq->pll_x_clk);
86 else 86 else
87 pll_x_prepared = true; 87 cpufreq->pll_x_prepared = true;
88 88
89 return ret; 89 return ret;
90} 90}
91 91
92static int tegra_target(struct cpufreq_policy *policy, unsigned int index) 92static int tegra_target(struct cpufreq_policy *policy, unsigned int index)
93{ 93{
94 struct tegra20_cpufreq *cpufreq = cpufreq_get_driver_data();
94 unsigned long rate = freq_table[index].frequency; 95 unsigned long rate = freq_table[index].frequency;
95 unsigned int ifreq = clk_get_rate(pll_p_clk) / 1000; 96 unsigned int ifreq = clk_get_rate(cpufreq->pll_p_clk) / 1000;
96 int ret = 0; 97 int ret;
97
98 /*
99 * Vote on memory bus frequency based on cpu frequency
100 * This sets the minimum frequency, display or avp may request higher
101 */
102 if (rate >= 816000)
103 clk_set_rate(emc_clk, 600000000); /* cpu 816 MHz, emc max */
104 else if (rate >= 456000)
105 clk_set_rate(emc_clk, 300000000); /* cpu 456 MHz, emc 150Mhz */
106 else
107 clk_set_rate(emc_clk, 100000000); /* emc 50Mhz */
108 98
109 /* 99 /*
110 * target freq == pll_p, don't need to take extra reference to pll_x_clk 100 * target freq == pll_p, don't need to take extra reference to pll_x_clk
111 * as it isn't used anymore. 101 * as it isn't used anymore.
112 */ 102 */
113 if (rate == ifreq) 103 if (rate == ifreq)
114 return clk_set_parent(cpu_clk, pll_p_clk); 104 return clk_set_parent(cpufreq->cpu_clk, cpufreq->pll_p_clk);
115 105
116 ret = clk_set_rate(pll_x_clk, rate * 1000); 106 ret = clk_set_rate(cpufreq->pll_x_clk, rate * 1000);
117 /* Restore to earlier frequency on error, i.e. pll_x */ 107 /* Restore to earlier frequency on error, i.e. pll_x */
118 if (ret) 108 if (ret)
119 pr_err("Failed to change pll_x to %lu\n", rate); 109 dev_err(cpufreq->dev, "Failed to change pll_x to %lu\n", rate);
120 110
121 ret = clk_set_parent(cpu_clk, pll_x_clk); 111 ret = clk_set_parent(cpufreq->cpu_clk, cpufreq->pll_x_clk);
122 /* This shouldn't fail while changing or restoring */ 112 /* This shouldn't fail while changing or restoring */
123 WARN_ON(ret); 113 WARN_ON(ret);
124 114
@@ -126,9 +116,9 @@ static int tegra_target(struct cpufreq_policy *policy, unsigned int index)
126 * Drop count to pll_x clock only if we switched to intermediate freq 116 * Drop count to pll_x clock only if we switched to intermediate freq
127 * earlier while transitioning to a target frequency. 117 * earlier while transitioning to a target frequency.
128 */ 118 */
129 if (pll_x_prepared) { 119 if (cpufreq->pll_x_prepared) {
130 clk_disable_unprepare(pll_x_clk); 120 clk_disable_unprepare(cpufreq->pll_x_clk);
131 pll_x_prepared = false; 121 cpufreq->pll_x_prepared = false;
132 } 122 }
133 123
134 return ret; 124 return ret;
@@ -136,81 +126,111 @@ static int tegra_target(struct cpufreq_policy *policy, unsigned int index)
136 126
137static int tegra_cpu_init(struct cpufreq_policy *policy) 127static int tegra_cpu_init(struct cpufreq_policy *policy)
138{ 128{
129 struct tegra20_cpufreq *cpufreq = cpufreq_get_driver_data();
139 int ret; 130 int ret;
140 131
141 if (policy->cpu >= NUM_CPUS) 132 clk_prepare_enable(cpufreq->cpu_clk);
142 return -EINVAL;
143
144 clk_prepare_enable(emc_clk);
145 clk_prepare_enable(cpu_clk);
146 133
147 /* FIXME: what's the actual transition time? */ 134 /* FIXME: what's the actual transition time? */
148 ret = cpufreq_generic_init(policy, freq_table, 300 * 1000); 135 ret = cpufreq_generic_init(policy, freq_table, 300 * 1000);
149 if (ret) { 136 if (ret) {
150 clk_disable_unprepare(cpu_clk); 137 clk_disable_unprepare(cpufreq->cpu_clk);
151 clk_disable_unprepare(emc_clk);
152 return ret; 138 return ret;
153 } 139 }
154 140
155 policy->clk = cpu_clk; 141 policy->clk = cpufreq->cpu_clk;
156 policy->suspend_freq = freq_table[0].frequency; 142 policy->suspend_freq = freq_table[0].frequency;
157 return 0; 143 return 0;
158} 144}
159 145
160static int tegra_cpu_exit(struct cpufreq_policy *policy) 146static int tegra_cpu_exit(struct cpufreq_policy *policy)
161{ 147{
162 clk_disable_unprepare(cpu_clk); 148 struct tegra20_cpufreq *cpufreq = cpufreq_get_driver_data();
163 clk_disable_unprepare(emc_clk); 149
150 clk_disable_unprepare(cpufreq->cpu_clk);
164 return 0; 151 return 0;
165} 152}
166 153
167static struct cpufreq_driver tegra_cpufreq_driver = { 154static int tegra20_cpufreq_probe(struct platform_device *pdev)
168 .flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK,
169 .verify = cpufreq_generic_frequency_table_verify,
170 .get_intermediate = tegra_get_intermediate,
171 .target_intermediate = tegra_target_intermediate,
172 .target_index = tegra_target,
173 .get = cpufreq_generic_get,
174 .init = tegra_cpu_init,
175 .exit = tegra_cpu_exit,
176 .name = "tegra",
177 .attr = cpufreq_generic_attr,
178 .suspend = cpufreq_generic_suspend,
179};
180
181static int __init tegra_cpufreq_init(void)
182{ 155{
183 cpu_clk = clk_get_sys(NULL, "cclk"); 156 struct tegra20_cpufreq *cpufreq;
184 if (IS_ERR(cpu_clk)) 157 int err;
185 return PTR_ERR(cpu_clk); 158
186 159 cpufreq = devm_kzalloc(&pdev->dev, sizeof(*cpufreq), GFP_KERNEL);
187 pll_x_clk = clk_get_sys(NULL, "pll_x"); 160 if (!cpufreq)
188 if (IS_ERR(pll_x_clk)) 161 return -ENOMEM;
189 return PTR_ERR(pll_x_clk); 162
190 163 cpufreq->cpu_clk = clk_get_sys(NULL, "cclk");
191 pll_p_clk = clk_get_sys(NULL, "pll_p"); 164 if (IS_ERR(cpufreq->cpu_clk))
192 if (IS_ERR(pll_p_clk)) 165 return PTR_ERR(cpufreq->cpu_clk);
193 return PTR_ERR(pll_p_clk); 166
194 167 cpufreq->pll_x_clk = clk_get_sys(NULL, "pll_x");
195 emc_clk = clk_get_sys("cpu", "emc"); 168 if (IS_ERR(cpufreq->pll_x_clk)) {
196 if (IS_ERR(emc_clk)) { 169 err = PTR_ERR(cpufreq->pll_x_clk);
197 clk_put(cpu_clk); 170 goto put_cpu;
198 return PTR_ERR(emc_clk); 171 }
172
173 cpufreq->pll_p_clk = clk_get_sys(NULL, "pll_p");
174 if (IS_ERR(cpufreq->pll_p_clk)) {
175 err = PTR_ERR(cpufreq->pll_p_clk);
176 goto put_pll_x;
199 } 177 }
200 178
201 return cpufreq_register_driver(&tegra_cpufreq_driver); 179 cpufreq->dev = &pdev->dev;
180 cpufreq->driver.get = cpufreq_generic_get;
181 cpufreq->driver.attr = cpufreq_generic_attr;
182 cpufreq->driver.init = tegra_cpu_init;
183 cpufreq->driver.exit = tegra_cpu_exit;
184 cpufreq->driver.flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK;
185 cpufreq->driver.verify = cpufreq_generic_frequency_table_verify;
186 cpufreq->driver.suspend = cpufreq_generic_suspend;
187 cpufreq->driver.driver_data = cpufreq;
188 cpufreq->driver.target_index = tegra_target;
189 cpufreq->driver.get_intermediate = tegra_get_intermediate;
190 cpufreq->driver.target_intermediate = tegra_target_intermediate;
191 snprintf(cpufreq->driver.name, CPUFREQ_NAME_LEN, "tegra");
192
193 err = cpufreq_register_driver(&cpufreq->driver);
194 if (err)
195 goto put_pll_p;
196
197 platform_set_drvdata(pdev, cpufreq);
198
199 return 0;
200
201put_pll_p:
202 clk_put(cpufreq->pll_p_clk);
203put_pll_x:
204 clk_put(cpufreq->pll_x_clk);
205put_cpu:
206 clk_put(cpufreq->cpu_clk);
207
208 return err;
202} 209}
203 210
204static void __exit tegra_cpufreq_exit(void) 211static int tegra20_cpufreq_remove(struct platform_device *pdev)
205{ 212{
206 cpufreq_unregister_driver(&tegra_cpufreq_driver); 213 struct tegra20_cpufreq *cpufreq = platform_get_drvdata(pdev);
207 clk_put(emc_clk); 214
208 clk_put(cpu_clk); 215 cpufreq_unregister_driver(&cpufreq->driver);
216
217 clk_put(cpufreq->pll_p_clk);
218 clk_put(cpufreq->pll_x_clk);
219 clk_put(cpufreq->cpu_clk);
220
221 return 0;
209} 222}
210 223
224static struct platform_driver tegra20_cpufreq_driver = {
225 .probe = tegra20_cpufreq_probe,
226 .remove = tegra20_cpufreq_remove,
227 .driver = {
228 .name = "tegra20-cpufreq",
229 },
230};
231module_platform_driver(tegra20_cpufreq_driver);
211 232
233MODULE_ALIAS("platform:tegra20-cpufreq");
212MODULE_AUTHOR("Colin Cross <ccross@android.com>"); 234MODULE_AUTHOR("Colin Cross <ccross@android.com>");
213MODULE_DESCRIPTION("cpufreq driver for Nvidia Tegra2"); 235MODULE_DESCRIPTION("NVIDIA Tegra20 cpufreq driver");
214MODULE_LICENSE("GPL"); 236MODULE_LICENSE("GPL");
215module_init(tegra_cpufreq_init);
216module_exit(tegra_cpufreq_exit);
diff --git a/include/linux/notifier.h b/include/linux/notifier.h
index 6d731110e0db..f35c7bf76143 100644
--- a/include/linux/notifier.h
+++ b/include/linux/notifier.h
@@ -43,9 +43,7 @@
43 * in srcu_notifier_call_chain(): no cache bounces and no memory barriers. 43 * in srcu_notifier_call_chain(): no cache bounces and no memory barriers.
44 * As compensation, srcu_notifier_chain_unregister() is rather expensive. 44 * As compensation, srcu_notifier_chain_unregister() is rather expensive.
45 * SRCU notifier chains should be used when the chain will be called very 45 * SRCU notifier chains should be used when the chain will be called very
46 * often but notifier_blocks will seldom be removed. Also, SRCU notifier 46 * often but notifier_blocks will seldom be removed.
47 * chains are slightly more difficult to use because they require special
48 * runtime initialization.
49 */ 47 */
50 48
51struct notifier_block; 49struct notifier_block;
@@ -91,7 +89,7 @@ struct srcu_notifier_head {
91 (name)->head = NULL; \ 89 (name)->head = NULL; \
92 } while (0) 90 } while (0)
93 91
94/* srcu_notifier_heads must be initialized and cleaned up dynamically */ 92/* srcu_notifier_heads must be cleaned up dynamically */
95extern void srcu_init_notifier_head(struct srcu_notifier_head *nh); 93extern void srcu_init_notifier_head(struct srcu_notifier_head *nh);
96#define srcu_cleanup_notifier_head(name) \ 94#define srcu_cleanup_notifier_head(name) \
97 cleanup_srcu_struct(&(name)->srcu); 95 cleanup_srcu_struct(&(name)->srcu);
@@ -104,7 +102,13 @@ extern void srcu_init_notifier_head(struct srcu_notifier_head *nh);
104 .head = NULL } 102 .head = NULL }
105#define RAW_NOTIFIER_INIT(name) { \ 103#define RAW_NOTIFIER_INIT(name) { \
106 .head = NULL } 104 .head = NULL }
107/* srcu_notifier_heads cannot be initialized statically */ 105
106#define SRCU_NOTIFIER_INIT(name, pcpu) \
107 { \
108 .mutex = __MUTEX_INITIALIZER(name.mutex), \
109 .head = NULL, \
110 .srcu = __SRCU_STRUCT_INIT(name.srcu, pcpu), \
111 }
108 112
109#define ATOMIC_NOTIFIER_HEAD(name) \ 113#define ATOMIC_NOTIFIER_HEAD(name) \
110 struct atomic_notifier_head name = \ 114 struct atomic_notifier_head name = \
@@ -116,6 +120,26 @@ extern void srcu_init_notifier_head(struct srcu_notifier_head *nh);
116 struct raw_notifier_head name = \ 120 struct raw_notifier_head name = \
117 RAW_NOTIFIER_INIT(name) 121 RAW_NOTIFIER_INIT(name)
118 122
123#ifdef CONFIG_TREE_SRCU
124#define _SRCU_NOTIFIER_HEAD(name, mod) \
125 static DEFINE_PER_CPU(struct srcu_data, \
126 name##_head_srcu_data); \
127 mod struct srcu_notifier_head name = \
128 SRCU_NOTIFIER_INIT(name, name##_head_srcu_data)
129
130#else
131#define _SRCU_NOTIFIER_HEAD(name, mod) \
132 mod struct srcu_notifier_head name = \
133 SRCU_NOTIFIER_INIT(name, name)
134
135#endif
136
137#define SRCU_NOTIFIER_HEAD(name) \
138 _SRCU_NOTIFIER_HEAD(name, /* not static */)
139
140#define SRCU_NOTIFIER_HEAD_STATIC(name) \
141 _SRCU_NOTIFIER_HEAD(name, static)
142
119#ifdef __KERNEL__ 143#ifdef __KERNEL__
120 144
121extern int atomic_notifier_chain_register(struct atomic_notifier_head *nh, 145extern int atomic_notifier_chain_register(struct atomic_notifier_head *nh,
diff --git a/include/linux/srcutiny.h b/include/linux/srcutiny.h
index 261471f407a5..f41d2fb09f87 100644
--- a/include/linux/srcutiny.h
+++ b/include/linux/srcutiny.h
@@ -43,7 +43,7 @@ struct srcu_struct {
43 43
44void srcu_drive_gp(struct work_struct *wp); 44void srcu_drive_gp(struct work_struct *wp);
45 45
46#define __SRCU_STRUCT_INIT(name) \ 46#define __SRCU_STRUCT_INIT(name, __ignored) \
47{ \ 47{ \
48 .srcu_wq = __SWAIT_QUEUE_HEAD_INITIALIZER(name.srcu_wq), \ 48 .srcu_wq = __SWAIT_QUEUE_HEAD_INITIALIZER(name.srcu_wq), \
49 .srcu_cb_tail = &name.srcu_cb_head, \ 49 .srcu_cb_tail = &name.srcu_cb_head, \
@@ -56,9 +56,9 @@ void srcu_drive_gp(struct work_struct *wp);
56 * Tree SRCU, which needs some per-CPU data. 56 * Tree SRCU, which needs some per-CPU data.
57 */ 57 */
58#define DEFINE_SRCU(name) \ 58#define DEFINE_SRCU(name) \
59 struct srcu_struct name = __SRCU_STRUCT_INIT(name) 59 struct srcu_struct name = __SRCU_STRUCT_INIT(name, name)
60#define DEFINE_STATIC_SRCU(name) \ 60#define DEFINE_STATIC_SRCU(name) \
61 static struct srcu_struct name = __SRCU_STRUCT_INIT(name) 61 static struct srcu_struct name = __SRCU_STRUCT_INIT(name, name)
62 62
63void synchronize_srcu(struct srcu_struct *sp); 63void synchronize_srcu(struct srcu_struct *sp);
64 64
diff --git a/include/linux/srcutree.h b/include/linux/srcutree.h
index 4eda108abee0..745d4ca4dd50 100644
--- a/include/linux/srcutree.h
+++ b/include/linux/srcutree.h
@@ -104,9 +104,9 @@ struct srcu_struct {
104#define SRCU_STATE_SCAN1 1 104#define SRCU_STATE_SCAN1 1
105#define SRCU_STATE_SCAN2 2 105#define SRCU_STATE_SCAN2 2
106 106
107#define __SRCU_STRUCT_INIT(name) \ 107#define __SRCU_STRUCT_INIT(name, pcpu_name) \
108 { \ 108 { \
109 .sda = &name##_srcu_data, \ 109 .sda = &pcpu_name, \
110 .lock = __SPIN_LOCK_UNLOCKED(name.lock), \ 110 .lock = __SPIN_LOCK_UNLOCKED(name.lock), \
111 .srcu_gp_seq_needed = 0 - 1, \ 111 .srcu_gp_seq_needed = 0 - 1, \
112 __SRCU_DEP_MAP_INIT(name) \ 112 __SRCU_DEP_MAP_INIT(name) \
@@ -133,7 +133,7 @@ struct srcu_struct {
133 */ 133 */
134#define __DEFINE_SRCU(name, is_static) \ 134#define __DEFINE_SRCU(name, is_static) \
135 static DEFINE_PER_CPU(struct srcu_data, name##_srcu_data);\ 135 static DEFINE_PER_CPU(struct srcu_data, name##_srcu_data);\
136 is_static struct srcu_struct name = __SRCU_STRUCT_INIT(name) 136 is_static struct srcu_struct name = __SRCU_STRUCT_INIT(name, name##_srcu_data)
137#define DEFINE_SRCU(name) __DEFINE_SRCU(name, /* not static */) 137#define DEFINE_SRCU(name) __DEFINE_SRCU(name, /* not static */)
138#define DEFINE_STATIC_SRCU(name) __DEFINE_SRCU(name, static) 138#define DEFINE_STATIC_SRCU(name) __DEFINE_SRCU(name, static)
139 139