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
