]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/base/power/opp/of.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
[karo-tx-linux.git] / drivers / base / power / opp / of.c
1 /*
2  * Generic OPP OF helpers
3  *
4  * Copyright (C) 2009-2010 Texas Instruments Incorporated.
5  *      Nishanth Menon
6  *      Romit Dasgupta
7  *      Kevin Hilman
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License version 2 as
11  * published by the Free Software Foundation.
12  */
13
14 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
15
16 #include <linux/cpu.h>
17 #include <linux/errno.h>
18 #include <linux/device.h>
19 #include <linux/of.h>
20 #include <linux/export.h>
21
22 #include "opp.h"
23
24 static struct opp_table *_managed_opp(const struct device_node *np)
25 {
26         struct opp_table *opp_table;
27
28         list_for_each_entry_rcu(opp_table, &opp_tables, node) {
29                 if (opp_table->np == np) {
30                         /*
31                          * Multiple devices can point to the same OPP table and
32                          * so will have same node-pointer, np.
33                          *
34                          * But the OPPs will be considered as shared only if the
35                          * OPP table contains a "opp-shared" property.
36                          */
37                         if (opp_table->shared_opp == OPP_TABLE_ACCESS_SHARED)
38                                 return opp_table;
39
40                         return NULL;
41                 }
42         }
43
44         return NULL;
45 }
46
47 void _of_init_opp_table(struct opp_table *opp_table, struct device *dev)
48 {
49         struct device_node *np;
50
51         /*
52          * Only required for backward compatibility with v1 bindings, but isn't
53          * harmful for other cases. And so we do it unconditionally.
54          */
55         np = of_node_get(dev->of_node);
56         if (np) {
57                 u32 val;
58
59                 if (!of_property_read_u32(np, "clock-latency", &val))
60                         opp_table->clock_latency_ns_max = val;
61                 of_property_read_u32(np, "voltage-tolerance",
62                                      &opp_table->voltage_tolerance_v1);
63                 of_node_put(np);
64         }
65 }
66
67 static bool _opp_is_supported(struct device *dev, struct opp_table *opp_table,
68                               struct device_node *np)
69 {
70         unsigned int count = opp_table->supported_hw_count;
71         u32 version;
72         int ret;
73
74         if (!opp_table->supported_hw)
75                 return true;
76
77         while (count--) {
78                 ret = of_property_read_u32_index(np, "opp-supported-hw", count,
79                                                  &version);
80                 if (ret) {
81                         dev_warn(dev, "%s: failed to read opp-supported-hw property at index %d: %d\n",
82                                  __func__, count, ret);
83                         return false;
84                 }
85
86                 /* Both of these are bitwise masks of the versions */
87                 if (!(version & opp_table->supported_hw[count]))
88                         return false;
89         }
90
91         return true;
92 }
93
94 /* TODO: Support multiple regulators */
95 static int opp_parse_supplies(struct dev_pm_opp *opp, struct device *dev,
96                               struct opp_table *opp_table)
97 {
98         u32 microvolt[3] = {0};
99         u32 val;
100         int count, ret;
101         struct property *prop = NULL;
102         char name[NAME_MAX];
103
104         /* Search for "opp-microvolt-<name>" */
105         if (opp_table->prop_name) {
106                 snprintf(name, sizeof(name), "opp-microvolt-%s",
107                          opp_table->prop_name);
108                 prop = of_find_property(opp->np, name, NULL);
109         }
110
111         if (!prop) {
112                 /* Search for "opp-microvolt" */
113                 sprintf(name, "opp-microvolt");
114                 prop = of_find_property(opp->np, name, NULL);
115
116                 /* Missing property isn't a problem, but an invalid entry is */
117                 if (!prop)
118                         return 0;
119         }
120
121         count = of_property_count_u32_elems(opp->np, name);
122         if (count < 0) {
123                 dev_err(dev, "%s: Invalid %s property (%d)\n",
124                         __func__, name, count);
125                 return count;
126         }
127
128         /* There can be one or three elements here */
129         if (count != 1 && count != 3) {
130                 dev_err(dev, "%s: Invalid number of elements in %s property (%d)\n",
131                         __func__, name, count);
132                 return -EINVAL;
133         }
134
135         ret = of_property_read_u32_array(opp->np, name, microvolt, count);
136         if (ret) {
137                 dev_err(dev, "%s: error parsing %s: %d\n", __func__, name, ret);
138                 return -EINVAL;
139         }
140
141         opp->u_volt = microvolt[0];
142
143         if (count == 1) {
144                 opp->u_volt_min = opp->u_volt;
145                 opp->u_volt_max = opp->u_volt;
146         } else {
147                 opp->u_volt_min = microvolt[1];
148                 opp->u_volt_max = microvolt[2];
149         }
150
151         /* Search for "opp-microamp-<name>" */
152         prop = NULL;
153         if (opp_table->prop_name) {
154                 snprintf(name, sizeof(name), "opp-microamp-%s",
155                          opp_table->prop_name);
156                 prop = of_find_property(opp->np, name, NULL);
157         }
158
159         if (!prop) {
160                 /* Search for "opp-microamp" */
161                 sprintf(name, "opp-microamp");
162                 prop = of_find_property(opp->np, name, NULL);
163         }
164
165         if (prop && !of_property_read_u32(opp->np, name, &val))
166                 opp->u_amp = val;
167
168         return 0;
169 }
170
171 /**
172  * dev_pm_opp_of_remove_table() - Free OPP table entries created from static DT
173  *                                entries
174  * @dev:        device pointer used to lookup OPP table.
175  *
176  * Free OPPs created using static entries present in DT.
177  *
178  * Locking: The internal opp_table and opp structures are RCU protected.
179  * Hence this function indirectly uses RCU updater strategy with mutex locks
180  * to keep the integrity of the internal data structures. Callers should ensure
181  * that this function is *NOT* called under RCU protection or in contexts where
182  * mutex cannot be locked.
183  */
184 void dev_pm_opp_of_remove_table(struct device *dev)
185 {
186         _dev_pm_opp_remove_table(dev, false);
187 }
188 EXPORT_SYMBOL_GPL(dev_pm_opp_of_remove_table);
189
190 /* Returns opp descriptor node for a device, caller must do of_node_put() */
191 struct device_node *_of_get_opp_desc_node(struct device *dev)
192 {
193         /*
194          * TODO: Support for multiple OPP tables.
195          *
196          * There should be only ONE phandle present in "operating-points-v2"
197          * property.
198          */
199
200         return of_parse_phandle(dev->of_node, "operating-points-v2", 0);
201 }
202
203 /**
204  * _opp_add_static_v2() - Allocate static OPPs (As per 'v2' DT bindings)
205  * @dev:        device for which we do this operation
206  * @np:         device node
207  *
208  * This function adds an opp definition to the opp table and returns status. The
209  * opp can be controlled using dev_pm_opp_enable/disable functions and may be
210  * removed by dev_pm_opp_remove.
211  *
212  * Locking: The internal opp_table and opp structures are RCU protected.
213  * Hence this function internally uses RCU updater strategy with mutex locks
214  * to keep the integrity of the internal data structures. Callers should ensure
215  * that this function is *NOT* called under RCU protection or in contexts where
216  * mutex cannot be locked.
217  *
218  * Return:
219  * 0            On success OR
220  *              Duplicate OPPs (both freq and volt are same) and opp->available
221  * -EEXIST      Freq are same and volt are different OR
222  *              Duplicate OPPs (both freq and volt are same) and !opp->available
223  * -ENOMEM      Memory allocation failure
224  * -EINVAL      Failed parsing the OPP node
225  */
226 static int _opp_add_static_v2(struct device *dev, struct device_node *np)
227 {
228         struct opp_table *opp_table;
229         struct dev_pm_opp *new_opp;
230         u64 rate;
231         u32 val;
232         int ret;
233
234         /* Hold our table modification lock here */
235         mutex_lock(&opp_table_lock);
236
237         new_opp = _allocate_opp(dev, &opp_table);
238         if (!new_opp) {
239                 ret = -ENOMEM;
240                 goto unlock;
241         }
242
243         ret = of_property_read_u64(np, "opp-hz", &rate);
244         if (ret < 0) {
245                 dev_err(dev, "%s: opp-hz not found\n", __func__);
246                 goto free_opp;
247         }
248
249         /* Check if the OPP supports hardware's hierarchy of versions or not */
250         if (!_opp_is_supported(dev, opp_table, np)) {
251                 dev_dbg(dev, "OPP not supported by hardware: %llu\n", rate);
252                 goto free_opp;
253         }
254
255         /*
256          * Rate is defined as an unsigned long in clk API, and so casting
257          * explicitly to its type. Must be fixed once rate is 64 bit
258          * guaranteed in clk API.
259          */
260         new_opp->rate = (unsigned long)rate;
261         new_opp->turbo = of_property_read_bool(np, "turbo-mode");
262
263         new_opp->np = np;
264         new_opp->dynamic = false;
265         new_opp->available = true;
266
267         if (!of_property_read_u32(np, "clock-latency-ns", &val))
268                 new_opp->clock_latency_ns = val;
269
270         ret = opp_parse_supplies(new_opp, dev, opp_table);
271         if (ret)
272                 goto free_opp;
273
274         ret = _opp_add(dev, new_opp, opp_table);
275         if (ret)
276                 goto free_opp;
277
278         /* OPP to select on device suspend */
279         if (of_property_read_bool(np, "opp-suspend")) {
280                 if (opp_table->suspend_opp) {
281                         dev_warn(dev, "%s: Multiple suspend OPPs found (%lu %lu)\n",
282                                  __func__, opp_table->suspend_opp->rate,
283                                  new_opp->rate);
284                 } else {
285                         new_opp->suspend = true;
286                         opp_table->suspend_opp = new_opp;
287                 }
288         }
289
290         if (new_opp->clock_latency_ns > opp_table->clock_latency_ns_max)
291                 opp_table->clock_latency_ns_max = new_opp->clock_latency_ns;
292
293         mutex_unlock(&opp_table_lock);
294
295         pr_debug("%s: turbo:%d rate:%lu uv:%lu uvmin:%lu uvmax:%lu latency:%lu\n",
296                  __func__, new_opp->turbo, new_opp->rate, new_opp->u_volt,
297                  new_opp->u_volt_min, new_opp->u_volt_max,
298                  new_opp->clock_latency_ns);
299
300         /*
301          * Notify the changes in the availability of the operable
302          * frequency/voltage list.
303          */
304         srcu_notifier_call_chain(&opp_table->srcu_head, OPP_EVENT_ADD, new_opp);
305         return 0;
306
307 free_opp:
308         _opp_remove(opp_table, new_opp, false);
309 unlock:
310         mutex_unlock(&opp_table_lock);
311         return ret;
312 }
313
314 /* Initializes OPP tables based on new bindings */
315 static int _of_add_opp_table_v2(struct device *dev, struct device_node *opp_np)
316 {
317         struct device_node *np;
318         struct opp_table *opp_table;
319         int ret = 0, count = 0;
320
321         mutex_lock(&opp_table_lock);
322
323         opp_table = _managed_opp(opp_np);
324         if (opp_table) {
325                 /* OPPs are already managed */
326                 if (!_add_opp_dev(dev, opp_table))
327                         ret = -ENOMEM;
328                 mutex_unlock(&opp_table_lock);
329                 return ret;
330         }
331         mutex_unlock(&opp_table_lock);
332
333         /* We have opp-table node now, iterate over it and add OPPs */
334         for_each_available_child_of_node(opp_np, np) {
335                 count++;
336
337                 ret = _opp_add_static_v2(dev, np);
338                 if (ret) {
339                         dev_err(dev, "%s: Failed to add OPP, %d\n", __func__,
340                                 ret);
341                         goto free_table;
342                 }
343         }
344
345         /* There should be one of more OPP defined */
346         if (WARN_ON(!count))
347                 return -ENOENT;
348
349         mutex_lock(&opp_table_lock);
350
351         opp_table = _find_opp_table(dev);
352         if (WARN_ON(IS_ERR(opp_table))) {
353                 ret = PTR_ERR(opp_table);
354                 mutex_unlock(&opp_table_lock);
355                 goto free_table;
356         }
357
358         opp_table->np = opp_np;
359         if (of_property_read_bool(opp_np, "opp-shared"))
360                 opp_table->shared_opp = OPP_TABLE_ACCESS_SHARED;
361         else
362                 opp_table->shared_opp = OPP_TABLE_ACCESS_EXCLUSIVE;
363
364         mutex_unlock(&opp_table_lock);
365
366         return 0;
367
368 free_table:
369         dev_pm_opp_of_remove_table(dev);
370
371         return ret;
372 }
373
374 /* Initializes OPP tables based on old-deprecated bindings */
375 static int _of_add_opp_table_v1(struct device *dev)
376 {
377         const struct property *prop;
378         const __be32 *val;
379         int nr;
380
381         prop = of_find_property(dev->of_node, "operating-points", NULL);
382         if (!prop)
383                 return -ENODEV;
384         if (!prop->value)
385                 return -ENODATA;
386
387         /*
388          * Each OPP is a set of tuples consisting of frequency and
389          * voltage like <freq-kHz vol-uV>.
390          */
391         nr = prop->length / sizeof(u32);
392         if (nr % 2) {
393                 dev_err(dev, "%s: Invalid OPP table\n", __func__);
394                 return -EINVAL;
395         }
396
397         val = prop->value;
398         while (nr) {
399                 unsigned long freq = be32_to_cpup(val++) * 1000;
400                 unsigned long volt = be32_to_cpup(val++);
401
402                 if (_opp_add_v1(dev, freq, volt, false))
403                         dev_warn(dev, "%s: Failed to add OPP %ld\n",
404                                  __func__, freq);
405                 nr -= 2;
406         }
407
408         return 0;
409 }
410
411 /**
412  * dev_pm_opp_of_add_table() - Initialize opp table from device tree
413  * @dev:        device pointer used to lookup OPP table.
414  *
415  * Register the initial OPP table with the OPP library for given device.
416  *
417  * Locking: The internal opp_table and opp structures are RCU protected.
418  * Hence this function indirectly uses RCU updater strategy with mutex locks
419  * to keep the integrity of the internal data structures. Callers should ensure
420  * that this function is *NOT* called under RCU protection or in contexts where
421  * mutex cannot be locked.
422  *
423  * Return:
424  * 0            On success OR
425  *              Duplicate OPPs (both freq and volt are same) and opp->available
426  * -EEXIST      Freq are same and volt are different OR
427  *              Duplicate OPPs (both freq and volt are same) and !opp->available
428  * -ENOMEM      Memory allocation failure
429  * -ENODEV      when 'operating-points' property is not found or is invalid data
430  *              in device node.
431  * -ENODATA     when empty 'operating-points' property is found
432  * -EINVAL      when invalid entries are found in opp-v2 table
433  */
434 int dev_pm_opp_of_add_table(struct device *dev)
435 {
436         struct device_node *opp_np;
437         int ret;
438
439         /*
440          * OPPs have two version of bindings now. The older one is deprecated,
441          * try for the new binding first.
442          */
443         opp_np = _of_get_opp_desc_node(dev);
444         if (!opp_np) {
445                 /*
446                  * Try old-deprecated bindings for backward compatibility with
447                  * older dtbs.
448                  */
449                 return _of_add_opp_table_v1(dev);
450         }
451
452         ret = _of_add_opp_table_v2(dev, opp_np);
453         of_node_put(opp_np);
454
455         return ret;
456 }
457 EXPORT_SYMBOL_GPL(dev_pm_opp_of_add_table);
458
459 /* CPU device specific helpers */
460
461 /**
462  * dev_pm_opp_of_cpumask_remove_table() - Removes OPP table for @cpumask
463  * @cpumask:    cpumask for which OPP table needs to be removed
464  *
465  * This removes the OPP tables for CPUs present in the @cpumask.
466  * This should be used only to remove static entries created from DT.
467  *
468  * Locking: The internal opp_table and opp structures are RCU protected.
469  * Hence this function internally uses RCU updater strategy with mutex locks
470  * to keep the integrity of the internal data structures. Callers should ensure
471  * that this function is *NOT* called under RCU protection or in contexts where
472  * mutex cannot be locked.
473  */
474 void dev_pm_opp_of_cpumask_remove_table(const struct cpumask *cpumask)
475 {
476         _dev_pm_opp_cpumask_remove_table(cpumask, true);
477 }
478 EXPORT_SYMBOL_GPL(dev_pm_opp_of_cpumask_remove_table);
479
480 /**
481  * dev_pm_opp_of_cpumask_add_table() - Adds OPP table for @cpumask
482  * @cpumask:    cpumask for which OPP table needs to be added.
483  *
484  * This adds the OPP tables for CPUs present in the @cpumask.
485  *
486  * Locking: The internal opp_table and opp structures are RCU protected.
487  * Hence this function internally uses RCU updater strategy with mutex locks
488  * to keep the integrity of the internal data structures. Callers should ensure
489  * that this function is *NOT* called under RCU protection or in contexts where
490  * mutex cannot be locked.
491  */
492 int dev_pm_opp_of_cpumask_add_table(const struct cpumask *cpumask)
493 {
494         struct device *cpu_dev;
495         int cpu, ret = 0;
496
497         WARN_ON(cpumask_empty(cpumask));
498
499         for_each_cpu(cpu, cpumask) {
500                 cpu_dev = get_cpu_device(cpu);
501                 if (!cpu_dev) {
502                         pr_err("%s: failed to get cpu%d device\n", __func__,
503                                cpu);
504                         continue;
505                 }
506
507                 ret = dev_pm_opp_of_add_table(cpu_dev);
508                 if (ret) {
509                         pr_err("%s: couldn't find opp table for cpu:%d, %d\n",
510                                __func__, cpu, ret);
511
512                         /* Free all other OPPs */
513                         dev_pm_opp_of_cpumask_remove_table(cpumask);
514                         break;
515                 }
516         }
517
518         return ret;
519 }
520 EXPORT_SYMBOL_GPL(dev_pm_opp_of_cpumask_add_table);
521
522 /*
523  * Works only for OPP v2 bindings.
524  *
525  * Returns -ENOENT if operating-points-v2 bindings aren't supported.
526  */
527 /**
528  * dev_pm_opp_of_get_sharing_cpus() - Get cpumask of CPUs sharing OPPs with
529  *                                    @cpu_dev using operating-points-v2
530  *                                    bindings.
531  *
532  * @cpu_dev:    CPU device for which we do this operation
533  * @cpumask:    cpumask to update with information of sharing CPUs
534  *
535  * This updates the @cpumask with CPUs that are sharing OPPs with @cpu_dev.
536  *
537  * Returns -ENOENT if operating-points-v2 isn't present for @cpu_dev.
538  *
539  * Locking: The internal opp_table and opp structures are RCU protected.
540  * Hence this function internally uses RCU updater strategy with mutex locks
541  * to keep the integrity of the internal data structures. Callers should ensure
542  * that this function is *NOT* called under RCU protection or in contexts where
543  * mutex cannot be locked.
544  */
545 int dev_pm_opp_of_get_sharing_cpus(struct device *cpu_dev,
546                                    struct cpumask *cpumask)
547 {
548         struct device_node *np, *tmp_np;
549         struct device *tcpu_dev;
550         int cpu, ret = 0;
551
552         /* Get OPP descriptor node */
553         np = _of_get_opp_desc_node(cpu_dev);
554         if (!np) {
555                 dev_dbg(cpu_dev, "%s: Couldn't find cpu_dev node.\n", __func__);
556                 return -ENOENT;
557         }
558
559         cpumask_set_cpu(cpu_dev->id, cpumask);
560
561         /* OPPs are shared ? */
562         if (!of_property_read_bool(np, "opp-shared"))
563                 goto put_cpu_node;
564
565         for_each_possible_cpu(cpu) {
566                 if (cpu == cpu_dev->id)
567                         continue;
568
569                 tcpu_dev = get_cpu_device(cpu);
570                 if (!tcpu_dev) {
571                         dev_err(cpu_dev, "%s: failed to get cpu%d device\n",
572                                 __func__, cpu);
573                         ret = -ENODEV;
574                         goto put_cpu_node;
575                 }
576
577                 /* Get OPP descriptor node */
578                 tmp_np = _of_get_opp_desc_node(tcpu_dev);
579                 if (!tmp_np) {
580                         dev_err(tcpu_dev, "%s: Couldn't find tcpu_dev node.\n",
581                                 __func__);
582                         ret = -ENOENT;
583                         goto put_cpu_node;
584                 }
585
586                 /* CPUs are sharing opp node */
587                 if (np == tmp_np)
588                         cpumask_set_cpu(cpu, cpumask);
589
590                 of_node_put(tmp_np);
591         }
592
593 put_cpu_node:
594         of_node_put(np);
595         return ret;
596 }
597 EXPORT_SYMBOL_GPL(dev_pm_opp_of_get_sharing_cpus);