Skip to content

Commit 520a552

Browse files
committed
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 <[email protected]> Reviewed-by: Ulf Hansson <[email protected]> Link: https://patch.msgid.link/[email protected]
1 parent bca84a7 commit 520a552

File tree

3 files changed

+18
-11
lines changed

3 files changed

+18
-11
lines changed

drivers/base/power/main.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1796,16 +1796,14 @@ static void device_prepare_smart_suspend(struct device *dev)
17961796

17971797
/*
17981798
* The "smart suspend" feature is enabled for devices whose drivers ask
1799-
* for it and for devices without PM callbacks unless runtime PM is
1800-
* disabled and enabling it is blocked for them.
1799+
* for it and for devices without PM callbacks.
18011800
*
18021801
* However, if "smart suspend" is not enabled for the device's parent
18031802
* or any of its suppliers that take runtime PM into account, it cannot
18041803
* be enabled for the device either.
18051804
*/
1806-
dev->power.smart_suspend = (dev->power.no_pm_callbacks ||
1807-
dev_pm_test_driver_flags(dev, DPM_FLAG_SMART_SUSPEND)) &&
1808-
!pm_runtime_blocked(dev);
1805+
dev->power.smart_suspend = dev->power.no_pm_callbacks ||
1806+
dev_pm_test_driver_flags(dev, DPM_FLAG_SMART_SUSPEND);
18091807

18101808
if (!dev_pm_smart_suspend(dev))
18111809
return;
@@ -1843,6 +1841,7 @@ static void device_prepare_smart_suspend(struct device *dev)
18431841
static int device_prepare(struct device *dev, pm_message_t state)
18441842
{
18451843
int (*callback)(struct device *) = NULL;
1844+
bool no_runtime_pm;
18461845
int ret = 0;
18471846

18481847
/*
@@ -1858,7 +1857,7 @@ static int device_prepare(struct device *dev, pm_message_t state)
18581857
* suspend-resume cycle is complete, so prepare to trigger a warning on
18591858
* subsequent attempts to enable it.
18601859
*/
1861-
pm_runtime_block_if_disabled(dev);
1860+
no_runtime_pm = pm_runtime_block_if_disabled(dev);
18621861

18631862
if (dev->power.syscore)
18641863
return 0;
@@ -1893,7 +1892,10 @@ static int device_prepare(struct device *dev, pm_message_t state)
18931892
pm_runtime_put(dev);
18941893
return ret;
18951894
}
1896-
device_prepare_smart_suspend(dev);
1895+
/* Do not enable "smart suspend" for devices without runtime PM. */
1896+
if (!no_runtime_pm)
1897+
device_prepare_smart_suspend(dev);
1898+
18971899
/*
18981900
* A positive return value from ->prepare() means "this device appears
18991901
* to be runtime-suspended and its state is fine, so if it really is

drivers/base/power/runtime.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1460,14 +1460,19 @@ int pm_runtime_barrier(struct device *dev)
14601460
}
14611461
EXPORT_SYMBOL_GPL(pm_runtime_barrier);
14621462

1463-
void pm_runtime_block_if_disabled(struct device *dev)
1463+
bool pm_runtime_block_if_disabled(struct device *dev)
14641464
{
1465+
bool ret;
1466+
14651467
spin_lock_irq(&dev->power.lock);
14661468

1467-
if (dev->power.disable_depth && dev->power.last_status == RPM_INVALID)
1469+
ret = dev->power.disable_depth && dev->power.last_status == RPM_INVALID;
1470+
if (ret)
14681471
dev->power.last_status = RPM_BLOCKED;
14691472

14701473
spin_unlock_irq(&dev->power.lock);
1474+
1475+
return ret;
14711476
}
14721477

14731478
void pm_runtime_unblock(struct device *dev)

include/linux/pm_runtime.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ extern int pm_runtime_get_if_in_use(struct device *dev);
7777
extern int pm_schedule_suspend(struct device *dev, unsigned int delay);
7878
extern int __pm_runtime_set_status(struct device *dev, unsigned int status);
7979
extern int pm_runtime_barrier(struct device *dev);
80-
extern void pm_runtime_block_if_disabled(struct device *dev);
80+
extern bool pm_runtime_block_if_disabled(struct device *dev);
8181
extern void pm_runtime_unblock(struct device *dev);
8282
extern void pm_runtime_enable(struct device *dev);
8383
extern void __pm_runtime_disable(struct device *dev, bool check_resume);
@@ -274,7 +274,7 @@ static inline int pm_runtime_get_if_active(struct device *dev)
274274
static inline int __pm_runtime_set_status(struct device *dev,
275275
unsigned int status) { return 0; }
276276
static inline int pm_runtime_barrier(struct device *dev) { return 0; }
277-
static inline void pm_runtime_block_if_disabled(struct device *dev) {}
277+
static inline bool pm_runtime_block_if_disabled(struct device *dev) { return true; }
278278
static inline void pm_runtime_unblock(struct device *dev) {}
279279
static inline void pm_runtime_enable(struct device *dev) {}
280280
static inline void __pm_runtime_disable(struct device *dev, bool c) {}

0 commit comments

Comments
 (0)