[PATCH] media: chips-media: wave5: Balance runtime PM on encoder close errors
From: Linmao Li
Date: Fri Jul 17 2026 - 04:00:19 EST
wave5_vpu_enc_close() resumes the device before taking the hardware lock.
Its three error paths call pm_runtime_resume_and_get() again instead of
dropping that reference. Each failure therefore increments the runtime PM
usage count twice and can prevent the device from suspending afterward.
Replace the extra resume calls with pm_runtime_put_sync() to balance the
reference acquired on entry, matching the successful close path. This
aligns wave5_vpu_enc_close() with wave5_vpu_dec_close(), which already
releases the reference on its error paths.
Fixes: 2092b3833487 ("media: chips-media: wave5: Support runtime suspend/resume")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Linmao Li <lilinmao@xxxxxxxxxx>
---
.../platform/chips-media/wave5/wave5-vpuapi.c | 15 +++++++--------
1 file changed, 7 insertions(+), 8 deletions(-)
diff --git a/drivers/media/platform/chips-media/wave5/wave5-vpuapi.c b/drivers/media/platform/chips-media/wave5/wave5-vpuapi.c
index f77abd5e122a..4c1842f02c88 100644
--- a/drivers/media/platform/chips-media/wave5/wave5-vpuapi.c
+++ b/drivers/media/platform/chips-media/wave5/wave5-vpuapi.c
@@ -754,7 +754,7 @@ int wave5_vpu_enc_close(struct vpu_instance *inst, u32 *fail_res)
ret = mutex_lock_interruptible(&vpu_dev->hw_lock);
if (ret) {
- pm_runtime_resume_and_get(inst->dev->dev);
+ pm_runtime_put_sync(inst->dev->dev);
return ret;
}
@@ -762,16 +762,13 @@ int wave5_vpu_enc_close(struct vpu_instance *inst, u32 *fail_res)
ret = wave5_vpu_enc_finish_seq(inst, fail_res);
if (ret < 0 && *fail_res != WAVE5_SYSERR_VPU_STILL_RUNNING) {
dev_warn(inst->dev->dev, "enc_finish_seq timed out\n");
- pm_runtime_resume_and_get(inst->dev->dev);
- mutex_unlock(&vpu_dev->hw_lock);
- return ret;
+ goto unlock_and_return;
}
if (*fail_res == WAVE5_SYSERR_VPU_STILL_RUNNING &&
retry++ >= MAX_FIRMWARE_CALL_RETRY) {
- pm_runtime_resume_and_get(inst->dev->dev);
- mutex_unlock(&vpu_dev->hw_lock);
- return -ETIMEDOUT;
+ ret = -ETIMEDOUT;
+ goto unlock_and_return;
}
} while (ret != 0);
@@ -787,10 +784,12 @@ int wave5_vpu_enc_close(struct vpu_instance *inst, u32 *fail_res)
}
wave5_vdi_free_dma_memory(vpu_dev, &p_enc_info->vb_task);
+
+unlock_and_return:
mutex_unlock(&vpu_dev->hw_lock);
pm_runtime_put_sync(inst->dev->dev);
- return 0;
+ return ret;
}
int wave5_vpu_enc_register_frame_buffer(struct vpu_instance *inst, unsigned int num,
--
2.25.1