Hello Sebastian,

At 2026-08-07 01:02:12, "Sebastian Reichel" <[email protected]> 
wrote:
>The DP AUX transfer method uses a completion triggered by an interrupt,
>which can timeout. If the function runs into the timeout and the
>interrupt fires afterwards, the following DP aux transfer completion
>would trigger immediately without waiting for the interrupt. This in
>turn means the next one would also be broken and so on.
>
>Fix this potential issue by re-initializing the completion directly
>before sending the AUX command.
>
>As this is racy (the interrupt might arrive between the completion
>re-init and the new command being programmed), also reset the AUX
>controller on timeouts and synchronize pending interrupts to gurantee

Typo: s/gurantee/guarantee


>that there are no pending AUX transfers when the dw_dp_aux_transfer()
>returns.
>
>Due to lack of a sink, which generates AUX timeouts, this change is
>effectively untested.
>
>Reported-by: Sashiko <[email protected]>
>Fixes: 86eecc3a9c2e ("drm/bridge: synopsys: Add DW DPTX Controller support 
>library")
>Signed-off-by: Sebastian Reichel <[email protected]>
>---
> drivers/gpu/drm/bridge/synopsys/dw-dp.c | 8 ++++++++
> 1 file changed, 8 insertions(+)
>
>diff --git a/drivers/gpu/drm/bridge/synopsys/dw-dp.c 
>b/drivers/gpu/drm/bridge/synopsys/dw-dp.c
>index b1856418f441..2573ea2bb574 100644
>--- a/drivers/gpu/drm/bridge/synopsys/dw-dp.c
>+++ b/drivers/gpu/drm/bridge/synopsys/dw-dp.c
>@@ -1466,6 +1466,8 @@ static ssize_t dw_dp_aux_transfer(struct drm_dp_aux *aux,
>       if (WARN_ON(msg->size > 16))
>               return -E2BIG;
> 
>+      reinit_completion(&dp->complete);
>+
>       switch (msg->request & ~DP_AUX_I2C_MOT) {
>       case DP_AUX_NATIVE_WRITE:
>       case DP_AUX_I2C_WRITE:
>@@ -1492,6 +1494,12 @@ static ssize_t dw_dp_aux_transfer(struct drm_dp_aux 
>*aux,
>       status = wait_for_completion_timeout(&dp->complete, timeout);
>       if (!status) {
>               dev_err(dp->dev, "timeout waiting for AUX reply\n");
>+              regmap_update_bits(dp->regmap, DW_DP_SOFT_RESET_CTRL,
>+                                 AUX_RESET, FIELD_PREP(AUX_RESET, 1));
>+              usleep_range(10, 20);
>+              regmap_update_bits(dp->regmap, DW_DP_SOFT_RESET_CTRL,
>+                                 AUX_RESET, FIELD_PREP(AUX_RESET, 0));
>+              synchronize_irq(dp->irq);
>               return -ETIMEDOUT;
>       }
> 
>
>-- 
>2.53.0
>

Reply via email to