diff options
author | Heikki Krogerus <heikki.krogerus@linux.intel.com> | 2013-01-10 13:25:11 +0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-01-16 11:03:00 +0400 |
commit | 9ee4b83e51f741a645c43e61b9f3f8075ca0fdf4 (patch) | |
tree | 93d759187615cb57aa42825a2303dc4f4b0f430c /drivers/tty/serial/8250/8250.c | |
parent | 6a7320c4669fbf26a8e71a4c8af4101923152375 (diff) | |
download | linux-9ee4b83e51f741a645c43e61b9f3f8075ca0fdf4.tar.xz |
serial: 8250: Add support for dmaengine
Add support for dmaengine API. The drivers can implement the
struct uart_8250_dma member in struct uart_8250_port and
8250.c can take care of the rest.
Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty/serial/8250/8250.c')
-rw-r--r-- | drivers/tty/serial/8250/8250.c | 31 |
1 files changed, 28 insertions, 3 deletions
diff --git a/drivers/tty/serial/8250/8250.c b/drivers/tty/serial/8250/8250.c index e2ac25a037ef..cb7db5a8ae92 100644 --- a/drivers/tty/serial/8250/8250.c +++ b/drivers/tty/serial/8250/8250.c @@ -1269,7 +1269,9 @@ static void serial8250_start_tx(struct uart_port *port) struct uart_8250_port *up = container_of(port, struct uart_8250_port, port); - if (!(up->ier & UART_IER_THRI)) { + if (up->dma && !serial8250_tx_dma(up)) { + return; + } else if (!(up->ier & UART_IER_THRI)) { up->ier |= UART_IER_THRI; serial_port_out(port, UART_IER, up->ier); @@ -1467,6 +1469,7 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir) unsigned long flags; struct uart_8250_port *up = container_of(port, struct uart_8250_port, port); + int dma_err = 0; if (iir & UART_IIR_NO_INT) return 0; @@ -1477,8 +1480,13 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir) DEBUG_INTR("status = %x...", status); - if (status & (UART_LSR_DR | UART_LSR_BI)) - status = serial8250_rx_chars(up, status); + if (status & (UART_LSR_DR | UART_LSR_BI)) { + if (up->dma) + dma_err = serial8250_rx_dma(up, iir); + + if (!up->dma || dma_err) + status = serial8250_rx_chars(up, status); + } serial8250_modem_status(up); if (status & UART_LSR_THRE) serial8250_tx_chars(up); @@ -2121,6 +2129,18 @@ dont_test_tx_en: up->msr_saved_flags = 0; /* + * Request DMA channels for both RX and TX. + */ + if (up->dma) { + retval = serial8250_request_dma(up); + if (retval) { + pr_warn_ratelimited("ttyS%d - failed to request DMA\n", + serial_index(port)); + up->dma = NULL; + } + } + + /* * Finally, enable interrupts. Note: Modem status interrupts * are set via set_termios(), which will be occurring imminently * anyway, so we don't enable them here. @@ -2153,6 +2173,9 @@ static void serial8250_shutdown(struct uart_port *port) up->ier = 0; serial_port_out(port, UART_IER, 0); + if (up->dma) + serial8250_release_dma(up); + spin_lock_irqsave(&port->lock, flags); if (port->flags & UPF_FOURPORT) { /* reset interrupts on the AST Fourport board */ @@ -3217,6 +3240,8 @@ int serial8250_register_8250_port(struct uart_8250_port *up) uart->dl_read = up->dl_read; if (up->dl_write) uart->dl_write = up->dl_write; + if (up->dma) + uart->dma = up->dma; if (serial8250_isa_config != NULL) serial8250_isa_config(0, &uart->port, |