Hello Sebastian, At 2026-08-07 01:02:09, "Sebastian Reichel" <[email protected]> wrote: >dw_dp_link_disable() may be called in atomic mode disable even when >dw_dp_link_enable() (or an earlier step) failed during atomic mode >enable as there is no error tracking. This would result in broken PHY >power state. > >This is fixed by introducing a new enabled state in the link structure >to ensure the link disabling only happens if it has been properly >enabled in the first place. > >The patch also adds missing error handling in dw_dp_link_enable() >itself to ensure the link enablement becomes an atomic operation. > >Fixes: 86eecc3a9c2e ("drm/bridge: synopsys: Add DW DPTX Controller support >library") >Reported-by: Sashiko <[email protected]>
>Signed-off-by: Sebastian Reichel <[email protected]> Acked-by: Andy Yan <[email protected]> > drivers/gpu/drm/bridge/synopsys/dw-dp.c | 19 ++++++++++++++++++- > 1 file changed, 18 insertions(+), 1 deletion(-) > >diff --git a/drivers/gpu/drm/bridge/synopsys/dw-dp.c >b/drivers/gpu/drm/bridge/synopsys/dw-dp.c >index d7945f7fe9f0..21d60e89126f 100644 >--- a/drivers/gpu/drm/bridge/synopsys/dw-dp.c >+++ b/drivers/gpu/drm/bridge/synopsys/dw-dp.c >@@ -280,6 +280,7 @@ struct dw_dp_link { > unsigned char revision; > unsigned int rate; > unsigned int lanes; >+ bool enabled; > u8 sink_count; > u8 vsc_sdp_supported; > struct dw_dp_link_caps caps; >@@ -1615,6 +1616,9 @@ static void dw_dp_link_disable(struct dw_dp *dp) > { > struct dw_dp_link *link = &dp->link; > >+ if (!link->enabled) >+ return; >+ > if (dw_dp_hpd_detect(dp)) > drm_dp_link_power_down(&dp->aux, dp->link.revision); > >@@ -1624,6 +1628,7 @@ static void dw_dp_link_disable(struct dw_dp *dp) > > link->train.clock_recovered = false; > link->train.channel_equalized = false; >+ link->enabled = false; > } > > static int dw_dp_link_enable(struct dw_dp *dp) >@@ -1636,10 +1641,22 @@ static int dw_dp_link_enable(struct dw_dp *dp) > > ret = drm_dp_link_power_up(&dp->aux, dp->link.revision); > if (ret < 0) >- return ret; >+ goto err_phy_power_off; > > ret = dw_dp_link_train(dp); >+ if (ret < 0) >+ goto err_link_power_down; >+ >+ dp->link.enabled = true; > >+ return 0; >+ >+err_link_power_down: >+ drm_dp_link_power_down(&dp->aux, dp->link.revision); >+ dw_dp_phy_xmit_enable(dp, 0); >+ >+err_phy_power_off: >+ phy_power_off(dp->phy); > return ret; > } > > >-- >2.53.0 >
