IRQ HPD can be reported with a plug or unplug event.

For plug + IRQ HPD, initialize the link through the plug path before
handling the IRQ. This ensures that the link and MST state are ready for
IRQ processing.

For unplug + IRQ HPD, ignore the IRQ because the link is being torn
down and the IRQ may be stale.

Signed-off-by: Yongxing Mou <[email protected]>
---
 drivers/gpu/drm/msm/dp/dp_display.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
b/drivers/gpu/drm/msm/dp/dp_display.c
index ed0b93e3bd08..94446bcf9448 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -1129,7 +1129,10 @@ static irqreturn_t msm_dp_display_irq_thread(int irq, 
void *dev_id)
                drm_bridge_hpd_notify(dp->msm_dp_display.bridge,
                                      connector_status_connected);
 
-       if (hpd_isr_status & DP_DP_IRQ_HPD_INT_MASK)
+       /* Do not access a link torn down by an unplug latched after an IRQ. */
+       if ((hpd_isr_status & DP_DP_IRQ_HPD_INT_MASK) &&
+           (!(hpd_isr_status & DP_DP_HPD_UNPLUG_INT_MASK) ||
+            (hpd_isr_status & DP_DP_HPD_PLUG_INT_MASK)))
                drm_bridge_hpd_notify_extra(dp->msm_dp_display.bridge,
                                            connector_status_connected,
                                            DRM_CONNECTOR_DP_IRQ_HPD);
@@ -1818,6 +1821,9 @@ void msm_dp_bridge_hpd_notify(struct drm_bridge *bridge,
        if (status == connector_status_connected) {
                if (hpd_link_status == ISR_IRQ_HPD_PULSE_COUNT ||
                    event == DRM_CONNECTOR_DP_IRQ_HPD) {
+                       if (!dp->plugged)
+                               msm_dp_hpd_plug_handle(dp);
+
                        msm_dp_irq_hpd_handle(dp);
                } else if (hpd_link_status == ISR_HPD_REPLUG_COUNT) {
                        msm_dp_hpd_unplug_handle(dp);

-- 
2.43.0

Reply via email to