Commit c28d4921 authored by Eugen Hristev's avatar Eugen Hristev Committed by Hans Verkuil

media: mediatek: vcodec: fix possible unbalanced PM counter

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: 4e855a6e ("[media] vcodec: mediatek: Add Mediatek V4L2 Video Encoder Driver")
Signed-off-by: default avatarEugen Hristev <eugen.hristev@collabora.com>
Reviewed-by: default avatarAngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Signed-off-by: default avatarAndrzej Pietrasiewicz <andrzej.p@collabora.com>
Signed-off-by: default avatarSebastian Fricke <sebastian.fricke@collabora.com>
Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
parent eb005c80
...@@ -58,13 +58,15 @@ int mtk_vcodec_init_enc_clk(struct mtk_vcodec_enc_dev *mtkdev) ...@@ -58,13 +58,15 @@ int mtk_vcodec_init_enc_clk(struct mtk_vcodec_enc_dev *mtkdev)
return 0; 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; int ret;
ret = pm_runtime_resume_and_get(pm->dev); ret = pm_runtime_resume_and_get(pm->dev);
if (ret) if (ret)
dev_err(pm->dev, "pm_runtime_resume_and_get fail: %d", 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) void mtk_vcodec_enc_pw_off(struct mtk_vcodec_pm *pm)
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
#include "mtk_vcodec_enc_drv.h" #include "mtk_vcodec_enc_drv.h"
int mtk_vcodec_init_enc_clk(struct mtk_vcodec_enc_dev *dev); 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_pw_off(struct mtk_vcodec_pm *pm);
void mtk_vcodec_enc_clock_on(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); void mtk_vcodec_enc_clock_off(struct mtk_vcodec_pm *pm);
......
...@@ -64,7 +64,9 @@ int venc_if_encode(struct mtk_vcodec_enc_ctx *ctx, ...@@ -64,7 +64,9 @@ int venc_if_encode(struct mtk_vcodec_enc_ctx *ctx,
ctx->dev->curr_ctx = ctx; ctx->dev->curr_ctx = ctx;
spin_unlock_irqrestore(&ctx->dev->irqlock, flags); 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); mtk_vcodec_enc_clock_on(&ctx->dev->pm);
ret = ctx->enc_if->encode(ctx->drv_handle, opt, frm_buf, ret = ctx->enc_if->encode(ctx->drv_handle, opt, frm_buf,
bs_buf, result); bs_buf, result);
...@@ -75,6 +77,7 @@ int venc_if_encode(struct mtk_vcodec_enc_ctx *ctx, ...@@ -75,6 +77,7 @@ int venc_if_encode(struct mtk_vcodec_enc_ctx *ctx,
ctx->dev->curr_ctx = NULL; ctx->dev->curr_ctx = NULL;
spin_unlock_irqrestore(&ctx->dev->irqlock, flags); spin_unlock_irqrestore(&ctx->dev->irqlock, flags);
venc_if_encode_pw_on_err:
mtk_venc_unlock(ctx); mtk_venc_unlock(ctx);
return ret; return ret;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment