mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 20:48:49 +08:00
serial: sh-sci: Reorder the SCxTDR write after the TDxE clear.
Under qemu there is a race between the TDxE read-and-clear and the SCxTDR write. While on hardware it can be gauranteed that the read-and-clear will happen prior to the character being written out, no such assumption can be made under emulation. As this path happens with IRQs off and the hardware itself doesn't care about the ordering, move the SCxTDR write until after the read-and-clear. Signed-off-by: Vladimir Prus <vladimir@codesourcery.com> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
This commit is contained in:
parent
5d52013cbb
commit
272966c070
@ -85,9 +85,9 @@ static void scif_sercon_putc(int c)
|
|||||||
while (((sci_in(&scif_port, SCFDR) & EPK_FIFO_BITS) >= EPK_FIFO_SIZE))
|
while (((sci_in(&scif_port, SCFDR) & EPK_FIFO_BITS) >= EPK_FIFO_SIZE))
|
||||||
;
|
;
|
||||||
|
|
||||||
sci_out(&scif_port, SCxTDR, c);
|
|
||||||
sci_in(&scif_port, SCxSR);
|
sci_in(&scif_port, SCxSR);
|
||||||
sci_out(&scif_port, SCxSR, 0xf3 & ~(0x20 | 0x40));
|
sci_out(&scif_port, SCxSR, 0xf3 & ~(0x20 | 0x40));
|
||||||
|
sci_out(&scif_port, SCxTDR, c);
|
||||||
|
|
||||||
while ((sci_in(&scif_port, SCxSR) & 0x40) == 0)
|
while ((sci_in(&scif_port, SCxSR) & 0x40) == 0)
|
||||||
;
|
;
|
||||||
|
@ -144,9 +144,9 @@ static void put_char(struct uart_port *port, char c)
|
|||||||
status = sci_in(port, SCxSR);
|
status = sci_in(port, SCxSR);
|
||||||
} while (!(status & SCxSR_TDxE(port)));
|
} while (!(status & SCxSR_TDxE(port)));
|
||||||
|
|
||||||
sci_out(port, SCxTDR, c);
|
|
||||||
sci_in(port, SCxSR); /* Dummy read */
|
sci_in(port, SCxSR); /* Dummy read */
|
||||||
sci_out(port, SCxSR, SCxSR_TDxE_CLEAR(port));
|
sci_out(port, SCxSR, SCxSR_TDxE_CLEAR(port));
|
||||||
|
sci_out(port, SCxTDR, c);
|
||||||
|
|
||||||
spin_unlock_irqrestore(&port->lock, flags);
|
spin_unlock_irqrestore(&port->lock, flags);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user