The plug and detect paths hold plugged_lock while accessing the sink
state, but IRQ-HPD processing updates the same state without that lock.
Unplug also changes the video-test flag and AUX transfer gate before
acquiring the lock.

Cover those updates with plugged_lock so that users of the connection
lock cannot observe partially updated HPD state. This also lets stream
failure cleanup decide whether to preserve AUX while excluding HPD
processing.

Assisted-by: LLM
Signed-off-by: Xilin Wu <[email protected]>
---
 drivers/gpu/drm/msm/dp/dp_display.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
b/drivers/gpu/drm/msm/dp/dp_display.c
index 4dcbd9b99d06..3ca039ff57b8 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -450,6 +450,8 @@ static int msm_dp_hpd_unplug_handle(struct 
msm_dp_display_private *dp)
 {
        struct platform_device *pdev = dp->msm_dp_display.pdev;
 
+       guard(mutex)(&dp->plugged_lock);
+
        dp->panel->video_test = false;
 
        msm_dp_aux_enable_xfers(dp->aux, false);
@@ -458,7 +460,6 @@ static int msm_dp_hpd_unplug_handle(struct 
msm_dp_display_private *dp)
                        dp->msm_dp_display.connector_type,
                        dp->link->sink_count);
 
-       guard(mutex)(&dp->plugged_lock);
        if (!dp->plugged)
                return 0;
 
@@ -500,6 +501,8 @@ static int msm_dp_irq_hpd_handle(struct 
msm_dp_display_private *dp)
        u32 sink_request;
        int rc = 0;
 
+       guard(mutex)(&dp->plugged_lock);
+
        /* irq_hpd can happen at either connected or disconnected state */
        drm_dbg_dp(dp->drm_dev, "Before, type=%d, sink_count=%d\n",
                        dp->msm_dp_display.connector_type,

-- 
2.55.0

Reply via email to