diff options
author | Stephen Boyd <sboyd@codeaurora.org> | 2011-10-25 22:19:43 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-11-15 15:02:13 -0500 |
commit | c2a3e84f950e7ddba1f3914b005861d46ae60359 (patch) | |
tree | 66582813076b24419d628ab083c8f15c0cc7de37 /drivers/tty/hvc | |
parent | 52b3bfc69efc44447ed2db25dd999aef64b3c970 (diff) |
tty: hvc_dcc: Fix duplicate character inputs
Reading from the DCC grabs a character from the buffer and
clears the status bit. Since this is a context-changing
operation, instructions following the character read that rely on
the status bit being accurate need to be synchronized with an
ISB.
In this case, the status bit check needs to execute after the
character read otherwise we run the risk of reading the character
and checking the status bit before the read can clear the status
bit in the first place. When this happens, the user will see the
same character they typed twice, instead of once.
Add an ISB after the read and the write, so that the status check
is synchronized with the read/write operations.
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/tty/hvc')
-rw-r--r-- | drivers/tty/hvc/hvc_dcc.c | 2 |
1 files changed, 2 insertions, 0 deletions
diff --git a/drivers/tty/hvc/hvc_dcc.c b/drivers/tty/hvc/hvc_dcc.c index 435f6facbc23..44fbebab5075 100644 --- a/drivers/tty/hvc/hvc_dcc.c +++ b/drivers/tty/hvc/hvc_dcc.c | |||
@@ -46,6 +46,7 @@ static inline char __dcc_getchar(void) | |||
46 | 46 | ||
47 | asm volatile("mrc p14, 0, %0, c0, c5, 0 @ read comms data reg" | 47 | asm volatile("mrc p14, 0, %0, c0, c5, 0 @ read comms data reg" |
48 | : "=r" (__c)); | 48 | : "=r" (__c)); |
49 | isb(); | ||
49 | 50 | ||
50 | return __c; | 51 | return __c; |
51 | } | 52 | } |
@@ -55,6 +56,7 @@ static inline void __dcc_putchar(char c) | |||
55 | asm volatile("mcr p14, 0, %0, c0, c5, 0 @ write a char" | 56 | asm volatile("mcr p14, 0, %0, c0, c5, 0 @ write a char" |
56 | : /* no output register */ | 57 | : /* no output register */ |
57 | : "r" (c)); | 58 | : "r" (c)); |
59 | isb(); | ||
58 | } | 60 | } |
59 | 61 | ||
60 | static int hvc_dcc_put_chars(uint32_t vt, const char *buf, int count) | 62 | static int hvc_dcc_put_chars(uint32_t vt, const char *buf, int count) |