diff mbox

mac_dbdma: always clear FLUSH bit once DBDMA channel flush is complete

Message ID 1440327055-29695-1-git-send-email-mark.cave-ayland@ilande.co.uk
State New
Headers show

Commit Message

Mark Cave-Ayland Aug. 23, 2015, 10:50 a.m. UTC
The code to flush the DBDMA channel was effectively duplicated in
dbdma_control_write(), except for the fact that the copy executed outside of a
RUN bit transition was broken by not clearing the FLUSH bit once the flush was
complete.

Newer PPC Linux kernels would timeout waiting for the FLUSH bit to clear again
after submitting a FLUSH command. Fix this by always clearing the FLUSH bit
once the channel flush is complete and removing the repeated code.

Reported-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>
---
 hw/misc/macio/mac_dbdma.c |   12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

Comments

Alexander Graf Aug. 24, 2015, 5:24 a.m. UTC | #1
On 23.08.15 03:50, Mark Cave-Ayland wrote:
> The code to flush the DBDMA channel was effectively duplicated in
> dbdma_control_write(), except for the fact that the copy executed outside of a
> RUN bit transition was broken by not clearing the FLUSH bit once the flush was
> complete.
> 
> Newer PPC Linux kernels would timeout waiting for the FLUSH bit to clear again
> after submitting a FLUSH command. Fix this by always clearing the FLUSH bit
> once the channel flush is complete and removing the repeated code.
> 
> Reported-by: Aurelien Jarno <aurelien@aurel32.net>
> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
> Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>

Thanks, applied to ppc-next.


Alex
diff mbox

Patch

diff --git a/hw/misc/macio/mac_dbdma.c b/hw/misc/macio/mac_dbdma.c
index b25e851..779683c 100644
--- a/hw/misc/macio/mac_dbdma.c
+++ b/hw/misc/macio/mac_dbdma.c
@@ -590,10 +590,11 @@  dbdma_control_write(DBDMA_channel *ch)
     if ((ch->regs[DBDMA_STATUS] & RUN) && !(status & RUN)) {
         /* RUN is cleared */
         status &= ~(ACTIVE|DEAD);
-        if ((status & FLUSH) && ch->flush) {
-            ch->flush(&ch->io);
-            status &= ~FLUSH;
-        }
+    }
+
+    if ((status & FLUSH) && ch->flush) {
+        ch->flush(&ch->io);
+        status &= ~FLUSH;
     }
 
     DBDMA_DPRINTF("    status 0x%08x\n", status);
@@ -603,9 +604,6 @@  dbdma_control_write(DBDMA_channel *ch)
     if (status & ACTIVE) {
         DBDMA_kick(dbdma_from_ch(ch));
     }
-    if ((status & FLUSH) && ch->flush) {
-        ch->flush(&ch->io);
-    }
 }
 
 static void dbdma_write(void *opaque, hwaddr addr,