Skip to content

Commit c111566

Browse files
Sakari Ailusrafaeljw
authored andcommitted
PM: runtime: Add pm_runtime_get_if_active()
pm_runtime_get_if_in_use() bumps up the PM-runtime usage count if it is not equal to zero and the device's PM-runtime status is 'active'. This works for drivers that do not use autoidle, but for those that do, the function returns zero even when the device is active. In order to maintain sane device state while the device is powered on in the hope that it'll be needed, pm_runtime_get_if_active(dev, true) returns a positive value if the device's PM-runtime status is 'active' when it is called, in which case it also increments the device's usage count. If the second argument of pm_runtime_get_if_active() is 'false', the function behaves just like pm_runtime_get_if_in_use(), so redefine the latter as a wrapper around the former. Signed-off-by: Sakari Ailus <[email protected]> [ rjw: Changelog ] Signed-off-by: Rafael J. Wysocki <[email protected]>
1 parent 98d54f8 commit c111566

File tree

3 files changed

+44
-10
lines changed

3 files changed

+44
-10
lines changed

Documentation/power/runtime_pm.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,12 @@ drivers/base/power/runtime.c and include/linux/pm_runtime.h:
382382
nonzero, increment the counter and return 1; otherwise return 0 without
383383
changing the counter
384384

385+
`int pm_runtime_get_if_active(struct device *dev, bool ign_usage_count);`
386+
- return -EINVAL if 'power.disable_depth' is nonzero; otherwise, if the
387+
runtime PM status is RPM_ACTIVE, and either ign_usage_count is true
388+
or the device's usage_count is non-zero, increment the counter and
389+
return 1; otherwise return 0 without changing the counter
390+
385391
`void pm_runtime_put_noidle(struct device *dev);`
386392
- decrement the device's usage counter
387393

drivers/base/power/runtime.c

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1087,29 +1087,47 @@ int __pm_runtime_resume(struct device *dev, int rpmflags)
10871087
EXPORT_SYMBOL_GPL(__pm_runtime_resume);
10881088

10891089
/**
1090-
* pm_runtime_get_if_in_use - Conditionally bump up the device's usage counter.
1090+
* pm_runtime_get_if_active - Conditionally bump up the device's usage counter.
10911091
* @dev: Device to handle.
10921092
*
10931093
* Return -EINVAL if runtime PM is disabled for the device.
10941094
*
1095-
* If that's not the case and if the device's runtime PM status is RPM_ACTIVE
1096-
* and the runtime PM usage counter is nonzero, increment the counter and
1097-
* return 1. Otherwise return 0 without changing the counter.
1095+
* Otherwise, if the device's runtime PM status is RPM_ACTIVE and either
1096+
* ign_usage_count is true or the device's usage_count is non-zero, increment
1097+
* the counter and return 1. Otherwise return 0 without changing the counter.
1098+
*
1099+
* If ign_usage_count is true, the function can be used to prevent suspending
1100+
* the device when its runtime PM status is RPM_ACTIVE.
1101+
*
1102+
* If ign_usage_count is false, the function can be used to prevent suspending
1103+
* the device when both its runtime PM status is RPM_ACTIVE and its usage_count
1104+
* is non-zero.
1105+
*
1106+
* The caller is resposible for putting the device's usage count when ther
1107+
* return value is greater than zero.
10981108
*/
1099-
int pm_runtime_get_if_in_use(struct device *dev)
1109+
int pm_runtime_get_if_active(struct device *dev, bool ign_usage_count)
11001110
{
11011111
unsigned long flags;
11021112
int retval;
11031113

11041114
spin_lock_irqsave(&dev->power.lock, flags);
1105-
retval = dev->power.disable_depth > 0 ? -EINVAL :
1106-
dev->power.runtime_status == RPM_ACTIVE
1107-
&& atomic_inc_not_zero(&dev->power.usage_count);
1115+
if (dev->power.disable_depth > 0) {
1116+
retval = -EINVAL;
1117+
} else if (dev->power.runtime_status != RPM_ACTIVE) {
1118+
retval = 0;
1119+
} else if (ign_usage_count) {
1120+
retval = 1;
1121+
atomic_inc(&dev->power.usage_count);
1122+
} else {
1123+
retval = atomic_inc_not_zero(&dev->power.usage_count);
1124+
}
11081125
trace_rpm_usage_rcuidle(dev, 0);
11091126
spin_unlock_irqrestore(&dev->power.lock, flags);
1127+
11101128
return retval;
11111129
}
1112-
EXPORT_SYMBOL_GPL(pm_runtime_get_if_in_use);
1130+
EXPORT_SYMBOL_GPL(pm_runtime_get_if_active);
11131131

11141132
/**
11151133
* __pm_runtime_set_status - Set runtime PM status of a device.

include/linux/pm_runtime.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ extern int pm_runtime_force_resume(struct device *dev);
3838
extern int __pm_runtime_idle(struct device *dev, int rpmflags);
3939
extern int __pm_runtime_suspend(struct device *dev, int rpmflags);
4040
extern int __pm_runtime_resume(struct device *dev, int rpmflags);
41-
extern int pm_runtime_get_if_in_use(struct device *dev);
41+
extern int pm_runtime_get_if_active(struct device *dev, bool ign_usage_count);
4242
extern int pm_schedule_suspend(struct device *dev, unsigned int delay);
4343
extern int __pm_runtime_set_status(struct device *dev, unsigned int status);
4444
extern int pm_runtime_barrier(struct device *dev);
@@ -60,6 +60,11 @@ extern void pm_runtime_put_suppliers(struct device *dev);
6060
extern void pm_runtime_new_link(struct device *dev);
6161
extern void pm_runtime_drop_link(struct device *dev);
6262

63+
static inline int pm_runtime_get_if_in_use(struct device *dev)
64+
{
65+
return pm_runtime_get_if_active(dev, false);
66+
}
67+
6368
static inline void pm_suspend_ignore_children(struct device *dev, bool enable)
6469
{
6570
dev->power.ignore_children = enable;
@@ -143,6 +148,11 @@ static inline int pm_runtime_get_if_in_use(struct device *dev)
143148
{
144149
return -EINVAL;
145150
}
151+
static inline int pm_runtime_get_if_active(struct device *dev,
152+
bool ign_usage_count)
153+
{
154+
return -EINVAL;
155+
}
146156
static inline int __pm_runtime_set_status(struct device *dev,
147157
unsigned int status) { return 0; }
148158
static inline int pm_runtime_barrier(struct device *dev) { return 0; }

0 commit comments

Comments
 (0)