bus: ti-sysc: Flush posted write only after srst_udelay
authorTony Lindgren <tony@atomide.com>
Fri, 24 Nov 2023 08:50:56 +0000 (10:50 +0200)
committerTony Lindgren <tony@atomide.com>
Tue, 28 Nov 2023 10:57:16 +0000 (12:57 +0200)
Commit 34539b442b3b ("bus: ti-sysc: Flush posted write on enable before
reset") caused a regression reproducable on omap4 duovero where the ISS
target module can produce interconnect errors on boot. Turns out the
registers are not accessible until after a delay for devices needing
a ti,sysc-delay-us value.

Let's fix this by flushing the posted write only after the reset delay.
We do flushing also for ti,sysc-delay-us using devices as that should
trigger an interconnect error if the delay is not properly configured.

Let's also add some comments while at it.

Fixes: 34539b442b3b ("bus: ti-sysc: Flush posted write on enable before reset")
Cc: stable@vger.kernel.org
Signed-off-by: Tony Lindgren <tony@atomide.com>
drivers/bus/ti-sysc.c

index d57bc066dce6b4c5bd97f5a662928b2b590f7221..9ed9239b1228f6f5ad979ab9d7dc37d084a814f1 100644 (file)
@@ -2158,13 +2158,23 @@ static int sysc_reset(struct sysc *ddata)
                sysc_val = sysc_read_sysconfig(ddata);
                sysc_val |= sysc_mask;
                sysc_write(ddata, sysc_offset, sysc_val);
-               /* Flush posted write */
+
+               /*
+                * Some devices need a delay before reading registers
+                * after reset. Presumably a srst_udelay is not needed
+                * for devices that use a rstctrl register reset.
+                */
+               if (ddata->cfg.srst_udelay)
+                       fsleep(ddata->cfg.srst_udelay);
+
+               /*
+                * Flush posted write. For devices needing srst_udelay
+                * this should trigger an interconnect error if the
+                * srst_udelay value is needed but not configured.
+                */
                sysc_val = sysc_read_sysconfig(ddata);
        }
 
-       if (ddata->cfg.srst_udelay)
-               fsleep(ddata->cfg.srst_udelay);
-
        if (ddata->post_reset_quirk)
                ddata->post_reset_quirk(ddata);