blob: 0459b1204694567f69c6e37c22774d41f5eab502 [file] [log] [blame]
Nishanth Menone1f60b22010-10-13 00:13:10 +02001/*
2 * Generic OPP Interface
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
Viresh Kumard6d2a522015-10-17 09:45:18 +053014#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
15
Viresh Kumard54974c2016-02-09 10:30:38 +053016#include <linux/clk.h>
Nishanth Menone1f60b22010-10-13 00:13:10 +020017#include <linux/errno.h>
18#include <linux/err.h>
Nishanth Menone1f60b22010-10-13 00:13:10 +020019#include <linux/slab.h>
Paul Gortmaker51990e82012-01-22 11:23:42 -050020#include <linux/device.h>
Liam Girdwood80126ce2012-10-23 01:27:44 +020021#include <linux/export.h>
Viresh Kumar9f8ea962016-02-09 10:30:33 +053022#include <linux/regulator/consumer.h>
Nishanth Menone1f60b22010-10-13 00:13:10 +020023
Viresh Kumarf59d3ee2015-09-04 13:47:26 +053024#include "opp.h"
Nishanth Menone1f60b22010-10-13 00:13:10 +020025
26/*
Viresh Kumar2c2709d2016-02-16 14:17:53 +053027 * The root of the list of all opp-tables. All opp_table structures branch off
28 * from here, with each opp_table containing the list of opps it supports in
Nishanth Menone1f60b22010-10-13 00:13:10 +020029 * various states of availability.
30 */
Viresh Kumarf47b72a2016-05-05 16:20:33 +053031LIST_HEAD(opp_tables);
Nishanth Menone1f60b22010-10-13 00:13:10 +020032/* Lock to allow exclusive modification to the device and opp lists */
Viresh Kumar2c2709d2016-02-16 14:17:53 +053033DEFINE_MUTEX(opp_table_lock);
Nishanth Menone1f60b22010-10-13 00:13:10 +020034
Viresh Kumar8a31d9d92017-01-23 10:11:47 +053035static void dev_pm_opp_get(struct dev_pm_opp *opp);
36
Viresh Kumar2c2709d2016-02-16 14:17:53 +053037static struct opp_device *_find_opp_dev(const struct device *dev,
38 struct opp_table *opp_table)
Viresh Kumar06441652015-07-29 16:23:04 +053039{
Viresh Kumar2c2709d2016-02-16 14:17:53 +053040 struct opp_device *opp_dev;
Viresh Kumar06441652015-07-29 16:23:04 +053041
Viresh Kumar2c2709d2016-02-16 14:17:53 +053042 list_for_each_entry(opp_dev, &opp_table->dev_list, node)
43 if (opp_dev->dev == dev)
44 return opp_dev;
Viresh Kumar06441652015-07-29 16:23:04 +053045
46 return NULL;
47}
48
Wei Yongjun6ac42392017-02-06 14:29:55 +000049static struct opp_table *_find_opp_table_unlocked(struct device *dev)
Viresh Kumar5b650b32017-01-23 10:11:48 +053050{
51 struct opp_table *opp_table;
52
53 list_for_each_entry(opp_table, &opp_tables, node) {
54 if (_find_opp_dev(dev, opp_table)) {
55 _get_opp_table_kref(opp_table);
56
57 return opp_table;
58 }
59 }
60
61 return ERR_PTR(-ENODEV);
62}
63
Nishanth Menone1f60b22010-10-13 00:13:10 +020064/**
Viresh Kumar2c2709d2016-02-16 14:17:53 +053065 * _find_opp_table() - find opp_table struct using device pointer
66 * @dev: device pointer used to lookup OPP table
Nishanth Menone1f60b22010-10-13 00:13:10 +020067 *
Viresh Kumar052c6f12017-01-23 10:11:49 +053068 * Search OPP table for one containing matching device.
Nishanth Menone1f60b22010-10-13 00:13:10 +020069 *
Viresh Kumar2c2709d2016-02-16 14:17:53 +053070 * Return: pointer to 'struct opp_table' if found, otherwise -ENODEV or
Nishanth Menone1f60b22010-10-13 00:13:10 +020071 * -EINVAL based on type of error.
72 *
Viresh Kumar5b650b32017-01-23 10:11:48 +053073 * The callers must call dev_pm_opp_put_opp_table() after the table is used.
Nishanth Menone1f60b22010-10-13 00:13:10 +020074 */
Viresh Kumar2c2709d2016-02-16 14:17:53 +053075struct opp_table *_find_opp_table(struct device *dev)
Nishanth Menone1f60b22010-10-13 00:13:10 +020076{
Viresh Kumar2c2709d2016-02-16 14:17:53 +053077 struct opp_table *opp_table;
Nishanth Menone1f60b22010-10-13 00:13:10 +020078
Viresh Kumar50a3cb02015-08-12 15:59:39 +053079 if (IS_ERR_OR_NULL(dev)) {
Nishanth Menone1f60b22010-10-13 00:13:10 +020080 pr_err("%s: Invalid parameters\n", __func__);
81 return ERR_PTR(-EINVAL);
82 }
83
Viresh Kumar5b650b32017-01-23 10:11:48 +053084 mutex_lock(&opp_table_lock);
85 opp_table = _find_opp_table_unlocked(dev);
86 mutex_unlock(&opp_table_lock);
Nishanth Menone1f60b22010-10-13 00:13:10 +020087
Viresh Kumar5b650b32017-01-23 10:11:48 +053088 return opp_table;
Nishanth Menone1f60b22010-10-13 00:13:10 +020089}
90
91/**
Linus Torvaldsbaf51c42015-11-11 09:03:01 -080092 * dev_pm_opp_get_voltage() - Gets the voltage corresponding to an opp
Nishanth Menone1f60b22010-10-13 00:13:10 +020093 * @opp: opp for which voltage has to be returned for
94 *
Nishanth Menon984f16c2014-12-24 11:22:57 -060095 * Return: voltage in micro volt corresponding to the opp, else
Nishanth Menone1f60b22010-10-13 00:13:10 +020096 * return 0
97 *
Viresh Kumardfbe4672016-12-01 16:28:19 +053098 * This is useful only for devices with single power supply.
Nishanth Menone1f60b22010-10-13 00:13:10 +020099 */
Nishanth Menon47d43ba2013-09-19 16:03:51 -0500100unsigned long dev_pm_opp_get_voltage(struct dev_pm_opp *opp)
Nishanth Menone1f60b22010-10-13 00:13:10 +0200101{
Viresh Kumar052c6f12017-01-23 10:11:49 +0530102 if (IS_ERR_OR_NULL(opp)) {
Nishanth Menone1f60b22010-10-13 00:13:10 +0200103 pr_err("%s: Invalid parameters\n", __func__);
Viresh Kumar052c6f12017-01-23 10:11:49 +0530104 return 0;
105 }
Nishanth Menone1f60b22010-10-13 00:13:10 +0200106
Viresh Kumar052c6f12017-01-23 10:11:49 +0530107 return opp->supplies[0].u_volt;
Nishanth Menone1f60b22010-10-13 00:13:10 +0200108}
Nishanth Menon5d4879c2013-09-19 16:03:50 -0500109EXPORT_SYMBOL_GPL(dev_pm_opp_get_voltage);
Nishanth Menone1f60b22010-10-13 00:13:10 +0200110
111/**
Nishanth Menon5d4879c2013-09-19 16:03:50 -0500112 * dev_pm_opp_get_freq() - Gets the frequency corresponding to an available opp
Nishanth Menone1f60b22010-10-13 00:13:10 +0200113 * @opp: opp for which frequency has to be returned for
114 *
Nishanth Menon984f16c2014-12-24 11:22:57 -0600115 * Return: frequency in hertz corresponding to the opp, else
Nishanth Menone1f60b22010-10-13 00:13:10 +0200116 * return 0
Nishanth Menone1f60b22010-10-13 00:13:10 +0200117 */
Nishanth Menon47d43ba2013-09-19 16:03:51 -0500118unsigned long dev_pm_opp_get_freq(struct dev_pm_opp *opp)
Nishanth Menone1f60b22010-10-13 00:13:10 +0200119{
Viresh Kumar052c6f12017-01-23 10:11:49 +0530120 if (IS_ERR_OR_NULL(opp) || !opp->available) {
Nishanth Menone1f60b22010-10-13 00:13:10 +0200121 pr_err("%s: Invalid parameters\n", __func__);
Viresh Kumar052c6f12017-01-23 10:11:49 +0530122 return 0;
123 }
Nishanth Menone1f60b22010-10-13 00:13:10 +0200124
Viresh Kumar052c6f12017-01-23 10:11:49 +0530125 return opp->rate;
Nishanth Menone1f60b22010-10-13 00:13:10 +0200126}
Nishanth Menon5d4879c2013-09-19 16:03:50 -0500127EXPORT_SYMBOL_GPL(dev_pm_opp_get_freq);
Nishanth Menone1f60b22010-10-13 00:13:10 +0200128
129/**
Bartlomiej Zolnierkiewicz19445b22015-07-09 17:43:35 +0200130 * dev_pm_opp_is_turbo() - Returns if opp is turbo OPP or not
131 * @opp: opp for which turbo mode is being verified
132 *
133 * Turbo OPPs are not for normal use, and can be enabled (under certain
134 * conditions) for short duration of times to finish high throughput work
135 * quickly. Running on them for longer times may overheat the chip.
136 *
137 * Return: true if opp is turbo opp, else false.
Bartlomiej Zolnierkiewicz19445b22015-07-09 17:43:35 +0200138 */
139bool dev_pm_opp_is_turbo(struct dev_pm_opp *opp)
140{
Viresh Kumar052c6f12017-01-23 10:11:49 +0530141 if (IS_ERR_OR_NULL(opp) || !opp->available) {
Bartlomiej Zolnierkiewicz19445b22015-07-09 17:43:35 +0200142 pr_err("%s: Invalid parameters\n", __func__);
143 return false;
144 }
145
Viresh Kumar052c6f12017-01-23 10:11:49 +0530146 return opp->turbo;
Bartlomiej Zolnierkiewicz19445b22015-07-09 17:43:35 +0200147}
148EXPORT_SYMBOL_GPL(dev_pm_opp_is_turbo);
149
150/**
Viresh Kumar3ca9bb32015-07-29 16:23:03 +0530151 * dev_pm_opp_get_max_clock_latency() - Get max clock latency in nanoseconds
152 * @dev: device for which we do this operation
153 *
154 * Return: This function returns the max clock latency in nanoseconds.
Viresh Kumar3ca9bb32015-07-29 16:23:03 +0530155 */
156unsigned long dev_pm_opp_get_max_clock_latency(struct device *dev)
157{
Viresh Kumar2c2709d2016-02-16 14:17:53 +0530158 struct opp_table *opp_table;
Viresh Kumar3ca9bb32015-07-29 16:23:03 +0530159 unsigned long clock_latency_ns;
160
Viresh Kumar2c2709d2016-02-16 14:17:53 +0530161 opp_table = _find_opp_table(dev);
162 if (IS_ERR(opp_table))
Viresh Kumar5b650b32017-01-23 10:11:48 +0530163 return 0;
Viresh Kumar3ca9bb32015-07-29 16:23:03 +0530164
Viresh Kumar5b650b32017-01-23 10:11:48 +0530165 clock_latency_ns = opp_table->clock_latency_ns_max;
166
167 dev_pm_opp_put_opp_table(opp_table);
168
Viresh Kumar3ca9bb32015-07-29 16:23:03 +0530169 return clock_latency_ns;
170}
171EXPORT_SYMBOL_GPL(dev_pm_opp_get_max_clock_latency);
172
173/**
Viresh Kumar655c9df2016-02-09 10:30:35 +0530174 * dev_pm_opp_get_max_volt_latency() - Get max voltage latency in nanoseconds
175 * @dev: device for which we do this operation
176 *
177 * Return: This function returns the max voltage latency in nanoseconds.
Viresh Kumar655c9df2016-02-09 10:30:35 +0530178 */
179unsigned long dev_pm_opp_get_max_volt_latency(struct device *dev)
180{
Viresh Kumar2c2709d2016-02-16 14:17:53 +0530181 struct opp_table *opp_table;
Viresh Kumar655c9df2016-02-09 10:30:35 +0530182 struct dev_pm_opp *opp;
Viresh Kumar478256b2017-05-23 09:32:11 +0530183 struct regulator *reg;
Viresh Kumar655c9df2016-02-09 10:30:35 +0530184 unsigned long latency_ns = 0;
Viresh Kumardfbe4672016-12-01 16:28:19 +0530185 int ret, i, count;
186 struct {
187 unsigned long min;
188 unsigned long max;
189 } *uV;
190
Viresh Kumarcdd3e612017-01-23 10:11:51 +0530191 opp_table = _find_opp_table(dev);
192 if (IS_ERR(opp_table))
193 return 0;
194
195 count = opp_table->regulator_count;
Viresh Kumardfbe4672016-12-01 16:28:19 +0530196
197 /* Regulator may not be required for the device */
198 if (!count)
Viresh Kumarcdd3e612017-01-23 10:11:51 +0530199 goto put_opp_table;
Viresh Kumardfbe4672016-12-01 16:28:19 +0530200
Viresh Kumardfbe4672016-12-01 16:28:19 +0530201 uV = kmalloc_array(count, sizeof(*uV), GFP_KERNEL);
202 if (!uV)
Viresh Kumar478256b2017-05-23 09:32:11 +0530203 goto put_opp_table;
Viresh Kumar655c9df2016-02-09 10:30:35 +0530204
Viresh Kumar052c6f12017-01-23 10:11:49 +0530205 mutex_lock(&opp_table->lock);
206
Viresh Kumardfbe4672016-12-01 16:28:19 +0530207 for (i = 0; i < count; i++) {
208 uV[i].min = ~0;
209 uV[i].max = 0;
Viresh Kumar655c9df2016-02-09 10:30:35 +0530210
Viresh Kumar052c6f12017-01-23 10:11:49 +0530211 list_for_each_entry(opp, &opp_table->opp_list, node) {
Viresh Kumardfbe4672016-12-01 16:28:19 +0530212 if (!opp->available)
213 continue;
214
215 if (opp->supplies[i].u_volt_min < uV[i].min)
216 uV[i].min = opp->supplies[i].u_volt_min;
217 if (opp->supplies[i].u_volt_max > uV[i].max)
218 uV[i].max = opp->supplies[i].u_volt_max;
219 }
Viresh Kumar655c9df2016-02-09 10:30:35 +0530220 }
221
Viresh Kumar052c6f12017-01-23 10:11:49 +0530222 mutex_unlock(&opp_table->lock);
Viresh Kumar655c9df2016-02-09 10:30:35 +0530223
224 /*
Viresh Kumar2c2709d2016-02-16 14:17:53 +0530225 * The caller needs to ensure that opp_table (and hence the regulator)
Viresh Kumar655c9df2016-02-09 10:30:35 +0530226 * isn't freed, while we are executing this routine.
227 */
Andrzej Hajda8cc31112017-02-20 19:57:57 +0100228 for (i = 0; i < count; i++) {
Viresh Kumar478256b2017-05-23 09:32:11 +0530229 reg = opp_table->regulators[i];
Viresh Kumardfbe4672016-12-01 16:28:19 +0530230 ret = regulator_set_voltage_time(reg, uV[i].min, uV[i].max);
231 if (ret > 0)
232 latency_ns += ret * 1000;
233 }
234
Viresh Kumardfbe4672016-12-01 16:28:19 +0530235 kfree(uV);
Viresh Kumarcdd3e612017-01-23 10:11:51 +0530236put_opp_table:
237 dev_pm_opp_put_opp_table(opp_table);
Viresh Kumar655c9df2016-02-09 10:30:35 +0530238
239 return latency_ns;
240}
241EXPORT_SYMBOL_GPL(dev_pm_opp_get_max_volt_latency);
242
243/**
Viresh Kumar21743442016-02-09 10:30:36 +0530244 * dev_pm_opp_get_max_transition_latency() - Get max transition latency in
245 * nanoseconds
246 * @dev: device for which we do this operation
247 *
248 * Return: This function returns the max transition latency, in nanoseconds, to
249 * switch from one OPP to other.
Viresh Kumar21743442016-02-09 10:30:36 +0530250 */
251unsigned long dev_pm_opp_get_max_transition_latency(struct device *dev)
252{
253 return dev_pm_opp_get_max_volt_latency(dev) +
254 dev_pm_opp_get_max_clock_latency(dev);
255}
256EXPORT_SYMBOL_GPL(dev_pm_opp_get_max_transition_latency);
257
258/**
Viresh Kumar3aa26a32017-01-02 14:41:02 +0530259 * dev_pm_opp_get_suspend_opp_freq() - Get frequency of suspend opp in Hz
Bartlomiej Zolnierkiewicz4eafbd12015-09-08 18:41:01 +0200260 * @dev: device for which we do this operation
261 *
Viresh Kumar3aa26a32017-01-02 14:41:02 +0530262 * Return: This function returns the frequency of the OPP marked as suspend_opp
263 * if one is available, else returns 0;
Bartlomiej Zolnierkiewicz4eafbd12015-09-08 18:41:01 +0200264 */
Viresh Kumar3aa26a32017-01-02 14:41:02 +0530265unsigned long dev_pm_opp_get_suspend_opp_freq(struct device *dev)
Bartlomiej Zolnierkiewicz4eafbd12015-09-08 18:41:01 +0200266{
Viresh Kumar2c2709d2016-02-16 14:17:53 +0530267 struct opp_table *opp_table;
Viresh Kumar3aa26a32017-01-02 14:41:02 +0530268 unsigned long freq = 0;
Bartlomiej Zolnierkiewicz4eafbd12015-09-08 18:41:01 +0200269
Viresh Kumar2c2709d2016-02-16 14:17:53 +0530270 opp_table = _find_opp_table(dev);
Viresh Kumar5b650b32017-01-23 10:11:48 +0530271 if (IS_ERR(opp_table))
272 return 0;
Bartlomiej Zolnierkiewicz4eafbd12015-09-08 18:41:01 +0200273
Viresh Kumar5b650b32017-01-23 10:11:48 +0530274 if (opp_table->suspend_opp && opp_table->suspend_opp->available)
275 freq = dev_pm_opp_get_freq(opp_table->suspend_opp);
Viresh Kumar3aa26a32017-01-02 14:41:02 +0530276
Viresh Kumar5b650b32017-01-23 10:11:48 +0530277 dev_pm_opp_put_opp_table(opp_table);
278
Viresh Kumar3aa26a32017-01-02 14:41:02 +0530279 return freq;
Bartlomiej Zolnierkiewicz4eafbd12015-09-08 18:41:01 +0200280}
Viresh Kumar3aa26a32017-01-02 14:41:02 +0530281EXPORT_SYMBOL_GPL(dev_pm_opp_get_suspend_opp_freq);
Bartlomiej Zolnierkiewicz4eafbd12015-09-08 18:41:01 +0200282
283/**
Viresh Kumar2c2709d2016-02-16 14:17:53 +0530284 * dev_pm_opp_get_opp_count() - Get number of opps available in the opp table
Nishanth Menone1f60b22010-10-13 00:13:10 +0200285 * @dev: device for which we do this operation
286 *
Nishanth Menon984f16c2014-12-24 11:22:57 -0600287 * Return: This function returns the number of available opps if there are any,
Nishanth Menone1f60b22010-10-13 00:13:10 +0200288 * else returns 0 if none or the corresponding error value.
Nishanth Menone1f60b22010-10-13 00:13:10 +0200289 */
Nishanth Menon5d4879c2013-09-19 16:03:50 -0500290int dev_pm_opp_get_opp_count(struct device *dev)
Nishanth Menone1f60b22010-10-13 00:13:10 +0200291{
Viresh Kumar2c2709d2016-02-16 14:17:53 +0530292 struct opp_table *opp_table;
Nishanth Menon47d43ba2013-09-19 16:03:51 -0500293 struct dev_pm_opp *temp_opp;
Nishanth Menone1f60b22010-10-13 00:13:10 +0200294 int count = 0;
295
Viresh Kumar2c2709d2016-02-16 14:17:53 +0530296 opp_table = _find_opp_table(dev);
297 if (IS_ERR(opp_table)) {
298 count = PTR_ERR(opp_table);
Fabio Estevam035ed072017-09-29 14:39:49 -0300299 dev_dbg(dev, "%s: OPP table not found (%d)\n",
Dmitry Torokhovb4718c02014-12-16 15:09:38 -0800300 __func__, count);
Viresh Kumar5b650b32017-01-23 10:11:48 +0530301 return count;
Nishanth Menone1f60b22010-10-13 00:13:10 +0200302 }
303
Viresh Kumar052c6f12017-01-23 10:11:49 +0530304 mutex_lock(&opp_table->lock);
Viresh Kumar5b650b32017-01-23 10:11:48 +0530305
Viresh Kumar052c6f12017-01-23 10:11:49 +0530306 list_for_each_entry(temp_opp, &opp_table->opp_list, node) {
Nishanth Menone1f60b22010-10-13 00:13:10 +0200307 if (temp_opp->available)
308 count++;
309 }
310
Viresh Kumar052c6f12017-01-23 10:11:49 +0530311 mutex_unlock(&opp_table->lock);
Viresh Kumar5b650b32017-01-23 10:11:48 +0530312 dev_pm_opp_put_opp_table(opp_table);
313
Nishanth Menone1f60b22010-10-13 00:13:10 +0200314 return count;
315}
Nishanth Menon5d4879c2013-09-19 16:03:50 -0500316EXPORT_SYMBOL_GPL(dev_pm_opp_get_opp_count);
Nishanth Menone1f60b22010-10-13 00:13:10 +0200317
318/**
Nishanth Menon5d4879c2013-09-19 16:03:50 -0500319 * dev_pm_opp_find_freq_exact() - search for an exact frequency
Nishanth Menone1f60b22010-10-13 00:13:10 +0200320 * @dev: device for which we do this operation
321 * @freq: frequency to search for
Nishanth Menon7ae49612011-02-25 23:46:18 +0100322 * @available: true/false - match for available opp
Nishanth Menone1f60b22010-10-13 00:13:10 +0200323 *
Viresh Kumar2c2709d2016-02-16 14:17:53 +0530324 * Return: Searches for exact match in the opp table and returns pointer to the
Nishanth Menon984f16c2014-12-24 11:22:57 -0600325 * matching opp if found, else returns ERR_PTR in case of error and should
326 * be handled using IS_ERR. Error return values can be:
Nishanth Menon07797262012-10-24 22:00:12 +0200327 * EINVAL: for bad pointer
328 * ERANGE: no match found for search
329 * ENODEV: if device not found in list of registered devices
Nishanth Menone1f60b22010-10-13 00:13:10 +0200330 *
331 * Note: available is a modifier for the search. if available=true, then the
332 * match is for exact matching frequency and is available in the stored OPP
333 * table. if false, the match is for exact frequency which is not available.
334 *
335 * This provides a mechanism to enable an opp which is not available currently
336 * or the opposite as well.
337 *
Viresh Kumar8a31d9d92017-01-23 10:11:47 +0530338 * The callers are required to call dev_pm_opp_put() for the returned OPP after
339 * use.
Nishanth Menone1f60b22010-10-13 00:13:10 +0200340 */
Nishanth Menon47d43ba2013-09-19 16:03:51 -0500341struct dev_pm_opp *dev_pm_opp_find_freq_exact(struct device *dev,
342 unsigned long freq,
343 bool available)
Nishanth Menone1f60b22010-10-13 00:13:10 +0200344{
Viresh Kumar2c2709d2016-02-16 14:17:53 +0530345 struct opp_table *opp_table;
Nishanth Menon47d43ba2013-09-19 16:03:51 -0500346 struct dev_pm_opp *temp_opp, *opp = ERR_PTR(-ERANGE);
Nishanth Menone1f60b22010-10-13 00:13:10 +0200347
Viresh Kumar2c2709d2016-02-16 14:17:53 +0530348 opp_table = _find_opp_table(dev);
349 if (IS_ERR(opp_table)) {
350 int r = PTR_ERR(opp_table);
351
352 dev_err(dev, "%s: OPP table not found (%d)\n", __func__, r);
Nishanth Menone1f60b22010-10-13 00:13:10 +0200353 return ERR_PTR(r);
354 }
355
Viresh Kumar052c6f12017-01-23 10:11:49 +0530356 mutex_lock(&opp_table->lock);
Viresh Kumar5b650b32017-01-23 10:11:48 +0530357
Viresh Kumar052c6f12017-01-23 10:11:49 +0530358 list_for_each_entry(temp_opp, &opp_table->opp_list, node) {
Nishanth Menone1f60b22010-10-13 00:13:10 +0200359 if (temp_opp->available == available &&
360 temp_opp->rate == freq) {
361 opp = temp_opp;
Viresh Kumar8a31d9d92017-01-23 10:11:47 +0530362
363 /* Increment the reference count of OPP */
364 dev_pm_opp_get(opp);
Nishanth Menone1f60b22010-10-13 00:13:10 +0200365 break;
366 }
367 }
368
Viresh Kumar052c6f12017-01-23 10:11:49 +0530369 mutex_unlock(&opp_table->lock);
Viresh Kumar5b650b32017-01-23 10:11:48 +0530370 dev_pm_opp_put_opp_table(opp_table);
Viresh Kumar8a31d9d92017-01-23 10:11:47 +0530371
Nishanth Menone1f60b22010-10-13 00:13:10 +0200372 return opp;
373}
Nishanth Menon5d4879c2013-09-19 16:03:50 -0500374EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_exact);
Nishanth Menone1f60b22010-10-13 00:13:10 +0200375
Jisheng Zhang067b7ce2016-07-25 14:11:16 +0800376static noinline struct dev_pm_opp *_find_freq_ceil(struct opp_table *opp_table,
377 unsigned long *freq)
378{
379 struct dev_pm_opp *temp_opp, *opp = ERR_PTR(-ERANGE);
380
Viresh Kumar052c6f12017-01-23 10:11:49 +0530381 mutex_lock(&opp_table->lock);
382
383 list_for_each_entry(temp_opp, &opp_table->opp_list, node) {
Jisheng Zhang067b7ce2016-07-25 14:11:16 +0800384 if (temp_opp->available && temp_opp->rate >= *freq) {
385 opp = temp_opp;
386 *freq = opp->rate;
Viresh Kumar8a31d9d92017-01-23 10:11:47 +0530387
388 /* Increment the reference count of OPP */
389 dev_pm_opp_get(opp);
Jisheng Zhang067b7ce2016-07-25 14:11:16 +0800390 break;
391 }
392 }
393
Viresh Kumar052c6f12017-01-23 10:11:49 +0530394 mutex_unlock(&opp_table->lock);
395
Jisheng Zhang067b7ce2016-07-25 14:11:16 +0800396 return opp;
397}
398
Nishanth Menone1f60b22010-10-13 00:13:10 +0200399/**
Nishanth Menon5d4879c2013-09-19 16:03:50 -0500400 * dev_pm_opp_find_freq_ceil() - Search for an rounded ceil freq
Nishanth Menone1f60b22010-10-13 00:13:10 +0200401 * @dev: device for which we do this operation
402 * @freq: Start frequency
403 *
404 * Search for the matching ceil *available* OPP from a starting freq
405 * for a device.
406 *
Nishanth Menon984f16c2014-12-24 11:22:57 -0600407 * Return: matching *opp and refreshes *freq accordingly, else returns
Nishanth Menon07797262012-10-24 22:00:12 +0200408 * ERR_PTR in case of error and should be handled using IS_ERR. Error return
409 * values can be:
410 * EINVAL: for bad pointer
411 * ERANGE: no match found for search
412 * ENODEV: if device not found in list of registered devices
Nishanth Menone1f60b22010-10-13 00:13:10 +0200413 *
Viresh Kumar8a31d9d92017-01-23 10:11:47 +0530414 * The callers are required to call dev_pm_opp_put() for the returned OPP after
415 * use.
Nishanth Menone1f60b22010-10-13 00:13:10 +0200416 */
Nishanth Menon47d43ba2013-09-19 16:03:51 -0500417struct dev_pm_opp *dev_pm_opp_find_freq_ceil(struct device *dev,
418 unsigned long *freq)
Nishanth Menone1f60b22010-10-13 00:13:10 +0200419{
Viresh Kumar2c2709d2016-02-16 14:17:53 +0530420 struct opp_table *opp_table;
Viresh Kumar8a31d9d92017-01-23 10:11:47 +0530421 struct dev_pm_opp *opp;
Dmitry Torokhovb02ded22014-12-16 15:09:36 -0800422
Nishanth Menone1f60b22010-10-13 00:13:10 +0200423 if (!dev || !freq) {
424 dev_err(dev, "%s: Invalid argument freq=%p\n", __func__, freq);
425 return ERR_PTR(-EINVAL);
426 }
427
Viresh Kumar8a31d9d92017-01-23 10:11:47 +0530428 opp_table = _find_opp_table(dev);
Viresh Kumar5b650b32017-01-23 10:11:48 +0530429 if (IS_ERR(opp_table))
Viresh Kumar8a31d9d92017-01-23 10:11:47 +0530430 return ERR_CAST(opp_table);
Viresh Kumar5b650b32017-01-23 10:11:48 +0530431
Viresh Kumar8a31d9d92017-01-23 10:11:47 +0530432 opp = _find_freq_ceil(opp_table, freq);
433
Viresh Kumar5b650b32017-01-23 10:11:48 +0530434 dev_pm_opp_put_opp_table(opp_table);
Viresh Kumar8a31d9d92017-01-23 10:11:47 +0530435
436 return opp;
Nishanth Menone1f60b22010-10-13 00:13:10 +0200437}
Nishanth Menon5d4879c2013-09-19 16:03:50 -0500438EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_ceil);
Nishanth Menone1f60b22010-10-13 00:13:10 +0200439
440/**
Nishanth Menon5d4879c2013-09-19 16:03:50 -0500441 * dev_pm_opp_find_freq_floor() - Search for a rounded floor freq
Nishanth Menone1f60b22010-10-13 00:13:10 +0200442 * @dev: device for which we do this operation
443 * @freq: Start frequency
444 *
445 * Search for the matching floor *available* OPP from a starting freq
446 * for a device.
447 *
Nishanth Menon984f16c2014-12-24 11:22:57 -0600448 * Return: matching *opp and refreshes *freq accordingly, else returns
Nishanth Menon07797262012-10-24 22:00:12 +0200449 * ERR_PTR in case of error and should be handled using IS_ERR. Error return
450 * values can be:
451 * EINVAL: for bad pointer
452 * ERANGE: no match found for search
453 * ENODEV: if device not found in list of registered devices
Nishanth Menone1f60b22010-10-13 00:13:10 +0200454 *
Viresh Kumar8a31d9d92017-01-23 10:11:47 +0530455 * The callers are required to call dev_pm_opp_put() for the returned OPP after
456 * use.
Nishanth Menone1f60b22010-10-13 00:13:10 +0200457 */
Nishanth Menon47d43ba2013-09-19 16:03:51 -0500458struct dev_pm_opp *dev_pm_opp_find_freq_floor(struct device *dev,
459 unsigned long *freq)
Nishanth Menone1f60b22010-10-13 00:13:10 +0200460{
Viresh Kumar2c2709d2016-02-16 14:17:53 +0530461 struct opp_table *opp_table;
Nishanth Menon47d43ba2013-09-19 16:03:51 -0500462 struct dev_pm_opp *temp_opp, *opp = ERR_PTR(-ERANGE);
Nishanth Menone1f60b22010-10-13 00:13:10 +0200463
464 if (!dev || !freq) {
465 dev_err(dev, "%s: Invalid argument freq=%p\n", __func__, freq);
466 return ERR_PTR(-EINVAL);
467 }
468
Viresh Kumar2c2709d2016-02-16 14:17:53 +0530469 opp_table = _find_opp_table(dev);
Viresh Kumar5b650b32017-01-23 10:11:48 +0530470 if (IS_ERR(opp_table))
Viresh Kumar2c2709d2016-02-16 14:17:53 +0530471 return ERR_CAST(opp_table);
Viresh Kumar5b650b32017-01-23 10:11:48 +0530472
Viresh Kumar052c6f12017-01-23 10:11:49 +0530473 mutex_lock(&opp_table->lock);
Nishanth Menone1f60b22010-10-13 00:13:10 +0200474
Viresh Kumar052c6f12017-01-23 10:11:49 +0530475 list_for_each_entry(temp_opp, &opp_table->opp_list, node) {
Nishanth Menone1f60b22010-10-13 00:13:10 +0200476 if (temp_opp->available) {
477 /* go to the next node, before choosing prev */
478 if (temp_opp->rate > *freq)
479 break;
480 else
481 opp = temp_opp;
482 }
483 }
Viresh Kumar8a31d9d92017-01-23 10:11:47 +0530484
485 /* Increment the reference count of OPP */
486 if (!IS_ERR(opp))
487 dev_pm_opp_get(opp);
Viresh Kumar052c6f12017-01-23 10:11:49 +0530488 mutex_unlock(&opp_table->lock);
Viresh Kumar5b650b32017-01-23 10:11:48 +0530489 dev_pm_opp_put_opp_table(opp_table);
Viresh Kumar8a31d9d92017-01-23 10:11:47 +0530490
Nishanth Menone1f60b22010-10-13 00:13:10 +0200491 if (!IS_ERR(opp))
492 *freq = opp->rate;
493
494 return opp;
495}
Nishanth Menon5d4879c2013-09-19 16:03:50 -0500496EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_floor);
Nishanth Menone1f60b22010-10-13 00:13:10 +0200497
Viresh Kumar6a0712f2016-02-09 10:30:39 +0530498static int _set_opp_voltage(struct device *dev, struct regulator *reg,
Viresh Kumarce317812016-12-01 16:28:18 +0530499 struct dev_pm_opp_supply *supply)
Viresh Kumar6a0712f2016-02-09 10:30:39 +0530500{
501 int ret;
502
503 /* Regulator not available for device */
504 if (IS_ERR(reg)) {
505 dev_dbg(dev, "%s: regulator not available: %ld\n", __func__,
506 PTR_ERR(reg));
507 return 0;
508 }
509
Viresh Kumarce317812016-12-01 16:28:18 +0530510 dev_dbg(dev, "%s: voltages (mV): %lu %lu %lu\n", __func__,
511 supply->u_volt_min, supply->u_volt, supply->u_volt_max);
Viresh Kumar6a0712f2016-02-09 10:30:39 +0530512
Viresh Kumarce317812016-12-01 16:28:18 +0530513 ret = regulator_set_voltage_triplet(reg, supply->u_volt_min,
514 supply->u_volt, supply->u_volt_max);
Viresh Kumar6a0712f2016-02-09 10:30:39 +0530515 if (ret)
516 dev_err(dev, "%s: failed to set voltage (%lu %lu %lu mV): %d\n",
Viresh Kumarce317812016-12-01 16:28:18 +0530517 __func__, supply->u_volt_min, supply->u_volt,
518 supply->u_volt_max, ret);
Viresh Kumar6a0712f2016-02-09 10:30:39 +0530519
520 return ret;
521}
522
Viresh Kumar94735582016-12-01 16:28:20 +0530523static inline int
524_generic_set_opp_clk_only(struct device *dev, struct clk *clk,
525 unsigned long old_freq, unsigned long freq)
526{
527 int ret;
528
529 ret = clk_set_rate(clk, freq);
530 if (ret) {
531 dev_err(dev, "%s: failed to set clock rate: %d\n", __func__,
532 ret);
533 }
534
535 return ret;
536}
537
Viresh Kumarc74b32f2017-05-23 09:32:10 +0530538static int _generic_set_opp_regulator(const struct opp_table *opp_table,
539 struct device *dev,
540 unsigned long old_freq,
541 unsigned long freq,
542 struct dev_pm_opp_supply *old_supply,
543 struct dev_pm_opp_supply *new_supply)
Viresh Kumar94735582016-12-01 16:28:20 +0530544{
Viresh Kumarc74b32f2017-05-23 09:32:10 +0530545 struct regulator *reg = opp_table->regulators[0];
Viresh Kumar94735582016-12-01 16:28:20 +0530546 int ret;
547
548 /* This function only supports single regulator per device */
Viresh Kumarc74b32f2017-05-23 09:32:10 +0530549 if (WARN_ON(opp_table->regulator_count > 1)) {
Viresh Kumar94735582016-12-01 16:28:20 +0530550 dev_err(dev, "multiple regulators are not supported\n");
551 return -EINVAL;
552 }
553
554 /* Scaling up? Scale voltage before frequency */
555 if (freq > old_freq) {
556 ret = _set_opp_voltage(dev, reg, new_supply);
557 if (ret)
558 goto restore_voltage;
559 }
560
561 /* Change frequency */
Viresh Kumarc74b32f2017-05-23 09:32:10 +0530562 ret = _generic_set_opp_clk_only(dev, opp_table->clk, old_freq, freq);
Viresh Kumar94735582016-12-01 16:28:20 +0530563 if (ret)
564 goto restore_voltage;
565
566 /* Scaling down? Scale voltage after frequency */
567 if (freq < old_freq) {
568 ret = _set_opp_voltage(dev, reg, new_supply);
569 if (ret)
570 goto restore_freq;
571 }
572
573 return 0;
574
575restore_freq:
Viresh Kumarc74b32f2017-05-23 09:32:10 +0530576 if (_generic_set_opp_clk_only(dev, opp_table->clk, freq, old_freq))
Viresh Kumar94735582016-12-01 16:28:20 +0530577 dev_err(dev, "%s: failed to restore old-freq (%lu Hz)\n",
578 __func__, old_freq);
579restore_voltage:
580 /* This shouldn't harm even if the voltages weren't updated earlier */
Viresh Kumarc74b32f2017-05-23 09:32:10 +0530581 if (old_supply)
Viresh Kumar94735582016-12-01 16:28:20 +0530582 _set_opp_voltage(dev, reg, old_supply);
583
584 return ret;
585}
586
Viresh Kumar6a0712f2016-02-09 10:30:39 +0530587/**
588 * dev_pm_opp_set_rate() - Configure new OPP based on frequency
589 * @dev: device for which we do this operation
590 * @target_freq: frequency to achieve
591 *
592 * This configures the power-supplies and clock source to the levels specified
593 * by the OPP corresponding to the target_freq.
Viresh Kumar6a0712f2016-02-09 10:30:39 +0530594 */
595int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq)
596{
Viresh Kumar2c2709d2016-02-16 14:17:53 +0530597 struct opp_table *opp_table;
Viresh Kumar6a0712f2016-02-09 10:30:39 +0530598 unsigned long freq, old_freq;
Viresh Kumar94735582016-12-01 16:28:20 +0530599 struct dev_pm_opp *old_opp, *opp;
Viresh Kumar94735582016-12-01 16:28:20 +0530600 struct clk *clk;
601 int ret, size;
Viresh Kumar6a0712f2016-02-09 10:30:39 +0530602
603 if (unlikely(!target_freq)) {
604 dev_err(dev, "%s: Invalid target frequency %lu\n", __func__,
605 target_freq);
606 return -EINVAL;
607 }
608
Viresh Kumar052c6f12017-01-23 10:11:49 +0530609 opp_table = _find_opp_table(dev);
610 if (IS_ERR(opp_table)) {
611 dev_err(dev, "%s: device opp doesn't exist\n", __func__);
612 return PTR_ERR(opp_table);
613 }
614
615 clk = opp_table->clk;
616 if (IS_ERR(clk)) {
617 dev_err(dev, "%s: No clock available for the device\n",
618 __func__);
619 ret = PTR_ERR(clk);
620 goto put_opp_table;
621 }
Viresh Kumar6a0712f2016-02-09 10:30:39 +0530622
623 freq = clk_round_rate(clk, target_freq);
624 if ((long)freq <= 0)
625 freq = target_freq;
626
627 old_freq = clk_get_rate(clk);
628
629 /* Return early if nothing to do */
630 if (old_freq == freq) {
631 dev_dbg(dev, "%s: old/new frequencies (%lu Hz) are same, nothing to do\n",
632 __func__, freq);
Viresh Kumar052c6f12017-01-23 10:11:49 +0530633 ret = 0;
634 goto put_opp_table;
Viresh Kumar6a0712f2016-02-09 10:30:39 +0530635 }
636
Jisheng Zhang067b7ce2016-07-25 14:11:16 +0800637 old_opp = _find_freq_ceil(opp_table, &old_freq);
Arnd Bergmann4df27c92016-09-15 17:38:38 +0200638 if (IS_ERR(old_opp)) {
Viresh Kumar6a0712f2016-02-09 10:30:39 +0530639 dev_err(dev, "%s: failed to find current OPP for freq %lu (%ld)\n",
640 __func__, old_freq, PTR_ERR(old_opp));
641 }
642
Jisheng Zhang067b7ce2016-07-25 14:11:16 +0800643 opp = _find_freq_ceil(opp_table, &freq);
Viresh Kumar6a0712f2016-02-09 10:30:39 +0530644 if (IS_ERR(opp)) {
645 ret = PTR_ERR(opp);
646 dev_err(dev, "%s: failed to find OPP for freq %lu (%d)\n",
647 __func__, freq, ret);
Viresh Kumar052c6f12017-01-23 10:11:49 +0530648 goto put_old_opp;
Viresh Kumar6a0712f2016-02-09 10:30:39 +0530649 }
650
Viresh Kumar94735582016-12-01 16:28:20 +0530651 dev_dbg(dev, "%s: switching OPP: %lu Hz --> %lu Hz\n", __func__,
652 old_freq, freq);
Viresh Kumardfbe4672016-12-01 16:28:19 +0530653
Viresh Kumar94735582016-12-01 16:28:20 +0530654 /* Only frequency scaling */
Viresh Kumarc74b32f2017-05-23 09:32:10 +0530655 if (!opp_table->regulators) {
Viresh Kumar052c6f12017-01-23 10:11:49 +0530656 ret = _generic_set_opp_clk_only(dev, clk, old_freq, freq);
Viresh Kumarc74b32f2017-05-23 09:32:10 +0530657 } else if (!opp_table->set_opp) {
658 ret = _generic_set_opp_regulator(opp_table, dev, old_freq, freq,
659 IS_ERR(old_opp) ? NULL : old_opp->supplies,
660 opp->supplies);
661 } else {
662 struct dev_pm_set_opp_data *data;
663
664 data = opp_table->set_opp_data;
665 data->regulators = opp_table->regulators;
666 data->regulator_count = opp_table->regulator_count;
667 data->clk = clk;
668 data->dev = dev;
669
670 data->old_opp.rate = old_freq;
671 size = sizeof(*opp->supplies) * opp_table->regulator_count;
672 if (IS_ERR(old_opp))
673 memset(data->old_opp.supplies, 0, size);
674 else
675 memcpy(data->old_opp.supplies, old_opp->supplies, size);
676
677 data->new_opp.rate = freq;
678 memcpy(data->new_opp.supplies, opp->supplies, size);
679
680 ret = opp_table->set_opp(data);
Viresh Kumardfbe4672016-12-01 16:28:19 +0530681 }
682
Viresh Kumar8a31d9d92017-01-23 10:11:47 +0530683 dev_pm_opp_put(opp);
Viresh Kumar052c6f12017-01-23 10:11:49 +0530684put_old_opp:
Viresh Kumar8a31d9d92017-01-23 10:11:47 +0530685 if (!IS_ERR(old_opp))
686 dev_pm_opp_put(old_opp);
Viresh Kumar052c6f12017-01-23 10:11:49 +0530687put_opp_table:
Viresh Kumar5b650b32017-01-23 10:11:48 +0530688 dev_pm_opp_put_opp_table(opp_table);
Viresh Kumar052c6f12017-01-23 10:11:49 +0530689 return ret;
Viresh Kumar6a0712f2016-02-09 10:30:39 +0530690}
691EXPORT_SYMBOL_GPL(dev_pm_opp_set_rate);
692
Viresh Kumar2c2709d2016-02-16 14:17:53 +0530693/* OPP-dev Helpers */
Viresh Kumar2c2709d2016-02-16 14:17:53 +0530694static void _remove_opp_dev(struct opp_device *opp_dev,
695 struct opp_table *opp_table)
Viresh Kumar06441652015-07-29 16:23:04 +0530696{
Viresh Kumar2c2709d2016-02-16 14:17:53 +0530697 opp_debug_unregister(opp_dev, opp_table);
698 list_del(&opp_dev->node);
Viresh Kumar052c6f12017-01-23 10:11:49 +0530699 kfree(opp_dev);
Viresh Kumar06441652015-07-29 16:23:04 +0530700}
701
Viresh Kumar2c2709d2016-02-16 14:17:53 +0530702struct opp_device *_add_opp_dev(const struct device *dev,
703 struct opp_table *opp_table)
Viresh Kumar06441652015-07-29 16:23:04 +0530704{
Viresh Kumar2c2709d2016-02-16 14:17:53 +0530705 struct opp_device *opp_dev;
Viresh Kumardeaa5142015-11-11 07:59:01 +0530706 int ret;
Viresh Kumar06441652015-07-29 16:23:04 +0530707
Viresh Kumar2c2709d2016-02-16 14:17:53 +0530708 opp_dev = kzalloc(sizeof(*opp_dev), GFP_KERNEL);
709 if (!opp_dev)
Viresh Kumar06441652015-07-29 16:23:04 +0530710 return NULL;
711
Viresh Kumar2c2709d2016-02-16 14:17:53 +0530712 /* Initialize opp-dev */
713 opp_dev->dev = dev;
Viresh Kumar052c6f12017-01-23 10:11:49 +0530714 list_add(&opp_dev->node, &opp_table->dev_list);
Viresh Kumar06441652015-07-29 16:23:04 +0530715
Viresh Kumar2c2709d2016-02-16 14:17:53 +0530716 /* Create debugfs entries for the opp_table */
717 ret = opp_debug_register(opp_dev, opp_table);
Viresh Kumardeaa5142015-11-11 07:59:01 +0530718 if (ret)
719 dev_err(dev, "%s: Failed to register opp debugfs (%d)\n",
720 __func__, ret);
721
Viresh Kumar2c2709d2016-02-16 14:17:53 +0530722 return opp_dev;
Viresh Kumar06441652015-07-29 16:23:04 +0530723}
724
Viresh Kumarb6160e22017-01-02 14:41:04 +0530725static struct opp_table *_allocate_opp_table(struct device *dev)
Viresh Kumar07cce742014-12-10 09:45:34 +0530726{
Viresh Kumar2c2709d2016-02-16 14:17:53 +0530727 struct opp_table *opp_table;
728 struct opp_device *opp_dev;
Viresh Kumard54974c2016-02-09 10:30:38 +0530729 int ret;
Viresh Kumar07cce742014-12-10 09:45:34 +0530730
731 /*
Viresh Kumar2c2709d2016-02-16 14:17:53 +0530732 * Allocate a new OPP table. In the infrequent case where a new
Viresh Kumar07cce742014-12-10 09:45:34 +0530733 * device is needed to be added, we pay this penalty.
734 */
Viresh Kumar2c2709d2016-02-16 14:17:53 +0530735 opp_table = kzalloc(sizeof(*opp_table), GFP_KERNEL);
736 if (!opp_table)
Viresh Kumar07cce742014-12-10 09:45:34 +0530737 return NULL;
738
Viresh Kumar2c2709d2016-02-16 14:17:53 +0530739 INIT_LIST_HEAD(&opp_table->dev_list);
Viresh Kumar06441652015-07-29 16:23:04 +0530740
Viresh Kumar2c2709d2016-02-16 14:17:53 +0530741 opp_dev = _add_opp_dev(dev, opp_table);
742 if (!opp_dev) {
743 kfree(opp_table);
Viresh Kumar06441652015-07-29 16:23:04 +0530744 return NULL;
745 }
746
Viresh Kumarf47b72a2016-05-05 16:20:33 +0530747 _of_init_opp_table(opp_table, dev);
Viresh Kumar50f8cfb2016-02-09 10:30:37 +0530748
Viresh Kumard54974c2016-02-09 10:30:38 +0530749 /* Find clk for the device */
Viresh Kumar2c2709d2016-02-16 14:17:53 +0530750 opp_table->clk = clk_get(dev, NULL);
751 if (IS_ERR(opp_table->clk)) {
752 ret = PTR_ERR(opp_table->clk);
Viresh Kumard54974c2016-02-09 10:30:38 +0530753 if (ret != -EPROBE_DEFER)
754 dev_dbg(dev, "%s: Couldn't find clock: %d\n", __func__,
755 ret);
756 }
757
Viresh Kumar052c6f12017-01-23 10:11:49 +0530758 BLOCKING_INIT_NOTIFIER_HEAD(&opp_table->head);
Viresh Kumar2c2709d2016-02-16 14:17:53 +0530759 INIT_LIST_HEAD(&opp_table->opp_list);
Viresh Kumar37a73ec2017-01-23 10:11:41 +0530760 mutex_init(&opp_table->lock);
Viresh Kumarf067a982017-01-23 10:11:42 +0530761 kref_init(&opp_table->kref);
Viresh Kumar07cce742014-12-10 09:45:34 +0530762
Viresh Kumar2c2709d2016-02-16 14:17:53 +0530763 /* Secure the device table modification */
Viresh Kumar052c6f12017-01-23 10:11:49 +0530764 list_add(&opp_table->node, &opp_tables);
Viresh Kumar2c2709d2016-02-16 14:17:53 +0530765 return opp_table;
Viresh Kumar07cce742014-12-10 09:45:34 +0530766}
767
Viresh Kumarf067a982017-01-23 10:11:42 +0530768void _get_opp_table_kref(struct opp_table *opp_table)
Viresh Kumar3bac42c2015-07-29 16:22:59 +0530769{
Viresh Kumarf067a982017-01-23 10:11:42 +0530770 kref_get(&opp_table->kref);
771}
772
773struct opp_table *dev_pm_opp_get_opp_table(struct device *dev)
774{
775 struct opp_table *opp_table;
776
777 /* Hold our table modification lock here */
778 mutex_lock(&opp_table_lock);
779
Viresh Kumar5b650b32017-01-23 10:11:48 +0530780 opp_table = _find_opp_table_unlocked(dev);
781 if (!IS_ERR(opp_table))
Viresh Kumarf067a982017-01-23 10:11:42 +0530782 goto unlock;
Viresh Kumarf067a982017-01-23 10:11:42 +0530783
784 opp_table = _allocate_opp_table(dev);
785
786unlock:
787 mutex_unlock(&opp_table_lock);
788
789 return opp_table;
790}
791EXPORT_SYMBOL_GPL(dev_pm_opp_get_opp_table);
792
Viresh Kumarb83c1892017-01-23 10:11:45 +0530793static void _opp_table_kref_release(struct kref *kref)
Viresh Kumarf067a982017-01-23 10:11:42 +0530794{
795 struct opp_table *opp_table = container_of(kref, struct opp_table, kref);
Viresh Kumar2c2709d2016-02-16 14:17:53 +0530796 struct opp_device *opp_dev;
Viresh Kumar06441652015-07-29 16:23:04 +0530797
Viresh Kumard54974c2016-02-09 10:30:38 +0530798 /* Release clk */
Viresh Kumar2c2709d2016-02-16 14:17:53 +0530799 if (!IS_ERR(opp_table->clk))
800 clk_put(opp_table->clk);
Viresh Kumard54974c2016-02-09 10:30:38 +0530801
Viresh Kumar2c2709d2016-02-16 14:17:53 +0530802 opp_dev = list_first_entry(&opp_table->dev_list, struct opp_device,
803 node);
Viresh Kumar06441652015-07-29 16:23:04 +0530804
Viresh Kumar2c2709d2016-02-16 14:17:53 +0530805 _remove_opp_dev(opp_dev, opp_table);
Viresh Kumar06441652015-07-29 16:23:04 +0530806
807 /* dev_list must be empty now */
Viresh Kumar2c2709d2016-02-16 14:17:53 +0530808 WARN_ON(!list_empty(&opp_table->dev_list));
Viresh Kumar06441652015-07-29 16:23:04 +0530809
Viresh Kumar37a73ec2017-01-23 10:11:41 +0530810 mutex_destroy(&opp_table->lock);
Viresh Kumar052c6f12017-01-23 10:11:49 +0530811 list_del(&opp_table->node);
812 kfree(opp_table);
Viresh Kumar3bac42c2015-07-29 16:22:59 +0530813
Viresh Kumarf067a982017-01-23 10:11:42 +0530814 mutex_unlock(&opp_table_lock);
815}
816
817void dev_pm_opp_put_opp_table(struct opp_table *opp_table)
818{
819 kref_put_mutex(&opp_table->kref, _opp_table_kref_release,
820 &opp_table_lock);
821}
822EXPORT_SYMBOL_GPL(dev_pm_opp_put_opp_table);
823
Viresh Kumar8cd2f6e2017-01-02 14:41:01 +0530824void _opp_free(struct dev_pm_opp *opp)
Viresh Kumar969fceb2017-01-02 14:40:59 +0530825{
826 kfree(opp);
Viresh Kumar969fceb2017-01-02 14:40:59 +0530827}
828
Viresh Kumar70347642017-01-23 10:11:46 +0530829static void _opp_kref_release(struct kref *kref)
Viresh Kumar129eec52014-11-27 08:54:06 +0530830{
Viresh Kumar70347642017-01-23 10:11:46 +0530831 struct dev_pm_opp *opp = container_of(kref, struct dev_pm_opp, kref);
832 struct opp_table *opp_table = opp->opp_table;
Viresh Kumar37a73ec2017-01-23 10:11:41 +0530833
Viresh Kumar129eec52014-11-27 08:54:06 +0530834 /*
835 * Notify the changes in the availability of the operable
836 * frequency/voltage list.
837 */
Viresh Kumar052c6f12017-01-23 10:11:49 +0530838 blocking_notifier_call_chain(&opp_table->head, OPP_EVENT_REMOVE, opp);
Viresh Kumardeaa5142015-11-11 07:59:01 +0530839 opp_debug_remove_one(opp);
Viresh Kumar052c6f12017-01-23 10:11:49 +0530840 list_del(&opp->node);
841 kfree(opp);
Viresh Kumar129eec52014-11-27 08:54:06 +0530842
Viresh Kumar37a73ec2017-01-23 10:11:41 +0530843 mutex_unlock(&opp_table->lock);
Viresh Kumar31641cd2017-01-23 10:11:44 +0530844 dev_pm_opp_put_opp_table(opp_table);
Viresh Kumar129eec52014-11-27 08:54:06 +0530845}
846
Viresh Kumar8a31d9d92017-01-23 10:11:47 +0530847static void dev_pm_opp_get(struct dev_pm_opp *opp)
848{
849 kref_get(&opp->kref);
850}
851
Viresh Kumar70347642017-01-23 10:11:46 +0530852void dev_pm_opp_put(struct dev_pm_opp *opp)
853{
854 kref_put_mutex(&opp->kref, _opp_kref_release, &opp->opp_table->lock);
855}
856EXPORT_SYMBOL_GPL(dev_pm_opp_put);
857
Viresh Kumar129eec52014-11-27 08:54:06 +0530858/**
Viresh Kumar2c2709d2016-02-16 14:17:53 +0530859 * dev_pm_opp_remove() - Remove an OPP from OPP table
Viresh Kumar129eec52014-11-27 08:54:06 +0530860 * @dev: device for which we do this operation
861 * @freq: OPP to remove with matching 'freq'
862 *
Viresh Kumar2c2709d2016-02-16 14:17:53 +0530863 * This function removes an opp from the opp table.
Viresh Kumar129eec52014-11-27 08:54:06 +0530864 */
865void dev_pm_opp_remove(struct device *dev, unsigned long freq)
866{
867 struct dev_pm_opp *opp;
Viresh Kumar2c2709d2016-02-16 14:17:53 +0530868 struct opp_table *opp_table;
Viresh Kumar129eec52014-11-27 08:54:06 +0530869 bool found = false;
870
Viresh Kumar2c2709d2016-02-16 14:17:53 +0530871 opp_table = _find_opp_table(dev);
872 if (IS_ERR(opp_table))
Viresh Kumar5b650b32017-01-23 10:11:48 +0530873 return;
Viresh Kumar129eec52014-11-27 08:54:06 +0530874
Viresh Kumar37a73ec2017-01-23 10:11:41 +0530875 mutex_lock(&opp_table->lock);
876
Viresh Kumar2c2709d2016-02-16 14:17:53 +0530877 list_for_each_entry(opp, &opp_table->opp_list, node) {
Viresh Kumar129eec52014-11-27 08:54:06 +0530878 if (opp->rate == freq) {
879 found = true;
880 break;
881 }
882 }
883
Viresh Kumar37a73ec2017-01-23 10:11:41 +0530884 mutex_unlock(&opp_table->lock);
885
Viresh Kumar5b650b32017-01-23 10:11:48 +0530886 if (found) {
887 dev_pm_opp_put(opp);
888 } else {
Viresh Kumar129eec52014-11-27 08:54:06 +0530889 dev_warn(dev, "%s: Couldn't find OPP with freq: %lu\n",
890 __func__, freq);
Viresh Kumar129eec52014-11-27 08:54:06 +0530891 }
892
Viresh Kumar5b650b32017-01-23 10:11:48 +0530893 dev_pm_opp_put_opp_table(opp_table);
Viresh Kumar129eec52014-11-27 08:54:06 +0530894}
895EXPORT_SYMBOL_GPL(dev_pm_opp_remove);
896
Viresh Kumar8cd2f6e2017-01-02 14:41:01 +0530897struct dev_pm_opp *_opp_allocate(struct opp_table *table)
Viresh Kumar23dacf62015-07-29 16:23:01 +0530898{
899 struct dev_pm_opp *opp;
Viresh Kumardfbe4672016-12-01 16:28:19 +0530900 int count, supply_size;
Viresh Kumar23dacf62015-07-29 16:23:01 +0530901
Viresh Kumardfbe4672016-12-01 16:28:19 +0530902 /* Allocate space for at least one supply */
903 count = table->regulator_count ? table->regulator_count : 1;
904 supply_size = sizeof(*opp->supplies) * count;
Viresh Kumar23dacf62015-07-29 16:23:01 +0530905
Viresh Kumardfbe4672016-12-01 16:28:19 +0530906 /* allocate new OPP node and supplies structures */
907 opp = kzalloc(sizeof(*opp) + supply_size, GFP_KERNEL);
Viresh Kumar8cd2f6e2017-01-02 14:41:01 +0530908 if (!opp)
Viresh Kumar23dacf62015-07-29 16:23:01 +0530909 return NULL;
Viresh Kumar23dacf62015-07-29 16:23:01 +0530910
Viresh Kumardfbe4672016-12-01 16:28:19 +0530911 /* Put the supplies at the end of the OPP structure as an empty array */
912 opp->supplies = (struct dev_pm_opp_supply *)(opp + 1);
913 INIT_LIST_HEAD(&opp->node);
914
Viresh Kumar23dacf62015-07-29 16:23:01 +0530915 return opp;
916}
917
Viresh Kumar7d34d562016-02-09 10:30:34 +0530918static bool _opp_supported_by_regulators(struct dev_pm_opp *opp,
Viresh Kumar2c2709d2016-02-16 14:17:53 +0530919 struct opp_table *opp_table)
Viresh Kumar7d34d562016-02-09 10:30:34 +0530920{
Viresh Kumardfbe4672016-12-01 16:28:19 +0530921 struct regulator *reg;
922 int i;
Viresh Kumar7d34d562016-02-09 10:30:34 +0530923
Viresh Kumardfbe4672016-12-01 16:28:19 +0530924 for (i = 0; i < opp_table->regulator_count; i++) {
925 reg = opp_table->regulators[i];
926
927 if (!regulator_is_supported_voltage(reg,
928 opp->supplies[i].u_volt_min,
929 opp->supplies[i].u_volt_max)) {
930 pr_warn("%s: OPP minuV: %lu maxuV: %lu, not supported by regulator\n",
931 __func__, opp->supplies[i].u_volt_min,
932 opp->supplies[i].u_volt_max);
933 return false;
934 }
Viresh Kumar7d34d562016-02-09 10:30:34 +0530935 }
936
937 return true;
938}
939
Viresh Kumar7f8538e2017-01-02 14:40:55 +0530940/*
941 * Returns:
942 * 0: On success. And appropriate error message for duplicate OPPs.
943 * -EBUSY: For OPP with same freq/volt and is available. The callers of
944 * _opp_add() must return 0 if they receive -EBUSY from it. This is to make
945 * sure we don't print error messages unnecessarily if different parts of
946 * kernel try to initialize the OPP table.
947 * -EEXIST: For OPP with same freq but different volt or is unavailable. This
948 * should be considered an error by the callers of _opp_add().
949 */
Viresh Kumarf47b72a2016-05-05 16:20:33 +0530950int _opp_add(struct device *dev, struct dev_pm_opp *new_opp,
951 struct opp_table *opp_table)
Viresh Kumar23dacf62015-07-29 16:23:01 +0530952{
953 struct dev_pm_opp *opp;
Viresh Kumar37a73ec2017-01-23 10:11:41 +0530954 struct list_head *head;
Viresh Kumardeaa5142015-11-11 07:59:01 +0530955 int ret;
Viresh Kumar23dacf62015-07-29 16:23:01 +0530956
957 /*
958 * Insert new OPP in order of increasing frequency and discard if
959 * already present.
960 *
Viresh Kumar2c2709d2016-02-16 14:17:53 +0530961 * Need to use &opp_table->opp_list in the condition part of the 'for'
Viresh Kumar23dacf62015-07-29 16:23:01 +0530962 * loop, don't replace it with head otherwise it will become an infinite
963 * loop.
964 */
Viresh Kumar37a73ec2017-01-23 10:11:41 +0530965 mutex_lock(&opp_table->lock);
966 head = &opp_table->opp_list;
967
Viresh Kumar052c6f12017-01-23 10:11:49 +0530968 list_for_each_entry(opp, &opp_table->opp_list, node) {
Viresh Kumar23dacf62015-07-29 16:23:01 +0530969 if (new_opp->rate > opp->rate) {
970 head = &opp->node;
971 continue;
972 }
973
974 if (new_opp->rate < opp->rate)
975 break;
976
977 /* Duplicate OPPs */
Viresh Kumar06441652015-07-29 16:23:04 +0530978 dev_warn(dev, "%s: duplicate OPPs detected. Existing: freq: %lu, volt: %lu, enabled: %d. New: freq: %lu, volt: %lu, enabled: %d\n",
Viresh Kumardfbe4672016-12-01 16:28:19 +0530979 __func__, opp->rate, opp->supplies[0].u_volt,
980 opp->available, new_opp->rate,
981 new_opp->supplies[0].u_volt, new_opp->available);
Viresh Kumar23dacf62015-07-29 16:23:01 +0530982
Viresh Kumardfbe4672016-12-01 16:28:19 +0530983 /* Should we compare voltages for all regulators here ? */
Viresh Kumar37a73ec2017-01-23 10:11:41 +0530984 ret = opp->available &&
985 new_opp->supplies[0].u_volt == opp->supplies[0].u_volt ? -EBUSY : -EEXIST;
986
987 mutex_unlock(&opp_table->lock);
988 return ret;
Viresh Kumar23dacf62015-07-29 16:23:01 +0530989 }
990
Viresh Kumar052c6f12017-01-23 10:11:49 +0530991 list_add(&new_opp->node, head);
Viresh Kumar37a73ec2017-01-23 10:11:41 +0530992 mutex_unlock(&opp_table->lock);
993
994 new_opp->opp_table = opp_table;
Viresh Kumar70347642017-01-23 10:11:46 +0530995 kref_init(&new_opp->kref);
Viresh Kumar23dacf62015-07-29 16:23:01 +0530996
Viresh Kumar31641cd2017-01-23 10:11:44 +0530997 /* Get a reference to the OPP table */
998 _get_opp_table_kref(opp_table);
999
Viresh Kumar2c2709d2016-02-16 14:17:53 +05301000 ret = opp_debug_create_one(new_opp, opp_table);
Viresh Kumardeaa5142015-11-11 07:59:01 +05301001 if (ret)
1002 dev_err(dev, "%s: Failed to register opp to debugfs (%d)\n",
1003 __func__, ret);
1004
Viresh Kumar2c2709d2016-02-16 14:17:53 +05301005 if (!_opp_supported_by_regulators(new_opp, opp_table)) {
Viresh Kumar7d34d562016-02-09 10:30:34 +05301006 new_opp->available = false;
1007 dev_warn(dev, "%s: OPP not supported by regulators (%lu)\n",
1008 __func__, new_opp->rate);
1009 }
1010
Viresh Kumar23dacf62015-07-29 16:23:01 +05301011 return 0;
1012}
1013
Viresh Kumar737002b2015-07-29 16:22:58 +05301014/**
Viresh Kumarb64b9c3f2015-10-15 21:42:44 +05301015 * _opp_add_v1() - Allocate a OPP based on v1 bindings.
Viresh Kumar8cd2f6e2017-01-02 14:41:01 +05301016 * @opp_table: OPP table
Nishanth Menone1f60b22010-10-13 00:13:10 +02001017 * @dev: device for which we do this operation
1018 * @freq: Frequency in Hz for this OPP
1019 * @u_volt: Voltage in uVolts for this OPP
1020 * @dynamic: Dynamically added OPPs.
1021 *
Viresh Kumar2c2709d2016-02-16 14:17:53 +05301022 * This function adds an opp definition to the opp table and returns status.
Nishanth Menone1f60b22010-10-13 00:13:10 +02001023 * The opp is made available by default and it can be controlled using
1024 * dev_pm_opp_enable/disable functions and may be removed by dev_pm_opp_remove.
1025 *
Viresh Kumar8f8d37b2015-09-04 13:47:24 +05301026 * NOTE: "dynamic" parameter impacts OPPs added by the dev_pm_opp_of_add_table
1027 * and freed by dev_pm_opp_of_remove_table.
Nishanth Menone1f60b22010-10-13 00:13:10 +02001028 *
Nishanth Menone1f60b22010-10-13 00:13:10 +02001029 * Return:
1030 * 0 On success OR
1031 * Duplicate OPPs (both freq and volt are same) and opp->available
1032 * -EEXIST Freq are same and volt are different OR
1033 * Duplicate OPPs (both freq and volt are same) and !opp->available
1034 * -ENOMEM Memory allocation failure
1035 */
Viresh Kumar8cd2f6e2017-01-02 14:41:01 +05301036int _opp_add_v1(struct opp_table *opp_table, struct device *dev,
1037 unsigned long freq, long u_volt, bool dynamic)
Nishanth Menone1f60b22010-10-13 00:13:10 +02001038{
Viresh Kumar23dacf62015-07-29 16:23:01 +05301039 struct dev_pm_opp *new_opp;
Viresh Kumar50f8cfb2016-02-09 10:30:37 +05301040 unsigned long tol;
Nishanth Menone1f60b22010-10-13 00:13:10 +02001041 int ret;
1042
Viresh Kumar8cd2f6e2017-01-02 14:41:01 +05301043 new_opp = _opp_allocate(opp_table);
1044 if (!new_opp)
1045 return -ENOMEM;
Viresh Kumar23dacf62015-07-29 16:23:01 +05301046
Nishanth Menone1f60b22010-10-13 00:13:10 +02001047 /* populate the opp table */
1048 new_opp->rate = freq;
Viresh Kumar2c2709d2016-02-16 14:17:53 +05301049 tol = u_volt * opp_table->voltage_tolerance_v1 / 100;
Viresh Kumardfbe4672016-12-01 16:28:19 +05301050 new_opp->supplies[0].u_volt = u_volt;
1051 new_opp->supplies[0].u_volt_min = u_volt - tol;
1052 new_opp->supplies[0].u_volt_max = u_volt + tol;
Nishanth Menone1f60b22010-10-13 00:13:10 +02001053 new_opp->available = true;
Viresh Kumaraa5f2f82015-07-29 16:23:00 +05301054 new_opp->dynamic = dynamic;
Viresh Kumar23dacf62015-07-29 16:23:01 +05301055
Viresh Kumar2c2709d2016-02-16 14:17:53 +05301056 ret = _opp_add(dev, new_opp, opp_table);
Viresh Kumar7f8538e2017-01-02 14:40:55 +05301057 if (ret) {
1058 /* Don't return error for duplicate OPPs */
1059 if (ret == -EBUSY)
1060 ret = 0;
Viresh Kumar23dacf62015-07-29 16:23:01 +05301061 goto free_opp;
Viresh Kumar7f8538e2017-01-02 14:40:55 +05301062 }
Viresh Kumar23dacf62015-07-29 16:23:01 +05301063
Nishanth Menone1f60b22010-10-13 00:13:10 +02001064 /*
1065 * Notify the changes in the availability of the operable
1066 * frequency/voltage list.
1067 */
Viresh Kumar052c6f12017-01-23 10:11:49 +05301068 blocking_notifier_call_chain(&opp_table->head, OPP_EVENT_ADD, new_opp);
Nishanth Menone1f60b22010-10-13 00:13:10 +02001069 return 0;
1070
1071free_opp:
Viresh Kumar8cd2f6e2017-01-02 14:41:01 +05301072 _opp_free(new_opp);
1073
Nishanth Menone1f60b22010-10-13 00:13:10 +02001074 return ret;
1075}
Viresh Kumar383934092014-11-25 16:04:18 +05301076
Viresh Kumar27465902015-07-29 16:23:02 +05301077/**
Viresh Kumar7de36b02015-12-09 08:01:46 +05301078 * dev_pm_opp_set_supported_hw() - Set supported platforms
1079 * @dev: Device for which supported-hw has to be set.
1080 * @versions: Array of hierarchy of versions to match.
1081 * @count: Number of elements in the array.
1082 *
1083 * This is required only for the V2 bindings, and it enables a platform to
1084 * specify the hierarchy of versions it supports. OPP layer will then enable
1085 * OPPs, which are available for those versions, based on its 'opp-supported-hw'
1086 * property.
Viresh Kumar7de36b02015-12-09 08:01:46 +05301087 */
Viresh Kumarfa301842017-01-23 10:11:43 +05301088struct opp_table *dev_pm_opp_set_supported_hw(struct device *dev,
1089 const u32 *versions, unsigned int count)
Viresh Kumar7de36b02015-12-09 08:01:46 +05301090{
Viresh Kumar2c2709d2016-02-16 14:17:53 +05301091 struct opp_table *opp_table;
Viresh Kumarfa301842017-01-23 10:11:43 +05301092 int ret;
Viresh Kumar7de36b02015-12-09 08:01:46 +05301093
Viresh Kumarfa301842017-01-23 10:11:43 +05301094 opp_table = dev_pm_opp_get_opp_table(dev);
1095 if (!opp_table)
1096 return ERR_PTR(-ENOMEM);
Viresh Kumar7de36b02015-12-09 08:01:46 +05301097
Viresh Kumar2c2709d2016-02-16 14:17:53 +05301098 /* Make sure there are no concurrent readers while updating opp_table */
1099 WARN_ON(!list_empty(&opp_table->opp_list));
Viresh Kumar7de36b02015-12-09 08:01:46 +05301100
Viresh Kumar2c2709d2016-02-16 14:17:53 +05301101 /* Do we already have a version hierarchy associated with opp_table? */
1102 if (opp_table->supported_hw) {
Viresh Kumar7de36b02015-12-09 08:01:46 +05301103 dev_err(dev, "%s: Already have supported hardware list\n",
1104 __func__);
1105 ret = -EBUSY;
1106 goto err;
1107 }
1108
Viresh Kumar2c2709d2016-02-16 14:17:53 +05301109 opp_table->supported_hw = kmemdup(versions, count * sizeof(*versions),
Viresh Kumar7de36b02015-12-09 08:01:46 +05301110 GFP_KERNEL);
Viresh Kumar2c2709d2016-02-16 14:17:53 +05301111 if (!opp_table->supported_hw) {
Viresh Kumar7de36b02015-12-09 08:01:46 +05301112 ret = -ENOMEM;
1113 goto err;
1114 }
1115
Viresh Kumar2c2709d2016-02-16 14:17:53 +05301116 opp_table->supported_hw_count = count;
Viresh Kumarfa301842017-01-23 10:11:43 +05301117
1118 return opp_table;
Viresh Kumar7de36b02015-12-09 08:01:46 +05301119
1120err:
Viresh Kumarfa301842017-01-23 10:11:43 +05301121 dev_pm_opp_put_opp_table(opp_table);
Viresh Kumar7de36b02015-12-09 08:01:46 +05301122
Viresh Kumarfa301842017-01-23 10:11:43 +05301123 return ERR_PTR(ret);
Viresh Kumar7de36b02015-12-09 08:01:46 +05301124}
1125EXPORT_SYMBOL_GPL(dev_pm_opp_set_supported_hw);
1126
1127/**
1128 * dev_pm_opp_put_supported_hw() - Releases resources blocked for supported hw
Viresh Kumarfa301842017-01-23 10:11:43 +05301129 * @opp_table: OPP table returned by dev_pm_opp_set_supported_hw().
Viresh Kumar7de36b02015-12-09 08:01:46 +05301130 *
1131 * This is required only for the V2 bindings, and is called for a matching
Viresh Kumar2c2709d2016-02-16 14:17:53 +05301132 * dev_pm_opp_set_supported_hw(). Until this is called, the opp_table structure
Viresh Kumar7de36b02015-12-09 08:01:46 +05301133 * will not be freed.
Viresh Kumar7de36b02015-12-09 08:01:46 +05301134 */
Viresh Kumarfa301842017-01-23 10:11:43 +05301135void dev_pm_opp_put_supported_hw(struct opp_table *opp_table)
Viresh Kumar7de36b02015-12-09 08:01:46 +05301136{
Viresh Kumar2c2709d2016-02-16 14:17:53 +05301137 /* Make sure there are no concurrent readers while updating opp_table */
1138 WARN_ON(!list_empty(&opp_table->opp_list));
Viresh Kumar7de36b02015-12-09 08:01:46 +05301139
Viresh Kumar2c2709d2016-02-16 14:17:53 +05301140 if (!opp_table->supported_hw) {
Viresh Kumarfa301842017-01-23 10:11:43 +05301141 pr_err("%s: Doesn't have supported hardware list\n",
1142 __func__);
1143 return;
Viresh Kumar7de36b02015-12-09 08:01:46 +05301144 }
1145
Viresh Kumar2c2709d2016-02-16 14:17:53 +05301146 kfree(opp_table->supported_hw);
1147 opp_table->supported_hw = NULL;
1148 opp_table->supported_hw_count = 0;
Viresh Kumar7de36b02015-12-09 08:01:46 +05301149
Viresh Kumarfa301842017-01-23 10:11:43 +05301150 dev_pm_opp_put_opp_table(opp_table);
Viresh Kumar7de36b02015-12-09 08:01:46 +05301151}
1152EXPORT_SYMBOL_GPL(dev_pm_opp_put_supported_hw);
1153
Viresh Kumar01fb4d32015-12-09 08:01:47 +05301154/**
1155 * dev_pm_opp_set_prop_name() - Set prop-extn name
Viresh Kumara5da6442016-02-16 14:17:52 +05301156 * @dev: Device for which the prop-name has to be set.
Viresh Kumar01fb4d32015-12-09 08:01:47 +05301157 * @name: name to postfix to properties.
1158 *
1159 * This is required only for the V2 bindings, and it enables a platform to
1160 * specify the extn to be used for certain property names. The properties to
1161 * which the extension will apply are opp-microvolt and opp-microamp. OPP core
1162 * should postfix the property name with -<name> while looking for them.
Viresh Kumar01fb4d32015-12-09 08:01:47 +05301163 */
Viresh Kumarfa301842017-01-23 10:11:43 +05301164struct opp_table *dev_pm_opp_set_prop_name(struct device *dev, const char *name)
Viresh Kumar01fb4d32015-12-09 08:01:47 +05301165{
Viresh Kumar2c2709d2016-02-16 14:17:53 +05301166 struct opp_table *opp_table;
Viresh Kumarfa301842017-01-23 10:11:43 +05301167 int ret;
Viresh Kumar01fb4d32015-12-09 08:01:47 +05301168
Viresh Kumarfa301842017-01-23 10:11:43 +05301169 opp_table = dev_pm_opp_get_opp_table(dev);
1170 if (!opp_table)
1171 return ERR_PTR(-ENOMEM);
Viresh Kumar01fb4d32015-12-09 08:01:47 +05301172
Viresh Kumar2c2709d2016-02-16 14:17:53 +05301173 /* Make sure there are no concurrent readers while updating opp_table */
1174 WARN_ON(!list_empty(&opp_table->opp_list));
Viresh Kumar01fb4d32015-12-09 08:01:47 +05301175
Viresh Kumar2c2709d2016-02-16 14:17:53 +05301176 /* Do we already have a prop-name associated with opp_table? */
1177 if (opp_table->prop_name) {
Viresh Kumar01fb4d32015-12-09 08:01:47 +05301178 dev_err(dev, "%s: Already have prop-name %s\n", __func__,
Viresh Kumar2c2709d2016-02-16 14:17:53 +05301179 opp_table->prop_name);
Viresh Kumar01fb4d32015-12-09 08:01:47 +05301180 ret = -EBUSY;
1181 goto err;
1182 }
1183
Viresh Kumar2c2709d2016-02-16 14:17:53 +05301184 opp_table->prop_name = kstrdup(name, GFP_KERNEL);
1185 if (!opp_table->prop_name) {
Viresh Kumar01fb4d32015-12-09 08:01:47 +05301186 ret = -ENOMEM;
1187 goto err;
1188 }
1189
Viresh Kumarfa301842017-01-23 10:11:43 +05301190 return opp_table;
Viresh Kumar01fb4d32015-12-09 08:01:47 +05301191
1192err:
Viresh Kumarfa301842017-01-23 10:11:43 +05301193 dev_pm_opp_put_opp_table(opp_table);
Viresh Kumar01fb4d32015-12-09 08:01:47 +05301194
Viresh Kumarfa301842017-01-23 10:11:43 +05301195 return ERR_PTR(ret);
Viresh Kumar01fb4d32015-12-09 08:01:47 +05301196}
1197EXPORT_SYMBOL_GPL(dev_pm_opp_set_prop_name);
1198
1199/**
1200 * dev_pm_opp_put_prop_name() - Releases resources blocked for prop-name
Viresh Kumarfa301842017-01-23 10:11:43 +05301201 * @opp_table: OPP table returned by dev_pm_opp_set_prop_name().
Viresh Kumar01fb4d32015-12-09 08:01:47 +05301202 *
1203 * This is required only for the V2 bindings, and is called for a matching
Viresh Kumar2c2709d2016-02-16 14:17:53 +05301204 * dev_pm_opp_set_prop_name(). Until this is called, the opp_table structure
Viresh Kumar01fb4d32015-12-09 08:01:47 +05301205 * will not be freed.
Viresh Kumar01fb4d32015-12-09 08:01:47 +05301206 */
Viresh Kumarfa301842017-01-23 10:11:43 +05301207void dev_pm_opp_put_prop_name(struct opp_table *opp_table)
Viresh Kumar01fb4d32015-12-09 08:01:47 +05301208{
Viresh Kumar2c2709d2016-02-16 14:17:53 +05301209 /* Make sure there are no concurrent readers while updating opp_table */
1210 WARN_ON(!list_empty(&opp_table->opp_list));
Viresh Kumar01fb4d32015-12-09 08:01:47 +05301211
Viresh Kumar2c2709d2016-02-16 14:17:53 +05301212 if (!opp_table->prop_name) {
Viresh Kumarfa301842017-01-23 10:11:43 +05301213 pr_err("%s: Doesn't have a prop-name\n", __func__);
1214 return;
Viresh Kumar01fb4d32015-12-09 08:01:47 +05301215 }
1216
Viresh Kumar2c2709d2016-02-16 14:17:53 +05301217 kfree(opp_table->prop_name);
1218 opp_table->prop_name = NULL;
Viresh Kumar01fb4d32015-12-09 08:01:47 +05301219
Viresh Kumarfa301842017-01-23 10:11:43 +05301220 dev_pm_opp_put_opp_table(opp_table);
Viresh Kumar01fb4d32015-12-09 08:01:47 +05301221}
1222EXPORT_SYMBOL_GPL(dev_pm_opp_put_prop_name);
1223
Viresh Kumar94735582016-12-01 16:28:20 +05301224static int _allocate_set_opp_data(struct opp_table *opp_table)
1225{
1226 struct dev_pm_set_opp_data *data;
1227 int len, count = opp_table->regulator_count;
1228
1229 if (WARN_ON(!count))
1230 return -EINVAL;
1231
1232 /* space for set_opp_data */
1233 len = sizeof(*data);
1234
1235 /* space for old_opp.supplies and new_opp.supplies */
1236 len += 2 * sizeof(struct dev_pm_opp_supply) * count;
1237
1238 data = kzalloc(len, GFP_KERNEL);
1239 if (!data)
1240 return -ENOMEM;
1241
1242 data->old_opp.supplies = (void *)(data + 1);
1243 data->new_opp.supplies = data->old_opp.supplies + count;
1244
1245 opp_table->set_opp_data = data;
1246
1247 return 0;
1248}
1249
1250static void _free_set_opp_data(struct opp_table *opp_table)
1251{
1252 kfree(opp_table->set_opp_data);
1253 opp_table->set_opp_data = NULL;
1254}
1255
Viresh Kumar9f8ea962016-02-09 10:30:33 +05301256/**
Viresh Kumardfbe4672016-12-01 16:28:19 +05301257 * dev_pm_opp_set_regulators() - Set regulator names for the device
Viresh Kumar9f8ea962016-02-09 10:30:33 +05301258 * @dev: Device for which regulator name is being set.
Viresh Kumardfbe4672016-12-01 16:28:19 +05301259 * @names: Array of pointers to the names of the regulator.
1260 * @count: Number of regulators.
Viresh Kumar9f8ea962016-02-09 10:30:33 +05301261 *
1262 * In order to support OPP switching, OPP layer needs to know the name of the
Viresh Kumardfbe4672016-12-01 16:28:19 +05301263 * device's regulators, as the core would be required to switch voltages as
1264 * well.
Viresh Kumar9f8ea962016-02-09 10:30:33 +05301265 *
1266 * This must be called before any OPPs are initialized for the device.
Viresh Kumar9f8ea962016-02-09 10:30:33 +05301267 */
Viresh Kumardfbe4672016-12-01 16:28:19 +05301268struct opp_table *dev_pm_opp_set_regulators(struct device *dev,
1269 const char * const names[],
1270 unsigned int count)
Viresh Kumar9f8ea962016-02-09 10:30:33 +05301271{
Viresh Kumar2c2709d2016-02-16 14:17:53 +05301272 struct opp_table *opp_table;
Viresh Kumar9f8ea962016-02-09 10:30:33 +05301273 struct regulator *reg;
Viresh Kumardfbe4672016-12-01 16:28:19 +05301274 int ret, i;
Viresh Kumar9f8ea962016-02-09 10:30:33 +05301275
Viresh Kumarfa301842017-01-23 10:11:43 +05301276 opp_table = dev_pm_opp_get_opp_table(dev);
1277 if (!opp_table)
1278 return ERR_PTR(-ENOMEM);
Viresh Kumar9f8ea962016-02-09 10:30:33 +05301279
1280 /* This should be called before OPPs are initialized */
Viresh Kumar2c2709d2016-02-16 14:17:53 +05301281 if (WARN_ON(!list_empty(&opp_table->opp_list))) {
Viresh Kumar9f8ea962016-02-09 10:30:33 +05301282 ret = -EBUSY;
1283 goto err;
1284 }
1285
Viresh Kumardfbe4672016-12-01 16:28:19 +05301286 /* Already have regulators set */
Viresh Kumare231f8d2016-12-01 16:28:22 +05301287 if (opp_table->regulators) {
Viresh Kumar9f8ea962016-02-09 10:30:33 +05301288 ret = -EBUSY;
1289 goto err;
1290 }
Viresh Kumardfbe4672016-12-01 16:28:19 +05301291
1292 opp_table->regulators = kmalloc_array(count,
1293 sizeof(*opp_table->regulators),
1294 GFP_KERNEL);
1295 if (!opp_table->regulators) {
1296 ret = -ENOMEM;
Viresh Kumar9f8ea962016-02-09 10:30:33 +05301297 goto err;
1298 }
1299
Viresh Kumardfbe4672016-12-01 16:28:19 +05301300 for (i = 0; i < count; i++) {
1301 reg = regulator_get_optional(dev, names[i]);
1302 if (IS_ERR(reg)) {
1303 ret = PTR_ERR(reg);
1304 if (ret != -EPROBE_DEFER)
1305 dev_err(dev, "%s: no regulator (%s) found: %d\n",
1306 __func__, names[i], ret);
1307 goto free_regulators;
1308 }
1309
1310 opp_table->regulators[i] = reg;
1311 }
1312
1313 opp_table->regulator_count = count;
Viresh Kumar9f8ea962016-02-09 10:30:33 +05301314
Viresh Kumar94735582016-12-01 16:28:20 +05301315 /* Allocate block only once to pass to set_opp() routines */
1316 ret = _allocate_set_opp_data(opp_table);
1317 if (ret)
1318 goto free_regulators;
1319
Stephen Boyd91291d92016-11-30 16:21:25 +05301320 return opp_table;
Viresh Kumar9f8ea962016-02-09 10:30:33 +05301321
Viresh Kumardfbe4672016-12-01 16:28:19 +05301322free_regulators:
1323 while (i != 0)
1324 regulator_put(opp_table->regulators[--i]);
1325
1326 kfree(opp_table->regulators);
1327 opp_table->regulators = NULL;
Viresh Kumar94735582016-12-01 16:28:20 +05301328 opp_table->regulator_count = 0;
Viresh Kumar9f8ea962016-02-09 10:30:33 +05301329err:
Viresh Kumarfa301842017-01-23 10:11:43 +05301330 dev_pm_opp_put_opp_table(opp_table);
Viresh Kumar9f8ea962016-02-09 10:30:33 +05301331
Stephen Boyd91291d92016-11-30 16:21:25 +05301332 return ERR_PTR(ret);
Viresh Kumar9f8ea962016-02-09 10:30:33 +05301333}
Viresh Kumardfbe4672016-12-01 16:28:19 +05301334EXPORT_SYMBOL_GPL(dev_pm_opp_set_regulators);
Viresh Kumar9f8ea962016-02-09 10:30:33 +05301335
1336/**
Viresh Kumardfbe4672016-12-01 16:28:19 +05301337 * dev_pm_opp_put_regulators() - Releases resources blocked for regulator
1338 * @opp_table: OPP table returned from dev_pm_opp_set_regulators().
Viresh Kumar9f8ea962016-02-09 10:30:33 +05301339 */
Viresh Kumardfbe4672016-12-01 16:28:19 +05301340void dev_pm_opp_put_regulators(struct opp_table *opp_table)
Viresh Kumar9f8ea962016-02-09 10:30:33 +05301341{
Viresh Kumardfbe4672016-12-01 16:28:19 +05301342 int i;
1343
Viresh Kumardfbe4672016-12-01 16:28:19 +05301344 if (!opp_table->regulators) {
1345 pr_err("%s: Doesn't have regulators set\n", __func__);
Viresh Kumarfa301842017-01-23 10:11:43 +05301346 return;
Viresh Kumar9f8ea962016-02-09 10:30:33 +05301347 }
1348
Viresh Kumar2c2709d2016-02-16 14:17:53 +05301349 /* Make sure there are no concurrent readers while updating opp_table */
1350 WARN_ON(!list_empty(&opp_table->opp_list));
Viresh Kumar9f8ea962016-02-09 10:30:33 +05301351
Viresh Kumardfbe4672016-12-01 16:28:19 +05301352 for (i = opp_table->regulator_count - 1; i >= 0; i--)
1353 regulator_put(opp_table->regulators[i]);
1354
Viresh Kumar94735582016-12-01 16:28:20 +05301355 _free_set_opp_data(opp_table);
1356
Viresh Kumardfbe4672016-12-01 16:28:19 +05301357 kfree(opp_table->regulators);
1358 opp_table->regulators = NULL;
1359 opp_table->regulator_count = 0;
Viresh Kumar9f8ea962016-02-09 10:30:33 +05301360
Viresh Kumarfa301842017-01-23 10:11:43 +05301361 dev_pm_opp_put_opp_table(opp_table);
Viresh Kumar9f8ea962016-02-09 10:30:33 +05301362}
Viresh Kumardfbe4672016-12-01 16:28:19 +05301363EXPORT_SYMBOL_GPL(dev_pm_opp_put_regulators);
Viresh Kumar9f8ea962016-02-09 10:30:33 +05301364
Viresh Kumar383934092014-11-25 16:04:18 +05301365/**
Viresh Kumar829a4e82017-06-21 10:29:13 +05301366 * dev_pm_opp_set_clkname() - Set clk name for the device
1367 * @dev: Device for which clk name is being set.
1368 * @name: Clk name.
1369 *
1370 * In order to support OPP switching, OPP layer needs to get pointer to the
1371 * clock for the device. Simple cases work fine without using this routine (i.e.
1372 * by passing connection-id as NULL), but for a device with multiple clocks
1373 * available, the OPP core needs to know the exact name of the clk to use.
1374 *
1375 * This must be called before any OPPs are initialized for the device.
1376 */
1377struct opp_table *dev_pm_opp_set_clkname(struct device *dev, const char *name)
1378{
1379 struct opp_table *opp_table;
1380 int ret;
1381
1382 opp_table = dev_pm_opp_get_opp_table(dev);
1383 if (!opp_table)
1384 return ERR_PTR(-ENOMEM);
1385
1386 /* This should be called before OPPs are initialized */
1387 if (WARN_ON(!list_empty(&opp_table->opp_list))) {
1388 ret = -EBUSY;
1389 goto err;
1390 }
1391
1392 /* Already have default clk set, free it */
1393 if (!IS_ERR(opp_table->clk))
1394 clk_put(opp_table->clk);
1395
1396 /* Find clk for the device */
1397 opp_table->clk = clk_get(dev, name);
1398 if (IS_ERR(opp_table->clk)) {
1399 ret = PTR_ERR(opp_table->clk);
1400 if (ret != -EPROBE_DEFER) {
1401 dev_err(dev, "%s: Couldn't find clock: %d\n", __func__,
1402 ret);
1403 }
1404 goto err;
1405 }
1406
1407 return opp_table;
1408
1409err:
1410 dev_pm_opp_put_opp_table(opp_table);
1411
1412 return ERR_PTR(ret);
1413}
1414EXPORT_SYMBOL_GPL(dev_pm_opp_set_clkname);
1415
1416/**
1417 * dev_pm_opp_put_clkname() - Releases resources blocked for clk.
1418 * @opp_table: OPP table returned from dev_pm_opp_set_clkname().
1419 */
1420void dev_pm_opp_put_clkname(struct opp_table *opp_table)
1421{
1422 /* Make sure there are no concurrent readers while updating opp_table */
1423 WARN_ON(!list_empty(&opp_table->opp_list));
1424
1425 clk_put(opp_table->clk);
1426 opp_table->clk = ERR_PTR(-EINVAL);
1427
1428 dev_pm_opp_put_opp_table(opp_table);
1429}
1430EXPORT_SYMBOL_GPL(dev_pm_opp_put_clkname);
1431
1432/**
Viresh Kumar4dab1602016-12-01 16:28:21 +05301433 * dev_pm_opp_register_set_opp_helper() - Register custom set OPP helper
1434 * @dev: Device for which the helper is getting registered.
1435 * @set_opp: Custom set OPP helper.
1436 *
1437 * This is useful to support complex platforms (like platforms with multiple
1438 * regulators per device), instead of the generic OPP set rate helper.
1439 *
1440 * This must be called before any OPPs are initialized for the device.
Viresh Kumar4dab1602016-12-01 16:28:21 +05301441 */
Viresh Kumarfa301842017-01-23 10:11:43 +05301442struct opp_table *dev_pm_opp_register_set_opp_helper(struct device *dev,
Viresh Kumar4dab1602016-12-01 16:28:21 +05301443 int (*set_opp)(struct dev_pm_set_opp_data *data))
1444{
1445 struct opp_table *opp_table;
1446 int ret;
1447
1448 if (!set_opp)
Viresh Kumarfa301842017-01-23 10:11:43 +05301449 return ERR_PTR(-EINVAL);
Viresh Kumar4dab1602016-12-01 16:28:21 +05301450
Viresh Kumarfa301842017-01-23 10:11:43 +05301451 opp_table = dev_pm_opp_get_opp_table(dev);
1452 if (!opp_table)
1453 return ERR_PTR(-ENOMEM);
Viresh Kumar4dab1602016-12-01 16:28:21 +05301454
1455 /* This should be called before OPPs are initialized */
1456 if (WARN_ON(!list_empty(&opp_table->opp_list))) {
1457 ret = -EBUSY;
1458 goto err;
1459 }
1460
1461 /* Already have custom set_opp helper */
1462 if (WARN_ON(opp_table->set_opp)) {
1463 ret = -EBUSY;
1464 goto err;
1465 }
1466
1467 opp_table->set_opp = set_opp;
1468
Viresh Kumarfa301842017-01-23 10:11:43 +05301469 return opp_table;
Viresh Kumar4dab1602016-12-01 16:28:21 +05301470
1471err:
Viresh Kumarfa301842017-01-23 10:11:43 +05301472 dev_pm_opp_put_opp_table(opp_table);
Viresh Kumar4dab1602016-12-01 16:28:21 +05301473
Viresh Kumarfa301842017-01-23 10:11:43 +05301474 return ERR_PTR(ret);
Viresh Kumar4dab1602016-12-01 16:28:21 +05301475}
1476EXPORT_SYMBOL_GPL(dev_pm_opp_register_set_opp_helper);
1477
1478/**
1479 * dev_pm_opp_register_put_opp_helper() - Releases resources blocked for
1480 * set_opp helper
Viresh Kumarfa301842017-01-23 10:11:43 +05301481 * @opp_table: OPP table returned from dev_pm_opp_register_set_opp_helper().
Viresh Kumar4dab1602016-12-01 16:28:21 +05301482 *
Viresh Kumarfa301842017-01-23 10:11:43 +05301483 * Release resources blocked for platform specific set_opp helper.
Viresh Kumar4dab1602016-12-01 16:28:21 +05301484 */
Viresh Kumarfa301842017-01-23 10:11:43 +05301485void dev_pm_opp_register_put_opp_helper(struct opp_table *opp_table)
Viresh Kumar4dab1602016-12-01 16:28:21 +05301486{
Viresh Kumar4dab1602016-12-01 16:28:21 +05301487 if (!opp_table->set_opp) {
Viresh Kumarfa301842017-01-23 10:11:43 +05301488 pr_err("%s: Doesn't have custom set_opp helper set\n",
1489 __func__);
1490 return;
Viresh Kumar4dab1602016-12-01 16:28:21 +05301491 }
1492
1493 /* Make sure there are no concurrent readers while updating opp_table */
1494 WARN_ON(!list_empty(&opp_table->opp_list));
1495
1496 opp_table->set_opp = NULL;
1497
Viresh Kumarfa301842017-01-23 10:11:43 +05301498 dev_pm_opp_put_opp_table(opp_table);
Viresh Kumar4dab1602016-12-01 16:28:21 +05301499}
1500EXPORT_SYMBOL_GPL(dev_pm_opp_register_put_opp_helper);
1501
1502/**
Nishanth Menone1f60b22010-10-13 00:13:10 +02001503 * dev_pm_opp_add() - Add an OPP table from a table definitions
1504 * @dev: device for which we do this operation
Nishanth Menon47d43ba2013-09-19 16:03:51 -05001505 * @freq: Frequency in Hz for this OPP
Nishanth Menone1f60b22010-10-13 00:13:10 +02001506 * @u_volt: Voltage in uVolts for this OPP
1507 *
Viresh Kumar2c2709d2016-02-16 14:17:53 +05301508 * This function adds an opp definition to the opp table and returns status.
Nishanth Menon47d43ba2013-09-19 16:03:51 -05001509 * The opp is made available by default and it can be controlled using
Nishanth Menone1f60b22010-10-13 00:13:10 +02001510 * dev_pm_opp_enable/disable functions.
1511 *
Viresh Kumara7470db2014-11-25 16:04:17 +05301512 * Return:
1513 * 0 On success OR
1514 * Duplicate OPPs (both freq and volt are same) and opp->available
1515 * -EEXIST Freq are same and volt are different OR
1516 * Duplicate OPPs (both freq and volt are same) and !opp->available
Viresh Kumar383934092014-11-25 16:04:18 +05301517 * -ENOMEM Memory allocation failure
Viresh Kumara7470db2014-11-25 16:04:17 +05301518 */
Nishanth Menone1f60b22010-10-13 00:13:10 +02001519int dev_pm_opp_add(struct device *dev, unsigned long freq, unsigned long u_volt)
1520{
Viresh Kumar8cd2f6e2017-01-02 14:41:01 +05301521 struct opp_table *opp_table;
1522 int ret;
1523
Viresh Kumarb83c1892017-01-23 10:11:45 +05301524 opp_table = dev_pm_opp_get_opp_table(dev);
1525 if (!opp_table)
1526 return -ENOMEM;
Viresh Kumar8cd2f6e2017-01-02 14:41:01 +05301527
1528 ret = _opp_add_v1(opp_table, dev, freq, u_volt, true);
Viresh Kumar8cd2f6e2017-01-02 14:41:01 +05301529
Viresh Kumarb83c1892017-01-23 10:11:45 +05301530 dev_pm_opp_put_opp_table(opp_table);
Viresh Kumar8cd2f6e2017-01-02 14:41:01 +05301531 return ret;
Nishanth Menone1f60b22010-10-13 00:13:10 +02001532}
1533EXPORT_SYMBOL_GPL(dev_pm_opp_add);
1534
Nishanth Menone1f60b22010-10-13 00:13:10 +02001535/**
Nishanth Menon327854c2014-12-24 11:22:56 -06001536 * _opp_set_availability() - helper to set the availability of an opp
Nishanth Menone1f60b22010-10-13 00:13:10 +02001537 * @dev: device for which we do this operation
1538 * @freq: OPP frequency to modify availability
1539 * @availability_req: availability status requested for this opp
1540 *
Viresh Kumar052c6f12017-01-23 10:11:49 +05301541 * Set the availability of an OPP, opp_{enable,disable} share a common logic
1542 * which is isolated here.
Nishanth Menone1f60b22010-10-13 00:13:10 +02001543 *
Nishanth Menon984f16c2014-12-24 11:22:57 -06001544 * Return: -EINVAL for bad pointers, -ENOMEM if no memory available for the
Stephen Boyde1a2d492015-09-24 12:28:44 -07001545 * copy operation, returns 0 if no modification was done OR modification was
Nishanth Menone1f60b22010-10-13 00:13:10 +02001546 * successful.
Nishanth Menone1f60b22010-10-13 00:13:10 +02001547 */
Nishanth Menon327854c2014-12-24 11:22:56 -06001548static int _opp_set_availability(struct device *dev, unsigned long freq,
1549 bool availability_req)
Nishanth Menone1f60b22010-10-13 00:13:10 +02001550{
Viresh Kumar2c2709d2016-02-16 14:17:53 +05301551 struct opp_table *opp_table;
Viresh Kumara7f39872017-01-23 10:11:50 +05301552 struct dev_pm_opp *tmp_opp, *opp = ERR_PTR(-ENODEV);
Nishanth Menone1f60b22010-10-13 00:13:10 +02001553 int r = 0;
1554
Viresh Kumar2c2709d2016-02-16 14:17:53 +05301555 /* Find the opp_table */
1556 opp_table = _find_opp_table(dev);
1557 if (IS_ERR(opp_table)) {
1558 r = PTR_ERR(opp_table);
Nishanth Menone1f60b22010-10-13 00:13:10 +02001559 dev_warn(dev, "%s: Device OPP not found (%d)\n", __func__, r);
Viresh Kumara7f39872017-01-23 10:11:50 +05301560 return r;
Nishanth Menone1f60b22010-10-13 00:13:10 +02001561 }
1562
Viresh Kumar37a73ec2017-01-23 10:11:41 +05301563 mutex_lock(&opp_table->lock);
1564
Nishanth Menone1f60b22010-10-13 00:13:10 +02001565 /* Do we have the frequency? */
Viresh Kumar2c2709d2016-02-16 14:17:53 +05301566 list_for_each_entry(tmp_opp, &opp_table->opp_list, node) {
Nishanth Menone1f60b22010-10-13 00:13:10 +02001567 if (tmp_opp->rate == freq) {
1568 opp = tmp_opp;
1569 break;
1570 }
1571 }
Viresh Kumar37a73ec2017-01-23 10:11:41 +05301572
Nishanth Menone1f60b22010-10-13 00:13:10 +02001573 if (IS_ERR(opp)) {
1574 r = PTR_ERR(opp);
1575 goto unlock;
1576 }
1577
1578 /* Is update really needed? */
1579 if (opp->available == availability_req)
1580 goto unlock;
Nishanth Menone1f60b22010-10-13 00:13:10 +02001581
Viresh Kumara7f39872017-01-23 10:11:50 +05301582 opp->available = availability_req;
Nishanth Menone1f60b22010-10-13 00:13:10 +02001583
Viresh Kumare4d8ae02017-09-21 10:44:36 -07001584 dev_pm_opp_get(opp);
1585 mutex_unlock(&opp_table->lock);
1586
MyungJoo Ham03ca3702011-09-30 22:35:12 +02001587 /* Notify the change of the OPP availability */
1588 if (availability_req)
Viresh Kumar052c6f12017-01-23 10:11:49 +05301589 blocking_notifier_call_chain(&opp_table->head, OPP_EVENT_ENABLE,
Viresh Kumara7f39872017-01-23 10:11:50 +05301590 opp);
MyungJoo Ham03ca3702011-09-30 22:35:12 +02001591 else
Viresh Kumar052c6f12017-01-23 10:11:49 +05301592 blocking_notifier_call_chain(&opp_table->head,
Viresh Kumara7f39872017-01-23 10:11:50 +05301593 OPP_EVENT_DISABLE, opp);
Nishanth Menone1f60b22010-10-13 00:13:10 +02001594
Viresh Kumare4d8ae02017-09-21 10:44:36 -07001595 dev_pm_opp_put(opp);
1596 goto put_table;
1597
Nishanth Menone1f60b22010-10-13 00:13:10 +02001598unlock:
Viresh Kumar5b650b32017-01-23 10:11:48 +05301599 mutex_unlock(&opp_table->lock);
Viresh Kumare4d8ae02017-09-21 10:44:36 -07001600put_table:
Viresh Kumar5b650b32017-01-23 10:11:48 +05301601 dev_pm_opp_put_opp_table(opp_table);
Nishanth Menone1f60b22010-10-13 00:13:10 +02001602 return r;
1603}
1604
1605/**
Nishanth Menon5d4879c2013-09-19 16:03:50 -05001606 * dev_pm_opp_enable() - Enable a specific OPP
Nishanth Menone1f60b22010-10-13 00:13:10 +02001607 * @dev: device for which we do this operation
1608 * @freq: OPP frequency to enable
1609 *
1610 * Enables a provided opp. If the operation is valid, this returns 0, else the
1611 * corresponding error value. It is meant to be used for users an OPP available
Nishanth Menon5d4879c2013-09-19 16:03:50 -05001612 * after being temporarily made unavailable with dev_pm_opp_disable.
Nishanth Menone1f60b22010-10-13 00:13:10 +02001613 *
Nishanth Menon984f16c2014-12-24 11:22:57 -06001614 * Return: -EINVAL for bad pointers, -ENOMEM if no memory available for the
Stephen Boyde1a2d492015-09-24 12:28:44 -07001615 * copy operation, returns 0 if no modification was done OR modification was
Nishanth Menon984f16c2014-12-24 11:22:57 -06001616 * successful.
Nishanth Menone1f60b22010-10-13 00:13:10 +02001617 */
Nishanth Menon5d4879c2013-09-19 16:03:50 -05001618int dev_pm_opp_enable(struct device *dev, unsigned long freq)
Nishanth Menone1f60b22010-10-13 00:13:10 +02001619{
Nishanth Menon327854c2014-12-24 11:22:56 -06001620 return _opp_set_availability(dev, freq, true);
Nishanth Menone1f60b22010-10-13 00:13:10 +02001621}
Nishanth Menon5d4879c2013-09-19 16:03:50 -05001622EXPORT_SYMBOL_GPL(dev_pm_opp_enable);
Nishanth Menone1f60b22010-10-13 00:13:10 +02001623
1624/**
Nishanth Menon5d4879c2013-09-19 16:03:50 -05001625 * dev_pm_opp_disable() - Disable a specific OPP
Nishanth Menone1f60b22010-10-13 00:13:10 +02001626 * @dev: device for which we do this operation
1627 * @freq: OPP frequency to disable
1628 *
1629 * Disables a provided opp. If the operation is valid, this returns
1630 * 0, else the corresponding error value. It is meant to be a temporary
1631 * control by users to make this OPP not available until the circumstances are
Nishanth Menon5d4879c2013-09-19 16:03:50 -05001632 * right to make it available again (with a call to dev_pm_opp_enable).
Nishanth Menone1f60b22010-10-13 00:13:10 +02001633 *
Nishanth Menon984f16c2014-12-24 11:22:57 -06001634 * Return: -EINVAL for bad pointers, -ENOMEM if no memory available for the
Stephen Boyde1a2d492015-09-24 12:28:44 -07001635 * copy operation, returns 0 if no modification was done OR modification was
Nishanth Menon984f16c2014-12-24 11:22:57 -06001636 * successful.
Nishanth Menone1f60b22010-10-13 00:13:10 +02001637 */
Nishanth Menon5d4879c2013-09-19 16:03:50 -05001638int dev_pm_opp_disable(struct device *dev, unsigned long freq)
Nishanth Menone1f60b22010-10-13 00:13:10 +02001639{
Nishanth Menon327854c2014-12-24 11:22:56 -06001640 return _opp_set_availability(dev, freq, false);
Nishanth Menone1f60b22010-10-13 00:13:10 +02001641}
Nishanth Menon5d4879c2013-09-19 16:03:50 -05001642EXPORT_SYMBOL_GPL(dev_pm_opp_disable);
Nishanth Menone1f60b22010-10-13 00:13:10 +02001643
MyungJoo Ham03ca3702011-09-30 22:35:12 +02001644/**
Viresh Kumardc2c9ad2017-01-02 14:41:03 +05301645 * dev_pm_opp_register_notifier() - Register OPP notifier for the device
1646 * @dev: Device for which notifier needs to be registered
1647 * @nb: Notifier block to be registered
Nishanth Menon984f16c2014-12-24 11:22:57 -06001648 *
Viresh Kumardc2c9ad2017-01-02 14:41:03 +05301649 * Return: 0 on success or a negative error value.
MyungJoo Ham03ca3702011-09-30 22:35:12 +02001650 */
Viresh Kumardc2c9ad2017-01-02 14:41:03 +05301651int dev_pm_opp_register_notifier(struct device *dev, struct notifier_block *nb)
MyungJoo Ham03ca3702011-09-30 22:35:12 +02001652{
Viresh Kumardc2c9ad2017-01-02 14:41:03 +05301653 struct opp_table *opp_table;
1654 int ret;
MyungJoo Ham03ca3702011-09-30 22:35:12 +02001655
Viresh Kumardc2c9ad2017-01-02 14:41:03 +05301656 opp_table = _find_opp_table(dev);
Viresh Kumar5b650b32017-01-23 10:11:48 +05301657 if (IS_ERR(opp_table))
1658 return PTR_ERR(opp_table);
1659
Viresh Kumar052c6f12017-01-23 10:11:49 +05301660 ret = blocking_notifier_chain_register(&opp_table->head, nb);
Viresh Kumardc2c9ad2017-01-02 14:41:03 +05301661
Viresh Kumar5b650b32017-01-23 10:11:48 +05301662 dev_pm_opp_put_opp_table(opp_table);
Viresh Kumardc2c9ad2017-01-02 14:41:03 +05301663
1664 return ret;
MyungJoo Ham03ca3702011-09-30 22:35:12 +02001665}
Viresh Kumardc2c9ad2017-01-02 14:41:03 +05301666EXPORT_SYMBOL(dev_pm_opp_register_notifier);
1667
1668/**
1669 * dev_pm_opp_unregister_notifier() - Unregister OPP notifier for the device
1670 * @dev: Device for which notifier needs to be unregistered
1671 * @nb: Notifier block to be unregistered
1672 *
1673 * Return: 0 on success or a negative error value.
1674 */
1675int dev_pm_opp_unregister_notifier(struct device *dev,
1676 struct notifier_block *nb)
1677{
1678 struct opp_table *opp_table;
1679 int ret;
1680
Viresh Kumardc2c9ad2017-01-02 14:41:03 +05301681 opp_table = _find_opp_table(dev);
Viresh Kumar5b650b32017-01-23 10:11:48 +05301682 if (IS_ERR(opp_table))
1683 return PTR_ERR(opp_table);
Viresh Kumardc2c9ad2017-01-02 14:41:03 +05301684
Viresh Kumar052c6f12017-01-23 10:11:49 +05301685 ret = blocking_notifier_chain_unregister(&opp_table->head, nb);
Viresh Kumardc2c9ad2017-01-02 14:41:03 +05301686
Viresh Kumar5b650b32017-01-23 10:11:48 +05301687 dev_pm_opp_put_opp_table(opp_table);
Viresh Kumardc2c9ad2017-01-02 14:41:03 +05301688
1689 return ret;
1690}
1691EXPORT_SYMBOL(dev_pm_opp_unregister_notifier);
Shawn Guob496dfb2012-09-05 01:09:12 +02001692
Sudeep Holla411466c2016-05-03 15:05:04 +01001693/*
1694 * Free OPPs either created using static entries present in DT or even the
1695 * dynamically added entries based on remove_all param.
Shawn Guob496dfb2012-09-05 01:09:12 +02001696 */
Viresh Kumar8cd2f6e2017-01-02 14:41:01 +05301697void _dev_pm_opp_remove_table(struct opp_table *opp_table, struct device *dev,
1698 bool remove_all)
Viresh Kumar9274c892017-01-02 14:41:00 +05301699{
1700 struct dev_pm_opp *opp, *tmp;
1701
Viresh Kumar9274c892017-01-02 14:41:00 +05301702 /* Find if opp_table manages a single device */
1703 if (list_is_singular(&opp_table->dev_list)) {
1704 /* Free static OPPs */
1705 list_for_each_entry_safe(opp, tmp, &opp_table->opp_list, node) {
1706 if (remove_all || !opp->dynamic)
Viresh Kumar70347642017-01-23 10:11:46 +05301707 dev_pm_opp_put(opp);
Viresh Kumar9274c892017-01-02 14:41:00 +05301708 }
1709 } else {
1710 _remove_opp_dev(_find_opp_dev(dev, opp_table), opp_table);
1711 }
1712}
1713
1714void _dev_pm_opp_find_and_remove_table(struct device *dev, bool remove_all)
Viresh Kumar737002b2015-07-29 16:22:58 +05301715{
Viresh Kumar2c2709d2016-02-16 14:17:53 +05301716 struct opp_table *opp_table;
Viresh Kumar737002b2015-07-29 16:22:58 +05301717
Viresh Kumar2c2709d2016-02-16 14:17:53 +05301718 /* Check for existing table for 'dev' */
1719 opp_table = _find_opp_table(dev);
1720 if (IS_ERR(opp_table)) {
1721 int error = PTR_ERR(opp_table);
Viresh Kumar737002b2015-07-29 16:22:58 +05301722
1723 if (error != -ENODEV)
Viresh Kumar2c2709d2016-02-16 14:17:53 +05301724 WARN(1, "%s: opp_table: %d\n",
Viresh Kumar737002b2015-07-29 16:22:58 +05301725 IS_ERR_OR_NULL(dev) ?
1726 "Invalid device" : dev_name(dev),
1727 error);
Viresh Kumar5b650b32017-01-23 10:11:48 +05301728 return;
Viresh Kumar737002b2015-07-29 16:22:58 +05301729 }
1730
Viresh Kumar9274c892017-01-02 14:41:00 +05301731 _dev_pm_opp_remove_table(opp_table, dev, remove_all);
Viresh Kumar737002b2015-07-29 16:22:58 +05301732
Viresh Kumar5b650b32017-01-23 10:11:48 +05301733 dev_pm_opp_put_opp_table(opp_table);
Viresh Kumar737002b2015-07-29 16:22:58 +05301734}
Viresh Kumar129eec52014-11-27 08:54:06 +05301735
1736/**
Sudeep Holla411466c2016-05-03 15:05:04 +01001737 * dev_pm_opp_remove_table() - Free all OPPs associated with the device
Viresh Kumar2c2709d2016-02-16 14:17:53 +05301738 * @dev: device pointer used to lookup OPP table.
Viresh Kumar129eec52014-11-27 08:54:06 +05301739 *
Sudeep Holla411466c2016-05-03 15:05:04 +01001740 * Free both OPPs created using static entries present in DT and the
1741 * dynamically added entries.
Viresh Kumar129eec52014-11-27 08:54:06 +05301742 */
Sudeep Holla411466c2016-05-03 15:05:04 +01001743void dev_pm_opp_remove_table(struct device *dev)
Viresh Kumar129eec52014-11-27 08:54:06 +05301744{
Viresh Kumar9274c892017-01-02 14:41:00 +05301745 _dev_pm_opp_find_and_remove_table(dev, true);
Viresh Kumar8d4d4e92015-06-12 17:10:38 +05301746}
Sudeep Holla411466c2016-05-03 15:05:04 +01001747EXPORT_SYMBOL_GPL(dev_pm_opp_remove_table);