diff options
author | David Howells <dhowells@redhat.com> | 2012-12-12 10:36:37 -0500 |
---|---|---|
committer | David Howells <dhowells@redhat.com> | 2012-12-12 10:46:14 -0500 |
commit | c98c406eb2c518c7c5bc922fafa1f9fdcb7b76f4 (patch) | |
tree | a7b5199a61df167bdcc34eb36af97d73bb6b3d0d /arch/mn10300/kernel | |
parent | 541880d9a2c7871f6370071d55aa6662d329c51e (diff) |
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 <dhowells@redhat.com>
Signed-off-by: Mark Salter <msalter@redhat.com>
Diffstat (limited to 'arch/mn10300/kernel')
-rw-r--r-- | arch/mn10300/kernel/mn10300-serial.c | 14 |
1 files 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) | |||
487 | 487 | ||
488 | try_again: | 488 | try_again: |
489 | /* pull chars out of the hat */ | 489 | /* pull chars out of the hat */ |
490 | ix = port->rx_outp; | 490 | ix = ACCESS_ONCE(port->rx_outp); |
491 | if (ix == port->rx_inp) { | 491 | if (CIRC_CNT(port->rx_inp, ix, MNSC_BUFFER_SIZE) == 0) { |
492 | if (push && !tty->low_latency) | 492 | if (push && !tty->low_latency) |
493 | tty_flip_buffer_push(tty); | 493 | tty_flip_buffer_push(tty); |
494 | return; | 494 | return; |
495 | } | 495 | } |
496 | 496 | ||
497 | smp_read_barrier_depends(); | ||
497 | ch = port->rx_buffer[ix++]; | 498 | ch = port->rx_buffer[ix++]; |
498 | st = port->rx_buffer[ix++]; | 499 | st = port->rx_buffer[ix++]; |
499 | smp_rmb(); | 500 | smp_mb(); |
500 | port->rx_outp = ix & (MNSC_BUFFER_SIZE - 1); | 501 | port->rx_outp = ix & (MNSC_BUFFER_SIZE - 1); |
501 | port->uart.icount.rx++; | 502 | port->uart.icount.rx++; |
502 | 503 | ||
@@ -1657,13 +1658,14 @@ static int mn10300_serial_poll_get_char(struct uart_port *_port) | |||
1657 | 1658 | ||
1658 | do { | 1659 | do { |
1659 | /* pull chars out of the hat */ | 1660 | /* pull chars out of the hat */ |
1660 | ix = port->rx_outp; | 1661 | ix = ACCESS_ONCE(port->rx_outp); |
1661 | if (ix == port->rx_inp) | 1662 | if (CIRC_CNT(port->rx_inp, ix, MNSC_BUFFER_SIZE) == 0) |
1662 | return NO_POLL_CHAR; | 1663 | return NO_POLL_CHAR; |
1663 | 1664 | ||
1665 | smp_read_barrier_depends(); | ||
1664 | ch = port->rx_buffer[ix++]; | 1666 | ch = port->rx_buffer[ix++]; |
1665 | st = port->rx_buffer[ix++]; | 1667 | st = port->rx_buffer[ix++]; |
1666 | smp_rmb(); | 1668 | smp_mb(); |
1667 | port->rx_outp = ix & (MNSC_BUFFER_SIZE - 1); | 1669 | port->rx_outp = ix & (MNSC_BUFFER_SIZE - 1); |
1668 | 1670 | ||
1669 | } while (st & (SC01STR_FEF | SC01STR_PEF | SC01STR_OEF)); | 1671 | } while (st & (SC01STR_FEF | SC01STR_PEF | SC01STR_OEF)); |