aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/serial
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/serial')
-rw-r--r--drivers/serial/bfin_sport_uart.c30
1 files changed, 21 insertions, 9 deletions
diff --git a/drivers/serial/bfin_sport_uart.c b/drivers/serial/bfin_sport_uart.c
index b9938acb0309..0b459cf1b2eb 100644
--- a/drivers/serial/bfin_sport_uart.c
+++ b/drivers/serial/bfin_sport_uart.c
@@ -54,7 +54,7 @@ struct sport_uart_port {
54#endif 54#endif
55}; 55};
56 56
57static void sport_uart_tx_chars(struct sport_uart_port *up); 57static int sport_uart_tx_chars(struct sport_uart_port *up);
58static void sport_stop_tx(struct uart_port *port); 58static void sport_stop_tx(struct uart_port *port);
59 59
60static inline void tx_one_byte(struct sport_uart_port *up, unsigned int value) 60static inline void tx_one_byte(struct sport_uart_port *up, unsigned int value)
@@ -307,18 +307,24 @@ static int sport_startup(struct uart_port *port)
307 return ret; 307 return ret;
308} 308}
309 309
310static void sport_uart_tx_chars(struct sport_uart_port *up) 310/*
311 * sport_uart_tx_chars
312 *
313 * ret 1 means need to enable sport.
314 * ret 0 means do nothing.
315 */
316static int sport_uart_tx_chars(struct sport_uart_port *up)
311{ 317{
312 struct circ_buf *xmit = &up->port.state->xmit; 318 struct circ_buf *xmit = &up->port.state->xmit;
313 319
314 if (SPORT_GET_STAT(up) & TXF) 320 if (SPORT_GET_STAT(up) & TXF)
315 return; 321 return 0;
316 322
317 if (up->port.x_char) { 323 if (up->port.x_char) {
318 tx_one_byte(up, up->port.x_char); 324 tx_one_byte(up, up->port.x_char);
319 up->port.icount.tx++; 325 up->port.icount.tx++;
320 up->port.x_char = 0; 326 up->port.x_char = 0;
321 return; 327 return 1;
322 } 328 }
323 329
324 if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) { 330 if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) {
@@ -329,7 +335,7 @@ static void sport_uart_tx_chars(struct sport_uart_port *up)
329 */ 335 */
330 if (SPORT_GET_STAT(up) & TXHRE) 336 if (SPORT_GET_STAT(up) & TXHRE)
331 sport_stop_tx(&up->port); 337 sport_stop_tx(&up->port);
332 return; 338 return 0;
333 } 339 }
334 340
335 while(!(SPORT_GET_STAT(up) & TXF) && !uart_circ_empty(xmit)) { 341 while(!(SPORT_GET_STAT(up) & TXF) && !uart_circ_empty(xmit)) {
@@ -340,6 +346,8 @@ static void sport_uart_tx_chars(struct sport_uart_port *up)
340 346
341 if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) 347 if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
342 uart_write_wakeup(&up->port); 348 uart_write_wakeup(&up->port);
349
350 return 1;
343} 351}
344 352
345static unsigned int sport_tx_empty(struct uart_port *port) 353static unsigned int sport_tx_empty(struct uart_port *port)
@@ -361,6 +369,9 @@ static void sport_stop_tx(struct uart_port *port)
361 369
362 pr_debug("%s enter\n", __func__); 370 pr_debug("%s enter\n", __func__);
363 371
372 if (!(SPORT_GET_TCR1(up) & TSPEN))
373 return;
374
364 /* Although the hold register is empty, last byte is still in shift 375 /* Although the hold register is empty, last byte is still in shift
365 * register and not sent out yet. So, put a dummy data into TX FIFO. 376 * register and not sent out yet. So, put a dummy data into TX FIFO.
366 * Then, sport tx stops when last byte is shift out and the dummy 377 * Then, sport tx stops when last byte is shift out and the dummy
@@ -383,11 +394,12 @@ static void sport_start_tx(struct uart_port *port)
383 pr_debug("%s enter\n", __func__); 394 pr_debug("%s enter\n", __func__);
384 395
385 /* Write data into SPORT FIFO before enable SPROT to transmit */ 396 /* Write data into SPORT FIFO before enable SPROT to transmit */
386 sport_uart_tx_chars(up); 397 if (sport_uart_tx_chars(up)) {
398 /* Enable transmit, then an interrupt will generated */
399 SPORT_PUT_TCR1(up, (SPORT_GET_TCR1(up) | TSPEN));
400 SSYNC();
401 }
387 402
388 /* Enable transmit, then an interrupt will generated */
389 SPORT_PUT_TCR1(up, (SPORT_GET_TCR1(up) | TSPEN));
390 SSYNC();
391 pr_debug("%s exit\n", __func__); 403 pr_debug("%s exit\n", __func__);
392} 404}
393 405