aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/serial/msm_serial.c
diff options
context:
space:
mode:
authorStephen Boyd <sboyd@codeaurora.org>2013-07-24 14:37:31 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-07-26 19:13:30 -0400
commit17fae28efe8f460918e13aedd7163690206c682d (patch)
treee18a47918d559d3c15d8a4da1ec6015e24929622 /drivers/tty/serial/msm_serial.c
parent6909dadd914259f459828b11c378ddea08d40ab6 (diff)
msm_serial: Send more than 1 character at a time on UARTDM
UARTDM cores have a TX fifo that can accept more than one character per register write, but the msm_serial driver currently only supports 1 character mode. Add support for this mode of operation to speed up the transmit path on DM devices. Signed-off-by: Stephen Boyd <sboyd@codeaurora.org> Acked-by: David Brown <davidb@codeaurora.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty/serial/msm_serial.c')
-rw-r--r--drivers/tty/serial/msm_serial.c51
1 files changed, 32 insertions, 19 deletions
diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c
index ca2ae6581149..252d514b47fb 100644
--- a/drivers/tty/serial/msm_serial.c
+++ b/drivers/tty/serial/msm_serial.c
@@ -195,10 +195,10 @@ static void handle_rx(struct uart_port *port)
195 tty_flip_buffer_push(tport); 195 tty_flip_buffer_push(tport);
196} 196}
197 197
198static void reset_dm_count(struct uart_port *port) 198static void reset_dm_count(struct uart_port *port, int count)
199{ 199{
200 wait_for_xmitr(port); 200 wait_for_xmitr(port);
201 msm_write(port, 1, UARTDM_NCF_TX); 201 msm_write(port, count, UARTDM_NCF_TX);
202 msm_read(port, UARTDM_NCF_TX); 202 msm_read(port, UARTDM_NCF_TX);
203} 203}
204 204
@@ -206,39 +206,52 @@ static void handle_tx(struct uart_port *port)
206{ 206{
207 struct circ_buf *xmit = &port->state->xmit; 207 struct circ_buf *xmit = &port->state->xmit;
208 struct msm_port *msm_port = UART_TO_MSM(port); 208 struct msm_port *msm_port = UART_TO_MSM(port);
209 int sent_tx; 209 unsigned int tx_count, num_chars;
210 unsigned int tf_pointer = 0;
211
212 tx_count = uart_circ_chars_pending(xmit);
213 tx_count = min3(tx_count, (unsigned int)UART_XMIT_SIZE - xmit->tail,
214 port->fifosize);
210 215
211 if (port->x_char) { 216 if (port->x_char) {
212 if (msm_port->is_uartdm) 217 if (msm_port->is_uartdm)
213 reset_dm_count(port); 218 reset_dm_count(port, tx_count + 1);
214 219
215 msm_write(port, port->x_char, 220 msm_write(port, port->x_char,
216 msm_port->is_uartdm ? UARTDM_TF : UART_TF); 221 msm_port->is_uartdm ? UARTDM_TF : UART_TF);
217 port->icount.tx++; 222 port->icount.tx++;
218 port->x_char = 0; 223 port->x_char = 0;
224 } else if (tx_count && msm_port->is_uartdm) {
225 reset_dm_count(port, tx_count);
219 } 226 }
220 227
221 if (msm_port->is_uartdm) 228 while (tf_pointer < tx_count) {
222 reset_dm_count(port); 229 int i;
230 char buf[4] = { 0 };
231 unsigned int *bf = (unsigned int *)&buf;
223 232
224 while (msm_read(port, UART_SR) & UART_SR_TX_READY) { 233 if (!(msm_read(port, UART_SR) & UART_SR_TX_READY))
225 if (uart_circ_empty(xmit)) {
226 /* disable tx interrupts */
227 msm_port->imr &= ~UART_IMR_TXLEV;
228 msm_write(port, msm_port->imr, UART_IMR);
229 break; 234 break;
230 }
231 msm_write(port, xmit->buf[xmit->tail],
232 msm_port->is_uartdm ? UARTDM_TF : UART_TF);
233 235
234 if (msm_port->is_uartdm) 236 if (msm_port->is_uartdm)
235 reset_dm_count(port); 237 num_chars = min(tx_count - tf_pointer, sizeof(buf));
238 else
239 num_chars = 1;
236 240
237 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); 241 for (i = 0; i < num_chars; i++) {
238 port->icount.tx++; 242 buf[i] = xmit->buf[xmit->tail + i];
239 sent_tx = 1; 243 port->icount.tx++;
244 }
245
246 msm_write(port, *bf, msm_port->is_uartdm ? UARTDM_TF : UART_TF);
247 xmit->tail = (xmit->tail + num_chars) & (UART_XMIT_SIZE - 1);
248 tf_pointer += num_chars;
240 } 249 }
241 250
251 /* disable tx interrupts if nothing more to send */
252 if (uart_circ_empty(xmit))
253 msm_stop_tx(port);
254
242 if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) 255 if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
243 uart_write_wakeup(port); 256 uart_write_wakeup(port);
244} 257}
@@ -759,7 +772,7 @@ static void msm_console_putchar(struct uart_port *port, int c)
759 struct msm_port *msm_port = UART_TO_MSM(port); 772 struct msm_port *msm_port = UART_TO_MSM(port);
760 773
761 if (msm_port->is_uartdm) 774 if (msm_port->is_uartdm)
762 reset_dm_count(port); 775 reset_dm_count(port, 1);
763 776
764 while (!(msm_read(port, UART_SR) & UART_SR_TX_READY)) 777 while (!(msm_read(port, UART_SR) & UART_SR_TX_READY))
765 ; 778 ;