From: "Jason-JH.Lin" <jason-jh.lin@xxxxxxxxxxxx> Operations within spin_locks are limited to fast memory access and confirmation of minimum lock duration. Although using spin_lock with config_lock seems to ensure shorter hold times, it is safer to use spin_lock_irqsave due to potential deadlocks and nested interrupt scenarios in interrupt contexts. So change config_lock from spin_lock to spin_lock_irqsave. Fixes: 7f82d9c43879 ("drm/mediatek: Clear pending flag when cmdq packet is done") Signed-off-by: Jason-JH.Lin <jason-jh.lin@xxxxxxxxxxxx> --- drivers/gpu/drm/mediatek/mtk_crtc.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_crtc.c b/drivers/gpu/drm/mediatek/mtk_crtc.c index b752c0b46383..d7f0926f896d 100644 --- a/drivers/gpu/drm/mediatek/mtk_crtc.c +++ b/drivers/gpu/drm/mediatek/mtk_crtc.c @@ -108,14 +108,16 @@ static void mtk_crtc_finish_page_flip(struct mtk_crtc *mtk_crtc) static void mtk_drm_finish_page_flip(struct mtk_crtc *mtk_crtc) { + unsigned long flags; + drm_crtc_handle_vblank(&mtk_crtc->base); - spin_lock(&mtk_crtc->config_lock); + spin_lock_irqsave(&mtk_crtc->config_lock, flags); if (!mtk_crtc->config_updating && mtk_crtc->pending_needs_vblank) { mtk_crtc_finish_page_flip(mtk_crtc); mtk_crtc->pending_needs_vblank = false; } - spin_unlock(&mtk_crtc->config_lock); + spin_unlock_irqrestore(&mtk_crtc->config_lock, flags); } #if IS_REACHABLE(CONFIG_MTK_CMDQ) @@ -313,16 +315,16 @@ static void ddp_cmdq_cb(struct mbox_client *cl, void *mssg) struct mtk_crtc *mtk_crtc = container_of(cmdq_cl, struct mtk_crtc, cmdq_client); struct mtk_crtc_state *state; unsigned int i; + unsigned long flags; if (data->sta < 0) return; state = to_mtk_crtc_state(mtk_crtc->base.state); - spin_lock(&mtk_crtc->config_lock); - + spin_lock_irqsave(&mtk_crtc->config_lock, flags); if (mtk_crtc->config_updating) { - spin_unlock(&mtk_crtc->config_lock); + spin_unlock_irqrestore(&mtk_crtc->config_lock, flags); goto ddp_cmdq_cb_out; } @@ -352,7 +354,7 @@ static void ddp_cmdq_cb(struct mbox_client *cl, void *mssg) mtk_crtc->pending_async_planes = false; } - spin_unlock(&mtk_crtc->config_lock); + spin_unlock_irqrestore(&mtk_crtc->config_lock, flags); ddp_cmdq_cb_out: @@ -585,12 +587,13 @@ static void mtk_crtc_update_config(struct mtk_crtc *mtk_crtc, bool needs_vblank) struct mtk_drm_private *priv = crtc->dev->dev_private; unsigned int pending_planes = 0, pending_async_planes = 0; int i; + unsigned long flags; mutex_lock(&mtk_crtc->hw_lock); - spin_lock(&mtk_crtc->config_lock); + spin_lock_irqsave(&mtk_crtc->config_lock, flags); mtk_crtc->config_updating = true; - spin_unlock(&mtk_crtc->config_lock); + spin_unlock_irqrestore(&mtk_crtc->config_lock, flags); if (needs_vblank) mtk_crtc->pending_needs_vblank = true; @@ -645,9 +648,9 @@ static void mtk_crtc_update_config(struct mtk_crtc *mtk_crtc, bool needs_vblank) mbox_client_txdone(mtk_crtc->cmdq_client.chan, 0); } #endif - spin_lock(&mtk_crtc->config_lock); + spin_lock_irqsave(&mtk_crtc->config_lock, flags); mtk_crtc->config_updating = false; - spin_unlock(&mtk_crtc->config_lock); + spin_unlock_irqrestore(&mtk_crtc->config_lock, flags); mutex_unlock(&mtk_crtc->hw_lock); } -- 2.43.0