Skip to content

Commit 60d69a7

Browse files
committed
Merge branches 'pm-core' and 'pm-runtime'
Merge a core power management update and runtime PM framework updates for 6.19-rc1: - Add WQ_UNBOUND to pm_wq workqueue (Marco Crivellari) - Add runtime PM wrapper macros for ACQUIRE()/ACQUIRE_ERR() and use them in the PCI core and the ACPI TAD driver (Rafael Wysocki) - Improve runtime PM in the ACPI TAD driver (Rafael Wysocki) - Update pm_runtime_allow/forbid() documentation (Rafael Wysocki) - Fix typos in runtime.c comments (Malaya Kumar Rout) * pm-core: PM: WQ_UNBOUND added to pm_wq workqueue * pm-runtime: PCI/sysfs: Use PM_RUNTIME_ACQUIRE()/PM_RUNTIME_ACQUIRE_ERR() ACPI: TAD: Use PM_RUNTIME_ACQUIRE()/PM_RUNTIME_ACQUIRE_ERR() PM: runtime: Wrapper macros for ACQUIRE()/ACQUIRE_ERR() PM: runtime: fix typos in runtime.c comments ACPI: TAD: Improve runtime PM using guard macros ACPI: TAD: Rearrange runtime PM operations in acpi_tad_remove() PM: runtime: docs: Update pm_runtime_allow/forbid() documentation
3 parents 5e8b7b5 + c9ff363 + 07f42f8 commit 60d69a7

6 files changed

Lines changed: 82 additions & 54 deletions

File tree

Documentation/power/runtime_pm.rst

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -480,16 +480,6 @@ drivers/base/power/runtime.c and include/linux/pm_runtime.h:
480480
`bool pm_runtime_status_suspended(struct device *dev);`
481481
- return true if the device's runtime PM status is 'suspended'
482482

483-
`void pm_runtime_allow(struct device *dev);`
484-
- set the power.runtime_auto flag for the device and decrease its usage
485-
counter (used by the /sys/devices/.../power/control interface to
486-
effectively allow the device to be power managed at run time)
487-
488-
`void pm_runtime_forbid(struct device *dev);`
489-
- unset the power.runtime_auto flag for the device and increase its usage
490-
counter (used by the /sys/devices/.../power/control interface to
491-
effectively prevent the device from being power managed at run time)
492-
493483
`void pm_runtime_no_callbacks(struct device *dev);`
494484
- set the power.no_callbacks flag for the device and remove the runtime
495485
PM attributes from /sys/devices/.../power (or prevent them from being

drivers/acpi/acpi_tad.c

Lines changed: 39 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -90,19 +90,18 @@ static int acpi_tad_set_real_time(struct device *dev, struct acpi_tad_rt *rt)
9090
args[0].buffer.pointer = (u8 *)rt;
9191
args[0].buffer.length = sizeof(*rt);
9292

93-
pm_runtime_get_sync(dev);
93+
PM_RUNTIME_ACQUIRE(dev, pm);
94+
if (PM_RUNTIME_ACQUIRE_ERR(&pm))
95+
return -ENXIO;
9496

9597
status = acpi_evaluate_integer(handle, "_SRT", &arg_list, &retval);
96-
97-
pm_runtime_put_sync(dev);
98-
9998
if (ACPI_FAILURE(status) || retval)
10099
return -EIO;
101100

102101
return 0;
103102
}
104103

105-
static int acpi_tad_get_real_time(struct device *dev, struct acpi_tad_rt *rt)
104+
static int acpi_tad_evaluate_grt(struct device *dev, struct acpi_tad_rt *rt)
106105
{
107106
acpi_handle handle = ACPI_HANDLE(dev);
108107
struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER };
@@ -111,12 +110,7 @@ static int acpi_tad_get_real_time(struct device *dev, struct acpi_tad_rt *rt)
111110
acpi_status status;
112111
int ret = -EIO;
113112

114-
pm_runtime_get_sync(dev);
115-
116113
status = acpi_evaluate_object(handle, "_GRT", NULL, &output);
117-
118-
pm_runtime_put_sync(dev);
119-
120114
if (ACPI_FAILURE(status))
121115
goto out_free;
122116

@@ -139,6 +133,21 @@ static int acpi_tad_get_real_time(struct device *dev, struct acpi_tad_rt *rt)
139133
return ret;
140134
}
141135

136+
static int acpi_tad_get_real_time(struct device *dev, struct acpi_tad_rt *rt)
137+
{
138+
int ret;
139+
140+
PM_RUNTIME_ACQUIRE(dev, pm);
141+
if (PM_RUNTIME_ACQUIRE_ERR(&pm))
142+
return -ENXIO;
143+
144+
ret = acpi_tad_evaluate_grt(dev, rt);
145+
if (ret)
146+
return ret;
147+
148+
return 0;
149+
}
150+
142151
static char *acpi_tad_rt_next_field(char *s, int *val)
143152
{
144153
char *p;
@@ -266,12 +275,11 @@ static int acpi_tad_wake_set(struct device *dev, char *method, u32 timer_id,
266275
args[0].integer.value = timer_id;
267276
args[1].integer.value = value;
268277

269-
pm_runtime_get_sync(dev);
278+
PM_RUNTIME_ACQUIRE(dev, pm);
279+
if (PM_RUNTIME_ACQUIRE_ERR(&pm))
280+
return -ENXIO;
270281

271282
status = acpi_evaluate_integer(handle, method, &arg_list, &retval);
272-
273-
pm_runtime_put_sync(dev);
274-
275283
if (ACPI_FAILURE(status) || retval)
276284
return -EIO;
277285

@@ -314,12 +322,11 @@ static ssize_t acpi_tad_wake_read(struct device *dev, char *buf, char *method,
314322

315323
args[0].integer.value = timer_id;
316324

317-
pm_runtime_get_sync(dev);
325+
PM_RUNTIME_ACQUIRE(dev, pm);
326+
if (PM_RUNTIME_ACQUIRE_ERR(&pm))
327+
return -ENXIO;
318328

319329
status = acpi_evaluate_integer(handle, method, &arg_list, &retval);
320-
321-
pm_runtime_put_sync(dev);
322-
323330
if (ACPI_FAILURE(status))
324331
return -EIO;
325332

@@ -370,12 +377,11 @@ static int acpi_tad_clear_status(struct device *dev, u32 timer_id)
370377

371378
args[0].integer.value = timer_id;
372379

373-
pm_runtime_get_sync(dev);
380+
PM_RUNTIME_ACQUIRE(dev, pm);
381+
if (PM_RUNTIME_ACQUIRE_ERR(&pm))
382+
return -ENXIO;
374383

375384
status = acpi_evaluate_integer(handle, "_CWS", &arg_list, &retval);
376-
377-
pm_runtime_put_sync(dev);
378-
379385
if (ACPI_FAILURE(status) || retval)
380386
return -EIO;
381387

@@ -411,12 +417,11 @@ static ssize_t acpi_tad_status_read(struct device *dev, char *buf, u32 timer_id)
411417

412418
args[0].integer.value = timer_id;
413419

414-
pm_runtime_get_sync(dev);
420+
PM_RUNTIME_ACQUIRE(dev, pm);
421+
if (PM_RUNTIME_ACQUIRE_ERR(&pm))
422+
return -ENXIO;
415423

416424
status = acpi_evaluate_integer(handle, "_GWS", &arg_list, &retval);
417-
418-
pm_runtime_put_sync(dev);
419-
420425
if (ACPI_FAILURE(status))
421426
return -EIO;
422427

@@ -563,8 +568,6 @@ static void acpi_tad_remove(struct platform_device *pdev)
563568

564569
device_init_wakeup(dev, false);
565570

566-
pm_runtime_get_sync(dev);
567-
568571
if (dd->capabilities & ACPI_TAD_RT)
569572
sysfs_remove_group(&dev->kobj, &acpi_tad_time_attr_group);
570573

@@ -573,14 +576,16 @@ static void acpi_tad_remove(struct platform_device *pdev)
573576

574577
sysfs_remove_group(&dev->kobj, &acpi_tad_attr_group);
575578

576-
acpi_tad_disable_timer(dev, ACPI_TAD_AC_TIMER);
577-
acpi_tad_clear_status(dev, ACPI_TAD_AC_TIMER);
578-
if (dd->capabilities & ACPI_TAD_DC_WAKE) {
579-
acpi_tad_disable_timer(dev, ACPI_TAD_DC_TIMER);
580-
acpi_tad_clear_status(dev, ACPI_TAD_DC_TIMER);
579+
scoped_guard(pm_runtime_noresume, dev) {
580+
acpi_tad_disable_timer(dev, ACPI_TAD_AC_TIMER);
581+
acpi_tad_clear_status(dev, ACPI_TAD_AC_TIMER);
582+
if (dd->capabilities & ACPI_TAD_DC_WAKE) {
583+
acpi_tad_disable_timer(dev, ACPI_TAD_DC_TIMER);
584+
acpi_tad_clear_status(dev, ACPI_TAD_DC_TIMER);
585+
}
581586
}
582587

583-
pm_runtime_put_sync(dev);
588+
pm_runtime_suspend(dev);
584589
pm_runtime_disable(dev);
585590
acpi_remove_cmos_rtc_space_handler(handle);
586591
}

drivers/base/power/runtime.c

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ static void update_pm_runtime_accounting(struct device *dev)
9090
/*
9191
* Because ktime_get_mono_fast_ns() is not monotonic during
9292
* timekeeping updates, ensure that 'now' is after the last saved
93-
* timesptamp.
93+
* timestamp.
9494
*/
9595
if (now < last)
9696
return;
@@ -217,7 +217,7 @@ static int dev_memalloc_noio(struct device *dev, void *data)
217217
* resume/suspend callback of any one of its ancestors(or the
218218
* block device itself), the deadlock may be triggered inside the
219219
* memory allocation since it might not complete until the block
220-
* device becomes active and the involed page I/O finishes. The
220+
* device becomes active and the involved page I/O finishes. The
221221
* situation is pointed out first by Alan Stern. Network device
222222
* are involved in iSCSI kind of situation.
223223
*
@@ -1210,7 +1210,7 @@ EXPORT_SYMBOL_GPL(__pm_runtime_resume);
12101210
*
12111211
* Otherwise, if its runtime PM status is %RPM_ACTIVE and (1) @ign_usage_count
12121212
* is set, or (2) @dev is not ignoring children and its active child count is
1213-
* nonero, or (3) the runtime PM usage counter of @dev is not zero, increment
1213+
* nonzero, or (3) the runtime PM usage counter of @dev is not zero, increment
12141214
* the usage counter of @dev and return 1.
12151215
*
12161216
* Otherwise, return 0 without changing the usage counter.
@@ -1664,9 +1664,12 @@ EXPORT_SYMBOL_GPL(devm_pm_runtime_get_noresume);
16641664
* pm_runtime_forbid - Block runtime PM of a device.
16651665
* @dev: Device to handle.
16661666
*
1667-
* Increase the device's usage count and clear its power.runtime_auto flag,
1668-
* so that it cannot be suspended at run time until pm_runtime_allow() is called
1669-
* for it.
1667+
* Resume @dev if already suspended and block runtime suspend of @dev in such
1668+
* a way that it can be unblocked via the /sys/devices/.../power/control
1669+
* interface, or otherwise by calling pm_runtime_allow().
1670+
*
1671+
* Calling this function many times in a row has the same effect as calling it
1672+
* once.
16701673
*/
16711674
void pm_runtime_forbid(struct device *dev)
16721675
{
@@ -1687,7 +1690,13 @@ EXPORT_SYMBOL_GPL(pm_runtime_forbid);
16871690
* pm_runtime_allow - Unblock runtime PM of a device.
16881691
* @dev: Device to handle.
16891692
*
1690-
* Decrease the device's usage count and set its power.runtime_auto flag.
1693+
* Unblock runtime suspend of @dev after it has been blocked by
1694+
* pm_runtime_forbid() (for instance, if it has been blocked via the
1695+
* /sys/devices/.../power/control interface), check if @dev can be
1696+
* suspended and suspend it in that case.
1697+
*
1698+
* Calling this function many times in a row has the same effect as calling it
1699+
* once.
16911700
*/
16921701
void pm_runtime_allow(struct device *dev)
16931702
{

drivers/pci/pci-sysfs.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1517,8 +1517,8 @@ static ssize_t reset_method_store(struct device *dev,
15171517
return count;
15181518
}
15191519

1520-
ACQUIRE(pm_runtime_active_try, pm)(dev);
1521-
if (ACQUIRE_ERR(pm_runtime_active_try, &pm))
1520+
PM_RUNTIME_ACQUIRE(dev, pm);
1521+
if (PM_RUNTIME_ACQUIRE_ERR(&pm))
15221522
return -ENXIO;
15231523

15241524
if (sysfs_streq(buf, "default")) {

include/linux/pm_runtime.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -637,6 +637,30 @@ DEFINE_GUARD_COND(pm_runtime_active_auto, _try,
637637
DEFINE_GUARD_COND(pm_runtime_active_auto, _try_enabled,
638638
pm_runtime_resume_and_get(_T), _RET == 0)
639639

640+
/* ACQUIRE() wrapper macros for the guards defined above. */
641+
642+
#define PM_RUNTIME_ACQUIRE(_dev, _var) \
643+
ACQUIRE(pm_runtime_active_try, _var)(_dev)
644+
645+
#define PM_RUNTIME_ACQUIRE_AUTOSUSPEND(_dev, _var) \
646+
ACQUIRE(pm_runtime_active_auto_try, _var)(_dev)
647+
648+
#define PM_RUNTIME_ACQUIRE_IF_ENABLED(_dev, _var) \
649+
ACQUIRE(pm_runtime_active_try_enabled, _var)(_dev)
650+
651+
#define PM_RUNTIME_ACQUIRE_IF_ENABLED_AUTOSUSPEND(_dev, _var) \
652+
ACQUIRE(pm_runtime_active_auto_try_enabled, _var)(_dev)
653+
654+
/*
655+
* ACQUIRE_ERR() wrapper macro for guard pm_runtime_active.
656+
*
657+
* Always check PM_RUNTIME_ACQUIRE_ERR() after using one of the
658+
* PM_RUNTIME_ACQUIRE*() macros defined above (yes, it can be used with
659+
* any of them) and if it is nonzero, avoid accessing the given device.
660+
*/
661+
#define PM_RUNTIME_ACQUIRE_ERR(_var_ptr) \
662+
ACQUIRE_ERR(pm_runtime_active, _var_ptr)
663+
640664
/**
641665
* pm_runtime_put_sync - Drop device usage counter and run "idle check" if 0.
642666
* @dev: Target device.

kernel/power/main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1068,7 +1068,7 @@ EXPORT_SYMBOL_GPL(pm_wq);
10681068

10691069
static int __init pm_start_workqueue(void)
10701070
{
1071-
pm_wq = alloc_workqueue("pm", WQ_FREEZABLE, 0);
1071+
pm_wq = alloc_workqueue("pm", WQ_FREEZABLE | WQ_UNBOUND, 0);
10721072

10731073
return pm_wq ? 0 : -ENOMEM;
10741074
}

0 commit comments

Comments
 (0)