mirror of
https://github.com/raspberrypi/linux.git
synced 2025-12-08 10:59:46 +00:00
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: 4e855a6efa ("[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>
This commit is contained in:
committed by
Hans Verkuil
parent
eb005c801e
commit
c28d4921a1
@@ -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 @@
|
|||||||
#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,
|
|||||||
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,
|
|||||||
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;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user