On 01/28, Viresh Kumar wrote:
+/**
- dev_pm_opp_put_regulator() - Releases resources blocked for regulator
 
- @dev: Device for which regulator was set.
 
- Locking: The internal device_opp and opp structures are RCU protected.
 
- Hence this function internally uses RCU updater strategy with mutex locks
 
- to keep the integrity of the internal data structures. Callers should ensure
 
- that this function is *NOT* called under RCU protection or in contexts where
 
- mutex cannot be locked.
 - */
 +void dev_pm_opp_put_regulator(struct device *dev) +{
- struct device_opp *dev_opp;
 - mutex_lock(&dev_opp_list_lock);
 - /* Check for existing list for 'dev' first */
 - dev_opp = _find_device_opp(dev);
 - if (IS_ERR(dev_opp)) {
 dev_err(dev, "Failed to find dev_opp: %ld\n", PTR_ERR(dev_opp));goto unlock;- }
 - if (IS_ERR_OR_NULL(dev_opp->regulator)) {
 dev_err(dev, "%s: Doesn't have regulator set\n", __func__);goto unlock;- }
 - /* Make sure there are no concurrent readers while updating dev_opp */
 - WARN_ON(!list_empty(&dev_opp->opp_list));
 - regulator_put(dev_opp->regulator);
 - dev_opp->regulator = ERR_PTR(-EINVAL);
 - /* Try freeing device_opp if this was the last blocking resource */
 - _remove_device_opp(dev_opp);
 +unlock:
- mutex_unlock(&dev_opp_list_lock);
 +} +EXPORT_SYMBOL_GPL(dev_pm_opp_put_regulator);
I'm still lost why we need this API. When the OPP is torn down we can call regulator_put there instead. The same style seems to be done for supported hw, and prop_name, which doesn't make any sense either. Just tear everything down when there aren't any more OPPs in the table.