Add devres wrapper for dev_pm_opp_set_regulators() dev_pm_opp_put_regulators () to simplify driver code. Signed-off-by: Yangtao Li <tiny.windzz@xxxxxxxxx> --- drivers/opp/core.c | 50 ++++++++++++++++++++++++++++++++++++++++++ include/linux/pm_opp.h | 9 ++++++++ 2 files changed, 59 insertions(+) diff --git a/drivers/opp/core.c b/drivers/opp/core.c index 53fdf33732d5..8709689a7152 100644 --- a/drivers/opp/core.c +++ b/drivers/opp/core.c @@ -1878,6 +1878,56 @@ void dev_pm_opp_put_regulators(struct opp_table *opp_table) } EXPORT_SYMBOL_GPL(dev_pm_opp_put_regulators); +static void devm_pm_opp_regulators_release(void *data) +{ + dev_pm_opp_put_regulators(data); +} + +/** + * devm_pm_opp_set_regulators() - Set regulator names for the device + * @dev: Device for which regulator name is being set. + * @names: Array of pointers to the names of the regulator. + * @count: Number of regulators. + * + * In order to support OPP switching, OPP layer needs to know the name of the + * device's regulators, as the core would be required to switch voltages as + * well. + * + * This must be called before any OPPs are initialized for the device. + * + * The opp_table structure will be freed after the device is destroyed. + */ +struct opp_table *devm_pm_opp_set_regulators(struct device *dev, + const char * const names[], + unsigned int count) +{ + struct opp_table *opp_table; + int err; + + opp_table = dev_pm_opp_set_regulators(dev, names, count); + if (IS_ERR(opp_table)) + return opp_table; + + err = devm_add_action_or_reset(dev, devm_pm_opp_regulators_release, + opp_table); + if (err) + opp_table = ERR_PTR(err); + + return opp_table; +} +EXPORT_SYMBOL_GPL(devm_pm_opp_set_regulators); + +/** + * devm_pm_opp_put_regulators() - Releases resources blocked for regulator + * @dev: Device for which we do this operation. + * @opp_table: OPP table returned from dev_pm_opp_set_regulators(). + */ +void devm_pm_opp_put_regulators(struct device *dev, struct opp_table *opp_table) +{ + devm_release_action(dev, devm_pm_opp_regulators_release, opp_table); +} +EXPORT_SYMBOL_GPL(devm_pm_opp_put_regulators); + /** * dev_pm_opp_set_clkname() - Set clk name for the device * @dev: Device for which clk name is being set. diff --git a/include/linux/pm_opp.h b/include/linux/pm_opp.h index 3418a2874f88..8a329247e08e 100644 --- a/include/linux/pm_opp.h +++ b/include/linux/pm_opp.h @@ -143,6 +143,8 @@ struct opp_table *dev_pm_opp_set_prop_name(struct device *dev, const char *name) void dev_pm_opp_put_prop_name(struct opp_table *opp_table); struct opp_table *dev_pm_opp_set_regulators(struct device *dev, const char * const names[], unsigned int count); void dev_pm_opp_put_regulators(struct opp_table *opp_table); +struct opp_table *devm_pm_opp_set_regulators(struct device *dev, const char * const names[], unsigned int count); +void devm_pm_opp_put_regulators(struct device *dev, struct opp_table *opp_table); struct opp_table *dev_pm_opp_set_clkname(struct device *dev, const char * name); void dev_pm_opp_put_clkname(struct opp_table *opp_table); struct opp_table *devm_pm_opp_set_clkname(struct device *dev, const char *name); @@ -321,6 +323,13 @@ static inline struct opp_table *dev_pm_opp_set_regulators(struct device *dev, co static inline void dev_pm_opp_put_regulators(struct opp_table *opp_table) {} +static inline struct opp_table *devm_pm_opp_set_regulators(struct device *dev, const char * const names[], unsigned int count) +{ + return ERR_PTR(-ENOTSUPP); +} + +static inline void devm_pm_opp_put_regulators(struct device *dev, struct opp_table *opp_table) {} + static inline struct opp_table *dev_pm_opp_set_clkname(struct device *dev, const char * name) { return ERR_PTR(-ENOTSUPP); -- 2.25.1