diff options
author | Stephen Boyd <sboyd@codeaurora.org> | 2014-06-30 17:54:01 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-07-10 19:10:42 -0400 |
commit | 68252424a7c757ce0a534696e22e1770408bc01d (patch) | |
tree | 9258881ca0da38a901e21f432a6e4f1685428c56 | |
parent | db3a1a43fbb3c0e2f993ce5e7305641075eeb1d6 (diff) |
tty: serial: msm: Support big-endian CPUs
To support big-endian CPUs use the string versions of the io
read/write macros on the TX/RX fifos and the non-raw variants of
the readl/writel macros throughout. This way we don't byteswap
the characters coming from the fifos but we properly deal with
the little-endian nature of the serial hardware while controlling
it.
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/tty/serial/msm_serial.c | 28 | ||||
-rw-r--r-- | drivers/tty/serial/msm_serial.h | 4 |
2 files changed, 20 insertions, 12 deletions
diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c index 90feee190f2a..c549110509bb 100644 --- a/drivers/tty/serial/msm_serial.c +++ b/drivers/tty/serial/msm_serial.c | |||
@@ -125,14 +125,14 @@ static void handle_rx_dm(struct uart_port *port, unsigned int misr) | |||
125 | port->icount.rx += count; | 125 | port->icount.rx += count; |
126 | 126 | ||
127 | while (count > 0) { | 127 | while (count > 0) { |
128 | unsigned int c; | 128 | unsigned char buf[4]; |
129 | 129 | ||
130 | sr = msm_read(port, UART_SR); | 130 | sr = msm_read(port, UART_SR); |
131 | if ((sr & UART_SR_RX_READY) == 0) { | 131 | if ((sr & UART_SR_RX_READY) == 0) { |
132 | msm_port->old_snap_state -= count; | 132 | msm_port->old_snap_state -= count; |
133 | break; | 133 | break; |
134 | } | 134 | } |
135 | c = msm_read(port, UARTDM_RF); | 135 | ioread32_rep(port->membase + UARTDM_RF, buf, 1); |
136 | if (sr & UART_SR_RX_BREAK) { | 136 | if (sr & UART_SR_RX_BREAK) { |
137 | port->icount.brk++; | 137 | port->icount.brk++; |
138 | if (uart_handle_break(port)) | 138 | if (uart_handle_break(port)) |
@@ -141,8 +141,7 @@ static void handle_rx_dm(struct uart_port *port, unsigned int misr) | |||
141 | port->icount.frame++; | 141 | port->icount.frame++; |
142 | 142 | ||
143 | /* TODO: handle sysrq */ | 143 | /* TODO: handle sysrq */ |
144 | tty_insert_flip_string(tport, (char *)&c, | 144 | tty_insert_flip_string(tport, buf, min(count, 4)); |
145 | (count > 4) ? 4 : count); | ||
146 | count -= 4; | 145 | count -= 4; |
147 | } | 146 | } |
148 | 147 | ||
@@ -219,6 +218,12 @@ static void handle_tx(struct uart_port *port) | |||
219 | struct msm_port *msm_port = UART_TO_MSM(port); | 218 | struct msm_port *msm_port = UART_TO_MSM(port); |
220 | unsigned int tx_count, num_chars; | 219 | unsigned int tx_count, num_chars; |
221 | unsigned int tf_pointer = 0; | 220 | unsigned int tf_pointer = 0; |
221 | void __iomem *tf; | ||
222 | |||
223 | if (msm_port->is_uartdm) | ||
224 | tf = port->membase + UARTDM_TF; | ||
225 | else | ||
226 | tf = port->membase + UART_TF; | ||
222 | 227 | ||
223 | tx_count = uart_circ_chars_pending(xmit); | 228 | tx_count = uart_circ_chars_pending(xmit); |
224 | tx_count = min3(tx_count, (unsigned int)UART_XMIT_SIZE - xmit->tail, | 229 | tx_count = min3(tx_count, (unsigned int)UART_XMIT_SIZE - xmit->tail, |
@@ -228,8 +233,7 @@ static void handle_tx(struct uart_port *port) | |||
228 | if (msm_port->is_uartdm) | 233 | if (msm_port->is_uartdm) |
229 | reset_dm_count(port, tx_count + 1); | 234 | reset_dm_count(port, tx_count + 1); |
230 | 235 | ||
231 | msm_write(port, port->x_char, | 236 | iowrite8_rep(tf, &port->x_char, 1); |
232 | msm_port->is_uartdm ? UARTDM_TF : UART_TF); | ||
233 | port->icount.tx++; | 237 | port->icount.tx++; |
234 | port->x_char = 0; | 238 | port->x_char = 0; |
235 | } else if (tx_count && msm_port->is_uartdm) { | 239 | } else if (tx_count && msm_port->is_uartdm) { |
@@ -239,7 +243,6 @@ static void handle_tx(struct uart_port *port) | |||
239 | while (tf_pointer < tx_count) { | 243 | while (tf_pointer < tx_count) { |
240 | int i; | 244 | int i; |
241 | char buf[4] = { 0 }; | 245 | char buf[4] = { 0 }; |
242 | unsigned int *bf = (unsigned int *)&buf; | ||
243 | 246 | ||
244 | if (!(msm_read(port, UART_SR) & UART_SR_TX_READY)) | 247 | if (!(msm_read(port, UART_SR) & UART_SR_TX_READY)) |
245 | break; | 248 | break; |
@@ -255,7 +258,7 @@ static void handle_tx(struct uart_port *port) | |||
255 | port->icount.tx++; | 258 | port->icount.tx++; |
256 | } | 259 | } |
257 | 260 | ||
258 | msm_write(port, *bf, msm_port->is_uartdm ? UARTDM_TF : UART_TF); | 261 | iowrite32_rep(tf, buf, 1); |
259 | xmit->tail = (xmit->tail + num_chars) & (UART_XMIT_SIZE - 1); | 262 | xmit->tail = (xmit->tail + num_chars) & (UART_XMIT_SIZE - 1); |
260 | tf_pointer += num_chars; | 263 | tf_pointer += num_chars; |
261 | } | 264 | } |
@@ -861,12 +864,18 @@ static void msm_console_write(struct console *co, const char *s, | |||
861 | struct msm_port *msm_port; | 864 | struct msm_port *msm_port; |
862 | int num_newlines = 0; | 865 | int num_newlines = 0; |
863 | bool replaced = false; | 866 | bool replaced = false; |
867 | void __iomem *tf; | ||
864 | 868 | ||
865 | BUG_ON(co->index < 0 || co->index >= UART_NR); | 869 | BUG_ON(co->index < 0 || co->index >= UART_NR); |
866 | 870 | ||
867 | port = get_port_from_line(co->index); | 871 | port = get_port_from_line(co->index); |
868 | msm_port = UART_TO_MSM(port); | 872 | msm_port = UART_TO_MSM(port); |
869 | 873 | ||
874 | if (msm_port->is_uartdm) | ||
875 | tf = port->membase + UARTDM_TF; | ||
876 | else | ||
877 | tf = port->membase + UART_TF; | ||
878 | |||
870 | /* Account for newlines that will get a carriage return added */ | 879 | /* Account for newlines that will get a carriage return added */ |
871 | for (i = 0; i < count; i++) | 880 | for (i = 0; i < count; i++) |
872 | if (s[i] == '\n') | 881 | if (s[i] == '\n') |
@@ -882,7 +891,6 @@ static void msm_console_write(struct console *co, const char *s, | |||
882 | int j; | 891 | int j; |
883 | unsigned int num_chars; | 892 | unsigned int num_chars; |
884 | char buf[4] = { 0 }; | 893 | char buf[4] = { 0 }; |
885 | unsigned int *bf = (unsigned int *)&buf; | ||
886 | 894 | ||
887 | if (msm_port->is_uartdm) | 895 | if (msm_port->is_uartdm) |
888 | num_chars = min(count - i, (unsigned int)sizeof(buf)); | 896 | num_chars = min(count - i, (unsigned int)sizeof(buf)); |
@@ -907,7 +915,7 @@ static void msm_console_write(struct console *co, const char *s, | |||
907 | while (!(msm_read(port, UART_SR) & UART_SR_TX_READY)) | 915 | while (!(msm_read(port, UART_SR) & UART_SR_TX_READY)) |
908 | cpu_relax(); | 916 | cpu_relax(); |
909 | 917 | ||
910 | msm_write(port, *bf, msm_port->is_uartdm ? UARTDM_TF : UART_TF); | 918 | iowrite32_rep(tf, buf, 1); |
911 | i += num_chars; | 919 | i += num_chars; |
912 | } | 920 | } |
913 | spin_unlock(&port->lock); | 921 | spin_unlock(&port->lock); |
diff --git a/drivers/tty/serial/msm_serial.h b/drivers/tty/serial/msm_serial.h index d98d45efdf86..73d3abe71e79 100644 --- a/drivers/tty/serial/msm_serial.h +++ b/drivers/tty/serial/msm_serial.h | |||
@@ -126,13 +126,13 @@ | |||
126 | static inline | 126 | static inline |
127 | void msm_write(struct uart_port *port, unsigned int val, unsigned int off) | 127 | void msm_write(struct uart_port *port, unsigned int val, unsigned int off) |
128 | { | 128 | { |
129 | __raw_writel(val, port->membase + off); | 129 | writel_relaxed(val, port->membase + off); |
130 | } | 130 | } |
131 | 131 | ||
132 | static inline | 132 | static inline |
133 | unsigned int msm_read(struct uart_port *port, unsigned int off) | 133 | unsigned int msm_read(struct uart_port *port, unsigned int off) |
134 | { | 134 | { |
135 | return __raw_readl(port->membase + off); | 135 | return readl_relaxed(port->membase + off); |
136 | } | 136 | } |
137 | 137 | ||
138 | /* | 138 | /* |