Re: [PATCH 6/8] PM / OPP: Support adjusting OPP voltages at runtime
From: Roger Lu <hidden>
Date: 2019-07-29 03:39:25
Also in:
linux-arm-kernel, linux-mediatek, linux-pm, lkml
Dear Stephen Boyd, This patch is derived from [1]. Please kindly shares the suggestion to us. Thanks very much. [1]: https://lore.kernel.org/patchwork/patch/599279/ Dear Viresh, I followed _opp_set_availability() coding style to refine dev_pm_opp_adjust_voltage() from this patch. Is this refinement suitable for OPP core? Thanks a lot. On Mon, 2019-05-20 at 12:47 +0800, Viresh Kumar wrote:
On 16-05-19, 17:08, Andrew-sh.Cheng wrote:quoted
From: Stephen Boyd <redacted> On some SoCs the Adaptive Voltage Scaling (AVS) technique is employed to optimize the operating voltage of a device. At a given frequency, the hardware monitors dynamic factors and either makes a suggestion for how much to adjust a voltage for the current frequency, or it automatically adjusts the voltage without software intervention. Add an API to the OPP library for the former case, so that AVS type devices can update the voltages for an OPP when the hardware determines the voltage should change. The assumption is that drivers like CPUfreq or devfreq will register for the OPP notifiers and adjust the voltage according to suggestions that AVS makes. This patch is devired from [1] submitted by Stephen. [1] https://lore.kernel.org/patchwork/patch/599279/ Signed-off-by: Stephen Boyd <redacted> Signed-off-by: Roger Lu <redacted> --- drivers/opp/core.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/pm_opp.h | 11 +++++++ 2 files changed, 89 insertions(+)This is an rcu implementation which got removed long back from OPP core. Please align this with the latest changes.
/**
* dev_pm_opp_adjust_voltage() - helper to change the voltage of an OPP
* @dev: device for which we do this operation
* @freq: OPP frequency to adjust voltage of
* @u_volt: new OPP voltage
*
* Return: -EINVAL for bad pointers, -ENOMEM if no memory available for
the
* copy operation, returns 0 if no modifcation was done OR modification
was
* successful.
*/
int dev_pm_opp_adjust_voltage(struct device *dev, unsigned long freq,
unsigned long u_volt)
{
struct opp_table *opp_table;
struct dev_pm_opp *tmp_opp, *opp = ERR_PTR(-ENODEV);
int r = 0;
/* Find the opp_table */
opp_table = _find_opp_table(dev);
if (IS_ERR(opp_table)) {
r = PTR_ERR(opp_table);
dev_warn(dev, "%s: Device OPP not found (%d)\n", __func__, r);
return r;
}
mutex_lock(&opp_table->lock);
/* Do we have the frequency? */
list_for_each_entry(tmp_opp, &opp_table->opp_list, node) {
if (tmp_opp->rate == freq) {
opp = tmp_opp;
break;
}
}
if (IS_ERR(opp)) {
r = PTR_ERR(opp);
goto adjust_unlock;
}
/* Is update really needed? */
if (opp->supplies->u_volt == u_volt)
goto adjust_unlock;
opp->supplies->u_volt = u_volt;
dev_pm_opp_get(opp);
mutex_unlock(&opp_table->lock);
/* Notify the voltage change of the OPP */
blocking_notifier_call_chain(&opp_table->head,
OPP_EVENT_ADJUST_VOLTAGE,
opp);
dev_pm_opp_put(opp);
goto adjust_put_table;
adjust_unlock:
mutex_unlock(&opp_table->lock);
adjust_put_table:
dev_pm_opp_put_opp_table(opp_table);
return r;
}
Sincerely,
Roger Lu.