diff options
Diffstat (limited to 'drivers/base/power/runtime.c')
| -rw-r--r-- | drivers/base/power/runtime.c | 50 | 
1 files changed, 44 insertions, 6 deletions
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index e1a10a03df8e..4c7055009bd6 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c @@ -966,6 +966,30 @@ int __pm_runtime_resume(struct device *dev, int rpmflags)  EXPORT_SYMBOL_GPL(__pm_runtime_resume);  /** + * pm_runtime_get_if_in_use - Conditionally bump up the device's usage counter. + * @dev: Device to handle. + * + * Return -EINVAL if runtime PM is disabled for the device. + * + * If that's not the case and if the device's runtime PM status is RPM_ACTIVE + * and the runtime PM usage counter is nonzero, increment the counter and + * return 1.  Otherwise return 0 without changing the counter. + */ +int pm_runtime_get_if_in_use(struct device *dev) +{ +	unsigned long flags; +	int retval; + +	spin_lock_irqsave(&dev->power.lock, flags); +	retval = dev->power.disable_depth > 0 ? -EINVAL : +		dev->power.runtime_status == RPM_ACTIVE +			&& atomic_inc_not_zero(&dev->power.usage_count); +	spin_unlock_irqrestore(&dev->power.lock, flags); +	return retval; +} +EXPORT_SYMBOL_GPL(pm_runtime_get_if_in_use); + +/**   * __pm_runtime_set_status - Set runtime PM status of a device.   * @dev: Device to handle.   * @status: New runtime PM status of the device. @@ -1390,18 +1414,32 @@ void pm_runtime_init(struct device *dev)  }  /** + * pm_runtime_reinit - Re-initialize runtime PM fields in given device object. + * @dev: Device object to re-initialize. + */ +void pm_runtime_reinit(struct device *dev) +{ +	if (!pm_runtime_enabled(dev)) { +		if (dev->power.runtime_status == RPM_ACTIVE) +			pm_runtime_set_suspended(dev); +		if (dev->power.irq_safe) { +			spin_lock_irq(&dev->power.lock); +			dev->power.irq_safe = 0; +			spin_unlock_irq(&dev->power.lock); +			if (dev->parent) +				pm_runtime_put(dev->parent); +		} +	} +} + +/**   * pm_runtime_remove - Prepare for removing a device from device hierarchy.   * @dev: Device object being removed from device hierarchy.   */  void pm_runtime_remove(struct device *dev)  {  	__pm_runtime_disable(dev, false); - -	/* Change the status back to 'suspended' to match the initial status. */ -	if (dev->power.runtime_status == RPM_ACTIVE) -		pm_runtime_set_suspended(dev); -	if (dev->power.irq_safe && dev->parent) -		pm_runtime_put(dev->parent); +	pm_runtime_reinit(dev);  }  /**  | 
