summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
diff options
context:
space:
mode:
authorRex-BC Chen <rex-bc.chen@mediatek.com>2022-03-21 15:23:20 +0800
committerChun-Kuang Hu <chunkuang.hu@kernel.org>2022-04-06 07:10:26 +0800
commitb74d921b900b6ce38c6247c0a1c86be9f3746493 (patch)
treee39c5eac570e2bb0e82cfbf3491f3bd1d69522c3 /drivers/gpu/drm/mediatek/mtk_drm_crtc.c
parent07fb1e5babd5d3d4228517295db2ea4067ce2a79 (diff)
drm/mediatek: Add vblank register/unregister callback functions
We encountered a kernel panic issue that callback data will be NULL when it's using in ovl irq handler. There is a timing issue between mtk_disp_ovl_irq_handler() and mtk_ovl_disable_vblank(). To resolve this issue, we use the flow to register/unregister vblank cb: - Register callback function and callback data when crtc creates. - Unregister callback function and callback data when crtc destroies. With this solution, we can assure callback data will not be NULL when vblank is disable. Link: https://patchwork.kernel.org/project/linux-mediatek/patch/20220321072320.15019-1-rex-bc.chen@mediatek.com/ Fixes: 9b0704988b15 ("drm/mediatek: Register vblank callback function") Signed-off-by: Rex-BC Chen <rex-bc.chen@mediatek.com> Reviewed-by: jason-jh.lin <jason-jh.lin@mediatek.com> Signed-off-by: Chun-Kuang Hu <chunkuang.hu@kernel.org>
Diffstat (limited to 'drivers/gpu/drm/mediatek/mtk_drm_crtc.c')
-rw-r--r--drivers/gpu/drm/mediatek/mtk_drm_crtc.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index a6adc4ea48e1..42cc7052b050 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -152,6 +152,7 @@ static void mtk_drm_cmdq_pkt_destroy(struct cmdq_pkt *pkt)
static void mtk_drm_crtc_destroy(struct drm_crtc *crtc)
{
struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
+ int i;
mtk_mutex_put(mtk_crtc->mutex);
#if IS_REACHABLE(CONFIG_MTK_CMDQ)
@@ -162,6 +163,14 @@ static void mtk_drm_crtc_destroy(struct drm_crtc *crtc)
mtk_crtc->cmdq_client.chan = NULL;
}
#endif
+
+ for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
+ struct mtk_ddp_comp *comp;
+
+ comp = mtk_crtc->ddp_comp[i];
+ mtk_ddp_comp_unregister_vblank_cb(comp);
+ }
+
drm_crtc_cleanup(crtc);
}
@@ -618,7 +627,7 @@ static int mtk_drm_crtc_enable_vblank(struct drm_crtc *crtc)
struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];
- mtk_ddp_comp_enable_vblank(comp, mtk_crtc_ddp_irq, &mtk_crtc->base);
+ mtk_ddp_comp_enable_vblank(comp);
return 0;
}
@@ -927,6 +936,9 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
if (comp->funcs->ctm_set)
has_ctm = true;
}
+
+ mtk_ddp_comp_register_vblank_cb(comp, mtk_crtc_ddp_irq,
+ &mtk_crtc->base);
}
for (i = 0; i < mtk_crtc->ddp_comp_nr; i++)