On 18-01-21, 03:55, Dmitry Osipenko wrote: > Extend OPP API with dev_pm_opp_sync_regulators() function, which syncs > voltage state of regulators. > > Tested-by: Peter Geis <pgwipeout@xxxxxxxxx> > Tested-by: Nicolas Chauvet <kwizart@xxxxxxxxx> > Tested-by: Matt Merhar <mattmerhar@xxxxxxxxxxxxxx> > Signed-off-by: Dmitry Osipenko <digetx@xxxxxxxxx> > --- > drivers/opp/core.c | 45 ++++++++++++++++++++++++++++++++++++++++++ > include/linux/pm_opp.h | 6 ++++++ > 2 files changed, 51 insertions(+) > > diff --git a/drivers/opp/core.c b/drivers/opp/core.c > index 7b4d07279638..99d18befc209 100644 > --- a/drivers/opp/core.c > +++ b/drivers/opp/core.c > @@ -2686,3 +2686,48 @@ void dev_pm_opp_remove_table(struct device *dev) > dev_pm_opp_put_opp_table(opp_table); > } > EXPORT_SYMBOL_GPL(dev_pm_opp_remove_table); > + > +/** > + * dev_pm_opp_sync_regulators() - Sync state of voltage regulators > + * @dev: device for which we do this operation > + * > + * Sync voltage state of the OPP table regulators. > + * > + * Return: 0 on success or a negative error value. > + */ > +int dev_pm_opp_sync_regulators(struct device *dev) > +{ > + struct opp_table *opp_table; > + struct regulator *reg; > + int i, ret = 0; > + > + /* Device may not have OPP table */ > + opp_table = _find_opp_table(dev); > + if (IS_ERR(opp_table)) > + return 0; > + > + /* Regulator may not be required for the device */ > + if (!opp_table->regulators) > + goto put_table; > + > + mutex_lock(&opp_table->lock); What exactly do you need this lock for ? > + > + /* Nothing to sync if voltage wasn't changed */ > + if (!opp_table->enabled) > + goto unlock; > + > + for (i = 0; i < opp_table->regulator_count; i++) { > + reg = opp_table->regulators[i]; > + ret = regulator_sync_voltage(reg); > + if (ret) > + break; > + } > +unlock: > + mutex_unlock(&opp_table->lock); > +put_table: > + /* Drop reference taken by _find_opp_table() */ > + dev_pm_opp_put_opp_table(opp_table); > + > + return ret; > +} > +EXPORT_SYMBOL_GPL(dev_pm_opp_sync_regulators); > diff --git a/include/linux/pm_opp.h b/include/linux/pm_opp.h > index c24bd34339d7..1c3a09cc8dcd 100644 > --- a/include/linux/pm_opp.h > +++ b/include/linux/pm_opp.h > @@ -162,6 +162,7 @@ int dev_pm_opp_set_sharing_cpus(struct device *cpu_dev, const struct cpumask *cp > int dev_pm_opp_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask); > void dev_pm_opp_remove_table(struct device *dev); > void dev_pm_opp_cpumask_remove_table(const struct cpumask *cpumask); > +int dev_pm_opp_sync_regulators(struct device *dev); > #else > static inline struct opp_table *dev_pm_opp_get_opp_table(struct device *dev) > { > @@ -398,6 +399,11 @@ static inline void dev_pm_opp_cpumask_remove_table(const struct cpumask *cpumask > { > } > > +static inline int dev_pm_opp_sync_regulators(struct device *dev) > +{ > + return -ENOTSUPP; > +} > + > #endif /* CONFIG_PM_OPP */ > > #if defined(CONFIG_PM_OPP) && defined(CONFIG_OF) > -- > 2.29.2 -- viresh