diff options
| author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2025-02-18 21:20:46 +0100 |
|---|---|---|
| committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2025-03-03 13:29:00 +0100 |
| commit | 520a552f19d55825108ab83da093084c9afb50e9 (patch) | |
| tree | 0aef7e72ac0bd67180fd9a0db8f1ddc47a5bbe03 /drivers/base | |
| parent | bca84a7b93fdc744d79d94423c2cb905b1832310 (diff) | |
| download | ath-520a552f19d55825108ab83da093084c9afb50e9.tar.gz | |
PM: sleep: Avoid unnecessary checks in device_prepare_smart_suspend()
Add an optimization (on top of previous changes) to avoid calling
pm_runtime_blocked(), which involves acquiring the device's PM spinlock,
for devices with no PM callbacks and runtime PM "blocked".
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
Link: https://patch.msgid.link/2978873.e9J7NaK4W3@rjwysocki.net
Diffstat (limited to 'drivers/base')
| -rw-r--r-- | drivers/base/power/main.c | 16 | ||||
| -rw-r--r-- | drivers/base/power/runtime.c | 9 |
2 files changed, 16 insertions, 9 deletions
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index cc9903065900d..a06ef91fbdb93 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -1796,16 +1796,14 @@ static void device_prepare_smart_suspend(struct device *dev) /* * The "smart suspend" feature is enabled for devices whose drivers ask - * for it and for devices without PM callbacks unless runtime PM is - * disabled and enabling it is blocked for them. + * for it and for devices without PM callbacks. * * However, if "smart suspend" is not enabled for the device's parent * or any of its suppliers that take runtime PM into account, it cannot * be enabled for the device either. */ - dev->power.smart_suspend = (dev->power.no_pm_callbacks || - dev_pm_test_driver_flags(dev, DPM_FLAG_SMART_SUSPEND)) && - !pm_runtime_blocked(dev); + dev->power.smart_suspend = dev->power.no_pm_callbacks || + dev_pm_test_driver_flags(dev, DPM_FLAG_SMART_SUSPEND); if (!dev_pm_smart_suspend(dev)) return; @@ -1843,6 +1841,7 @@ static void device_prepare_smart_suspend(struct device *dev) static int device_prepare(struct device *dev, pm_message_t state) { int (*callback)(struct device *) = NULL; + bool no_runtime_pm; int ret = 0; /* @@ -1858,7 +1857,7 @@ static int device_prepare(struct device *dev, pm_message_t state) * suspend-resume cycle is complete, so prepare to trigger a warning on * subsequent attempts to enable it. */ - pm_runtime_block_if_disabled(dev); + no_runtime_pm = pm_runtime_block_if_disabled(dev); if (dev->power.syscore) return 0; @@ -1893,7 +1892,10 @@ unlock: pm_runtime_put(dev); return ret; } - device_prepare_smart_suspend(dev); + /* Do not enable "smart suspend" for devices without runtime PM. */ + if (!no_runtime_pm) + device_prepare_smart_suspend(dev); + /* * A positive return value from ->prepare() means "this device appears * to be runtime-suspended and its state is fine, so if it really is diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index c0f5a9f892997..e772e45d30f31 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c @@ -1460,14 +1460,19 @@ int pm_runtime_barrier(struct device *dev) } EXPORT_SYMBOL_GPL(pm_runtime_barrier); -void pm_runtime_block_if_disabled(struct device *dev) +bool pm_runtime_block_if_disabled(struct device *dev) { + bool ret; + spin_lock_irq(&dev->power.lock); - if (dev->power.disable_depth && dev->power.last_status == RPM_INVALID) + ret = dev->power.disable_depth && dev->power.last_status == RPM_INVALID; + if (ret) dev->power.last_status = RPM_BLOCKED; spin_unlock_irq(&dev->power.lock); + + return ret; } void pm_runtime_unblock(struct device *dev) |
