From 0ea173b7747f7d93931d496a8ca4b329edb612b1 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Wed, 6 Dec 2023 17:52:21 +0000 Subject: [PATCH] pm: device_runtime: Avoid unnecessary resume/suspend We don't need to wait an async put to happen in case it has not started yet. In this case we can simply cancelling the pending work and change the internal state because the device is still active. This way we avoid a suspend and resume cycle. Signed-off-by: Flavio Ceolin --- subsys/pm/device_runtime.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/subsys/pm/device_runtime.c b/subsys/pm/device_runtime.c index 56f0b066a91..a4b64fbe994 100644 --- a/subsys/pm/device_runtime.c +++ b/subsys/pm/device_runtime.c @@ -177,8 +177,22 @@ int pm_device_runtime_get(const struct device *dev) pm->usage++; + /* + * Check if the device has a pending suspend operation (not started + * yet) and cancel it. This way we avoid unnecessary operations because + * the device is actually active. + */ + if ((pm->state == PM_DEVICE_STATE_SUSPENDING) && + ((k_work_cancel_delayable(&pm->work) & K_WORK_RUNNING) == 0)) { + pm->state = PM_DEVICE_STATE_ACTIVE; + goto unlock; + } + if (!k_is_pre_kernel()) { - /* wait until possible async suspend is completed */ + /* + * If the device is already suspending there is + * nothing else we can do but wait until it finishes. + */ while (pm->state == PM_DEVICE_STATE_SUSPENDING) { k_sem_give(&pm->lock);