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@xxxxxxxxxxxxx> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@xxxxxxxxxxxxx> --- Changes in v2: - collect R-b .../platform/mediatek/vcodec/encoder/mtk_vcodec_enc_pm.c | 4 +++- .../platform/mediatek/vcodec/encoder/mtk_vcodec_enc_pm.h | 2 +- drivers/media/platform/mediatek/vcodec/encoder/venc_drv_if.c | 5 ++++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_pm.c b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_pm.c index a22b7dfc656e..1a2b14a3e219 100644 --- a/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_pm.c +++ b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_pm.c @@ -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) diff --git a/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_pm.h b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_pm.h index 157ea08ba9e3..2e28f25e36cc 100644 --- a/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_pm.h +++ b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_pm.h @@ -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); diff --git a/drivers/media/platform/mediatek/vcodec/encoder/venc_drv_if.c b/drivers/media/platform/mediatek/vcodec/encoder/venc_drv_if.c index c402a686f3cb..e83747b8d69a 100644 --- a/drivers/media/platform/mediatek/vcodec/encoder/venc_drv_if.c +++ b/drivers/media/platform/mediatek/vcodec/encoder/venc_drv_if.c @@ -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; } -- 2.34.1