On Thu, 12 Mar 2026 at 22:35, Maíra Canal <[email protected]> wrote:
>
> The bcm2835_asb_control() function uses a tight polling loop to wait
> for the ASB bridge to acknowledge a request. During intensive workloads,
> this handshake intermittently fails for V3D's master ASB on BCM2711,
> resulting in "Failed to disable ASB master for v3d" errors during
> runtime PM suspend. As a consequence, the failed power-off leaves V3D in
> a broken state, leading to bus faults or system hangs on later accesses.
>
> As the timeout is insufficient in some scenarios, increase the polling
> timeout from 1us to 5us, which is still negligible in the context of a
> power domain transition. Also, move the start timestamp to after the
> MMIO write, as the write latency is counted against the timeout,
> reducing the effective wait time for the hardware to respond.
>
> Cc: [email protected]
> Reviewed-by: Stefan Wahren <[email protected]>
> Signed-off-by: Maíra Canal <[email protected]>
>
> ---
> To: Ulf Hansson <[email protected]>
> To: Ray Jui <[email protected]>
> To: Scott Branden <[email protected]>
> Cc: [email protected]
> ---
>  drivers/pmdomain/bcm/bcm2835-power.c | 5 ++---
>  1 file changed, 2 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/pmdomain/bcm/bcm2835-power.c 
> b/drivers/pmdomain/bcm/bcm2835-power.c
> index 
> 0450202bbee2513c9116a36abaa839b460550935..1815eb4ee69b9b672b5e314402f1cc9897c57dcb
>  100644
> --- a/drivers/pmdomain/bcm/bcm2835-power.c
> +++ b/drivers/pmdomain/bcm/bcm2835-power.c
> @@ -166,8 +166,6 @@ static int bcm2835_asb_control(struct bcm2835_power 
> *power, u32 reg, bool enable
>                 break;
>         }
>
> -       start = ktime_get_ns();
> -
>         /* Enable the module's async AXI bridges. */
>         if (enable) {
>                 val = readl(base + reg) & ~ASB_REQ_STOP;
> @@ -176,9 +174,10 @@ static int bcm2835_asb_control(struct bcm2835_power 
> *power, u32 reg, bool enable
>         }
>         writel(PM_PASSWORD | val, base + reg);
>
> +       start = ktime_get_ns();
>         while (!!(readl(base + reg) & ASB_ACK) == enable) {
>                 cpu_relax();
> -               if (ktime_get_ns() - start >= 1000)
> +               if (ktime_get_ns() - start >= 5000)
>                         return -ETIMEDOUT;
>         }

Please consider replacing the above polling-loop with
readl_poll_timeout() or use another one that fits better from the
similar helpers.

Kind regards
Uffe

Reply via email to