diff options
author | Sonic Zhang <sonic.zhang@analog.com> | 2010-03-09 12:25:37 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-05-21 12:34:28 -0400 |
commit | 9356c46170e0551f72467c9b0fb9a856a36aa2de (patch) | |
tree | 189b4dcf17222ab526c03e4631e7c92ae7d8402e /drivers/serial/bfin_sport_uart.c | |
parent | 60bd940f142741092b95a2e572f81741dc867545 (diff) |
serial: bfin_sport_uart: only enable SPORT TX if data is to be sent
Rather than always turn on the SPORT TX interrupt, only do it when we've
actually queued up data for transmission. This avoids useless interrupt
processing.
Signed-off-by: Sonic Zhang <sonic.zhang@analog.com>
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/serial/bfin_sport_uart.c')
-rw-r--r-- | drivers/serial/bfin_sport_uart.c | 30 |
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 | ||
57 | static void sport_uart_tx_chars(struct sport_uart_port *up); | 57 | static int sport_uart_tx_chars(struct sport_uart_port *up); |
58 | static void sport_stop_tx(struct uart_port *port); | 58 | static void sport_stop_tx(struct uart_port *port); |
59 | 59 | ||
60 | static inline void tx_one_byte(struct sport_uart_port *up, unsigned int value) | 60 | static 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 | ||
310 | static 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 | */ | ||
316 | static 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 | ||
345 | static unsigned int sport_tx_empty(struct uart_port *port) | 353 | static 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 | ||