Commit 520a552f authored by Rafael J. Wysocki's avatar Rafael J. Wysocki
Browse files

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: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
Reviewed-by: default avatarUlf Hansson <ulf.hansson@linaro.org>
Link: https://patch.msgid.link/2978873.e9J7NaK4W3@rjwysocki.net
parent bca84a7b
Loading
Loading
Loading
Loading
+9 −7
Original line number Diff line number Diff line
@@ -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 @@ static int device_prepare(struct device *dev, pm_message_t state)
		pm_runtime_put(dev);
		return ret;
	}
	/* 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
+7 −2
Original line number Diff line number Diff line
@@ -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)
+2 −2
Original line number Diff line number Diff line
@@ -77,7 +77,7 @@ extern int pm_runtime_get_if_in_use(struct device *dev);
extern int pm_schedule_suspend(struct device *dev, unsigned int delay);
extern int __pm_runtime_set_status(struct device *dev, unsigned int status);
extern int pm_runtime_barrier(struct device *dev);
extern void pm_runtime_block_if_disabled(struct device *dev);
extern bool pm_runtime_block_if_disabled(struct device *dev);
extern void pm_runtime_unblock(struct device *dev);
extern void pm_runtime_enable(struct device *dev);
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)
static inline int __pm_runtime_set_status(struct device *dev,
					    unsigned int status) { return 0; }
static inline int pm_runtime_barrier(struct device *dev) { return 0; }
static inline void pm_runtime_block_if_disabled(struct device *dev) {}
static inline bool pm_runtime_block_if_disabled(struct device *dev) { return true; }
static inline void pm_runtime_unblock(struct device *dev) {}
static inline void pm_runtime_enable(struct device *dev) {}
static inline void __pm_runtime_disable(struct device *dev, bool c) {}