diff options
Diffstat (limited to 'drivers/tty/serial/bfin_uart.c')
-rw-r--r-- | drivers/tty/serial/bfin_uart.c | 83 |
1 files changed, 37 insertions, 46 deletions
diff --git a/drivers/tty/serial/bfin_uart.c b/drivers/tty/serial/bfin_uart.c index 66afb98b77b..26953bfa692 100644 --- a/drivers/tty/serial/bfin_uart.c +++ b/drivers/tty/serial/bfin_uart.c @@ -116,15 +116,22 @@ static void bfin_serial_set_mctrl(struct uart_port *port, unsigned int mctrl) static irqreturn_t bfin_serial_mctrl_cts_int(int irq, void *dev_id) { struct bfin_serial_port *uart = dev_id; - unsigned int status; - - status = bfin_serial_get_mctrl(&uart->port); - uart_handle_cts_change(&uart->port, status & TIOCM_CTS); + unsigned int status = bfin_serial_get_mctrl(&uart->port); #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS - uart->scts = 1; + struct tty_struct *tty = uart->port.state->port.tty; + UART_CLEAR_SCTS(uart); - UART_CLEAR_IER(uart, EDSSI); + if (tty->hw_stopped) { + if (status) { + tty->hw_stopped = 0; + uart_write_wakeup(&uart->port); + } + } else { + if (!status) + tty->hw_stopped = 1; + } #endif + uart_handle_cts_change(&uart->port, status & TIOCM_CTS); return IRQ_HANDLED; } @@ -175,13 +182,6 @@ static void bfin_serial_start_tx(struct uart_port *port) struct bfin_serial_port *uart = (struct bfin_serial_port *)port; struct tty_struct *tty = uart->port.state->port.tty; -#ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS - if (uart->scts && !(bfin_serial_get_mctrl(&uart->port) & TIOCM_CTS)) { - uart->scts = 0; - uart_handle_cts_change(&uart->port, uart->scts); - } -#endif - /* * To avoid losting RX interrupt, we reset IR function * before sending data. @@ -380,12 +380,6 @@ static irqreturn_t bfin_serial_tx_int(int irq, void *dev_id) { struct bfin_serial_port *uart = dev_id; -#ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS - if (uart->scts && !(bfin_serial_get_mctrl(&uart->port) & TIOCM_CTS)) { - uart->scts = 0; - uart_handle_cts_change(&uart->port, uart->scts); - } -#endif spin_lock(&uart->port.lock); if (UART_GET_LSR(uart) & THRE) bfin_serial_tx_chars(uart); @@ -531,13 +525,6 @@ static irqreturn_t bfin_serial_dma_tx_int(int irq, void *dev_id) struct bfin_serial_port *uart = dev_id; struct circ_buf *xmit = &uart->port.state->xmit; -#ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS - if (uart->scts && !(bfin_serial_get_mctrl(&uart->port)&TIOCM_CTS)) { - uart->scts = 0; - uart_handle_cts_change(&uart->port, uart->scts); - } -#endif - spin_lock(&uart->port.lock); if (!(get_dma_curr_irqstat(uart->tx_dma_channel)&DMA_RUN)) { disable_dma(uart->tx_dma_channel); @@ -739,20 +726,26 @@ static int bfin_serial_startup(struct uart_port *port) pr_info("Unable to attach BlackFin UART CTS interrupt. So, disable it.\n"); } } - if (uart->rts_pin >= 0) - gpio_direction_output(uart->rts_pin, 0); + if (uart->rts_pin >= 0) { + if (gpio_request(uart->rts_pin, DRIVER_NAME)) { + pr_info("fail to request RTS PIN at GPIO_%d\n", uart->rts_pin); + uart->rts_pin = -1; + } else + gpio_direction_output(uart->rts_pin, 0); + } #endif #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS - if (uart->cts_pin >= 0 && request_irq(uart->status_irq, - bfin_serial_mctrl_cts_int, - 0, "BFIN_UART_MODEM_STATUS", uart)) { - uart->cts_pin = -1; - pr_info("Unable to attach BlackFin UART Modem Status interrupt.\n"); - } + if (uart->cts_pin >= 0) { + if (request_irq(uart->status_irq, bfin_serial_mctrl_cts_int, + IRQF_DISABLED, "BFIN_UART_MODEM_STATUS", uart)) { + uart->cts_pin = -1; + dev_info(port->dev, "Unable to attach BlackFin UART Modem Status interrupt.\n"); + } - /* CTS RTS PINs are negative assertive. */ - UART_PUT_MCR(uart, ACTS); - UART_SET_IER(uart, EDSSI); + /* CTS RTS PINs are negative assertive. */ + UART_PUT_MCR(uart, ACTS); + UART_SET_IER(uart, EDSSI); + } #endif UART_SET_IER(uart, ERBFI); @@ -792,6 +785,8 @@ static void bfin_serial_shutdown(struct uart_port *port) #ifdef CONFIG_SERIAL_BFIN_CTSRTS if (uart->cts_pin >= 0) free_irq(gpio_to_irq(uart->cts_pin), uart); + if (uart->rts_pin >= 0) + gpio_free(uart->rts_pin); #endif #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS if (uart->cts_pin >= 0) @@ -1370,18 +1365,18 @@ static int bfin_serial_probe(struct platform_device *pdev) res = platform_get_resource(pdev, IORESOURCE_IO, 0); if (res == NULL) uart->cts_pin = -1; - else + else { uart->cts_pin = res->start; +#ifdef CONFIG_SERIAL_BFIN_CTSRTS + uart->port.flags |= ASYNC_CTS_FLOW; +#endif + } res = platform_get_resource(pdev, IORESOURCE_IO, 1); if (res == NULL) uart->rts_pin = -1; else uart->rts_pin = res->start; -# if defined(CONFIG_SERIAL_BFIN_CTSRTS) - if (uart->rts_pin >= 0) - gpio_request(uart->rts_pin, DRIVER_NAME); -# endif #endif } @@ -1421,10 +1416,6 @@ static int __devexit bfin_serial_remove(struct platform_device *pdev) if (uart) { uart_remove_one_port(&bfin_serial_reg, &uart->port); -#ifdef CONFIG_SERIAL_BFIN_CTSRTS - if (uart->rts_pin >= 0) - gpio_free(uart->rts_pin); -#endif iounmap(uart->port.membase); peripheral_free_list( (unsigned short *)pdev->dev.platform_data); |