From c98c406eb2c518c7c5bc922fafa1f9fdcb7b76f4 Mon Sep 17 00:00:00 2001 From: David Howells Date: Wed, 12 Dec 2012 15:36:37 +0000 Subject: [PATCH] MN10300: ttySM: Use memory barriers correctly in circular buffer logic Use memory barriers correctly in the circular buffer logic used in the driver, as documented in Documentation/circular-buffers.txt. Signed-off-by: David Howells Signed-off-by: Mark Salter --- arch/mn10300/kernel/mn10300-serial.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/arch/mn10300/kernel/mn10300-serial.c b/arch/mn10300/kernel/mn10300-serial.c index 339cef4c8256..131b81f9d6c8 100644 --- a/arch/mn10300/kernel/mn10300-serial.c +++ b/arch/mn10300/kernel/mn10300-serial.c @@ -487,16 +487,17 @@ static void mn10300_serial_receive_interrupt(struct mn10300_serial_port *port) try_again: /* pull chars out of the hat */ - ix = port->rx_outp; - if (ix == port->rx_inp) { + ix = ACCESS_ONCE(port->rx_outp); + if (CIRC_CNT(port->rx_inp, ix, MNSC_BUFFER_SIZE) == 0) { if (push && !tty->low_latency) tty_flip_buffer_push(tty); return; } + smp_read_barrier_depends(); ch = port->rx_buffer[ix++]; st = port->rx_buffer[ix++]; - smp_rmb(); + smp_mb(); port->rx_outp = ix & (MNSC_BUFFER_SIZE - 1); port->uart.icount.rx++; @@ -1657,13 +1658,14 @@ static int mn10300_serial_poll_get_char(struct uart_port *_port) do { /* pull chars out of the hat */ - ix = port->rx_outp; - if (ix == port->rx_inp) + ix = ACCESS_ONCE(port->rx_outp); + if (CIRC_CNT(port->rx_inp, ix, MNSC_BUFFER_SIZE) == 0) return NO_POLL_CHAR; + smp_read_barrier_depends(); ch = port->rx_buffer[ix++]; st = port->rx_buffer[ix++]; - smp_rmb(); + smp_mb(); port->rx_outp = ix & (MNSC_BUFFER_SIZE - 1); } while (st & (SC01STR_FEF | SC01STR_PEF | SC01STR_OEF));