mirror of
https://github.com/torvalds/linux
synced 2024-11-05 18:23:50 +00:00
serial: MPSC: Remove race between Rx stop & restart
The patch in commit ID f7232056bf
stops (aborts)
the MPSC's receive engine just before restarting it. Unfortunately, it
doesn't wait for the abort to complete before restarting it which creates a
race between the abort and the restart. If the restart occurs first, the
in-progress abort stops it again and the rx engine remains stopped.
Instead, do the abort when the SDMA engine is being stopped. Make sure to
wait for the abort to complete before continuing.
Signed-off-by: Carlos Sanchez <carlos.sanchez@gecoinc.com>
Signed-off-by: Mark A. Greer <mgreer@mvista.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
817794e0df
commit
6c1ead5e77
1 changed files with 14 additions and 2 deletions
|
@ -1363,8 +1363,6 @@ mpsc_start_rx(struct mpsc_port_info *pi)
|
|||
{
|
||||
pr_debug("mpsc_start_rx[%d]: Starting...\n", pi->port.line);
|
||||
|
||||
/* Issue a Receive Abort to clear any receive errors */
|
||||
writel(MPSC_CHR_2_RA, pi->mpsc_base + MPSC_CHR_2);
|
||||
if (pi->rcv_data) {
|
||||
mpsc_enter_hunt(pi);
|
||||
mpsc_sdma_cmd(pi, SDMA_SDCM_ERD);
|
||||
|
@ -1379,6 +1377,20 @@ mpsc_stop_rx(struct uart_port *port)
|
|||
|
||||
pr_debug("mpsc_stop_rx[%d]: Stopping...\n", port->line);
|
||||
|
||||
if (pi->mirror_regs) {
|
||||
writel(pi->MPSC_CHR_2_m | MPSC_CHR_2_RA,
|
||||
pi->mpsc_base + MPSC_CHR_2);
|
||||
/* Erratum prevents reading CHR_2 so just delay for a while */
|
||||
udelay(100);
|
||||
}
|
||||
else {
|
||||
writel(readl(pi->mpsc_base + MPSC_CHR_2) | MPSC_CHR_2_RA,
|
||||
pi->mpsc_base + MPSC_CHR_2);
|
||||
|
||||
while (readl(pi->mpsc_base + MPSC_CHR_2) & MPSC_CHR_2_RA)
|
||||
udelay(10);
|
||||
}
|
||||
|
||||
mpsc_sdma_cmd(pi, SDMA_SDCM_AR);
|
||||
return;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue