6.18-stable review patch. If anyone has any objections, please let me know. ------------------ From: Linmao Li [ Upstream commit 4009daa5d9a72a67dd497bb4546632b2506a3650 ] 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@vger.kernel.org Signed-off-by: Linmao Li Reviewed-by: Nicolas Dufresne Signed-off-by: Nicolas Dufresne Signed-off-by: Hans Verkuil Signed-off-by: Sasha Levin --- .../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 e7ea2f6a99d5b..c76d657cf8631 100644 --- a/drivers/media/platform/chips-media/wave5/wave5-vpuapi.c +++ b/drivers/media/platform/chips-media/wave5/wave5-vpuapi.c @@ -729,7 +729,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; } @@ -737,16 +737,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); @@ -762,10 +759,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.53.0