media: mediatek: vcodec: fix possible unbalanced PM counter
authorEugen Hristev <eugen.hristev@collabora.com>
Thu, 28 Dec 2023 11:32:40 +0000 (13:32 +0200)
committerHans Verkuil <hverkuil-cisco@xs4all.nl>
Sat, 27 Apr 2024 08:04:30 +0000 (10:04 +0200)
It is possible that mtk_vcodec_enc_pw_on fails, and in that scenario
the PM counter is not incremented, and subsequent call to
mtk_vcodec_enc_pw_off decrements the counter, leading to a PM imbalance.
Fix by bailing out of venc_if_encode in the case when mtk_vcodec_enc_pw_on
fails.

Fixes: 4e855a6efa54 ("[media] vcodec: mediatek: Add Mediatek V4L2 Video Encoder Driver")
Signed-off-by: Eugen Hristev <eugen.hristev@collabora.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
Signed-off-by: Sebastian Fricke <sebastian.fricke@collabora.com>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_pm.c
drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_pm.h
drivers/media/platform/mediatek/vcodec/encoder/venc_drv_if.c

index a22b7dfc656e145f995ae36cd80a802dcfeb2b35..1a2b14a3e219c2b3c9f90832caf0d85bf932417a 100644 (file)
@@ -58,13 +58,15 @@ int mtk_vcodec_init_enc_clk(struct mtk_vcodec_enc_dev *mtkdev)
        return 0;
 }
 
-void mtk_vcodec_enc_pw_on(struct mtk_vcodec_pm *pm)
+int mtk_vcodec_enc_pw_on(struct mtk_vcodec_pm *pm)
 {
        int ret;
 
        ret = pm_runtime_resume_and_get(pm->dev);
        if (ret)
                dev_err(pm->dev, "pm_runtime_resume_and_get fail: %d", ret);
+
+       return ret;
 }
 
 void mtk_vcodec_enc_pw_off(struct mtk_vcodec_pm *pm)
index 157ea08ba9e36a15b117af71f88b55988e5efe29..2e28f25e36cc42bc596d5cecb11838f297668e27 100644 (file)
@@ -10,7 +10,7 @@
 #include "mtk_vcodec_enc_drv.h"
 
 int mtk_vcodec_init_enc_clk(struct mtk_vcodec_enc_dev *dev);
-void mtk_vcodec_enc_pw_on(struct mtk_vcodec_pm *pm);
+int mtk_vcodec_enc_pw_on(struct mtk_vcodec_pm *pm);
 void mtk_vcodec_enc_pw_off(struct mtk_vcodec_pm *pm);
 void mtk_vcodec_enc_clock_on(struct mtk_vcodec_pm *pm);
 void mtk_vcodec_enc_clock_off(struct mtk_vcodec_pm *pm);
index c402a686f3cb2d57813383f66a68e0b0cf1f884a..e83747b8d69ab37be8c15aa79418f1be22e5a5cf 100644 (file)
@@ -64,7 +64,9 @@ int venc_if_encode(struct mtk_vcodec_enc_ctx *ctx,
        ctx->dev->curr_ctx = ctx;
        spin_unlock_irqrestore(&ctx->dev->irqlock, flags);
 
-       mtk_vcodec_enc_pw_on(&ctx->dev->pm);
+       ret = mtk_vcodec_enc_pw_on(&ctx->dev->pm);
+       if (ret)
+               goto venc_if_encode_pw_on_err;
        mtk_vcodec_enc_clock_on(&ctx->dev->pm);
        ret = ctx->enc_if->encode(ctx->drv_handle, opt, frm_buf,
                                  bs_buf, result);
@@ -75,6 +77,7 @@ int venc_if_encode(struct mtk_vcodec_enc_ctx *ctx,
        ctx->dev->curr_ctx = NULL;
        spin_unlock_irqrestore(&ctx->dev->irqlock, flags);
 
+venc_if_encode_pw_on_err:
        mtk_venc_unlock(ctx);
        return ret;
 }