From 59e4e3e65d3f856cfcdc66de2db5530d7b161f68 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Mon, 6 Apr 2009 17:32:28 +0100 Subject: blackfin: Use unsigned long for flags with irq functions Signed-off-by: Mike Frysinger Signed-off-by: Bryan Wu Signed-off-by: Alan Cox Signed-off-by: Linus Torvalds --- drivers/serial/bfin_5xx.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/serial/bfin_5xx.c') diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c index 318d69dce8e1..45c32b23d736 100644 --- a/drivers/serial/bfin_5xx.c +++ b/drivers/serial/bfin_5xx.c @@ -415,7 +415,8 @@ static void bfin_serial_dma_rx_chars(struct bfin_serial_port *uart) void bfin_serial_rx_dma_timeout(struct bfin_serial_port *uart) { - int x_pos, pos, flags; + int x_pos, pos; + unsigned long flags; spin_lock_irqsave(&uart->port.lock, flags); @@ -1088,7 +1089,7 @@ static void bfin_serial_console_write(struct console *co, const char *s, unsigned int count) { struct bfin_serial_port *uart = &bfin_serial_ports[co->index]; - int flags = 0; + unsigned long flags; spin_lock_irqsave(&uart->port.lock, flags); uart_console_write(&uart->port, s, count, bfin_serial_console_putchar); -- cgit v1.2.3-59-g8ed1b From df04baf1e6a62ff232fa224504ccaa987b5be230 Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Mon, 6 Apr 2009 17:32:35 +0100 Subject: blackfin: Fix tty compile error in PIO mode Fixes this compile issue: drivers/serial/bfin_5xx.c: In function bfin_serial_rx_chars: drivers/serial/bfin_5xx.c:178: error: struct uart_info has no member named tty Signed-off-by: Sonic Zhang Signed-off-by: Bryan Wu Signed-off-by: Alan Cox Signed-off-by: Linus Torvalds --- drivers/serial/bfin_5xx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/serial/bfin_5xx.c') diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c index 45c32b23d736..d7b271656a2d 100644 --- a/drivers/serial/bfin_5xx.c +++ b/drivers/serial/bfin_5xx.c @@ -174,10 +174,10 @@ static void bfin_serial_rx_chars(struct bfin_serial_port *uart) return; } - if (!uart->port.info || !uart->port.info->tty) + if (!uart->port.info || !uart->port.info->port.tty) return; #endif - tty = uart->port.info->tty; + tty = uart->port.info->port.tty; if (ANOMALY_05000363) { /* The BF533 (and BF561) family of processors have a nice anomaly -- cgit v1.2.3-59-g8ed1b From 8c4210e3362e1cd44bd10c857dc5f69c0bf434da Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Mon, 6 Apr 2009 17:32:42 +0100 Subject: Fix DMA rx ring buffer handling Reported-by: Qian Zhang Signed-off-by: Sonic Zhang Signed-off-by: Bryan Wu Signed-off-by: Alan Cox Signed-off-by: Linus Torvalds --- drivers/serial/bfin_5xx.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/serial/bfin_5xx.c') diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c index d7b271656a2d..12b11da40b49 100644 --- a/drivers/serial/bfin_5xx.c +++ b/drivers/serial/bfin_5xx.c @@ -401,9 +401,11 @@ static void bfin_serial_dma_rx_chars(struct bfin_serial_port *uart) else flg = TTY_NORMAL; - for (i = uart->rx_dma_buf.tail; i != uart->rx_dma_buf.head; i++) { + for (i = uart->rx_dma_buf.tail; ; i++) { if (i >= UART_XMIT_SIZE) i = 0; + if (i == uart->rx_dma_buf.head) + break; if (!uart_handle_sysrq_char(&uart->port, uart->rx_dma_buf.buf[i])) uart_insert_char(&uart->port, status, OE, uart->rx_dma_buf.buf[i], flg); -- cgit v1.2.3-59-g8ed1b From f4487101c7c5e529777b297eda5a5b69347f51a0 Mon Sep 17 00:00:00 2001 From: Graf Yang Date: Mon, 6 Apr 2009 17:32:49 +0100 Subject: blackfin: Subtract ANOMALY_05000230 on quot Fix bug - up arrow key works abnormal for bf561 ezkit board Signed-off-by: Graf Yang Signed-off-by: Bryan Wu Signed-off-by: Alan Cox Signed-off-by: Linus Torvalds --- drivers/serial/bfin_5xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/serial/bfin_5xx.c') diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c index 12b11da40b49..f9b5a72e261a 100644 --- a/drivers/serial/bfin_5xx.c +++ b/drivers/serial/bfin_5xx.c @@ -760,7 +760,7 @@ bfin_serial_set_termios(struct uart_port *port, struct ktermios *termios, } baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); - quot = uart_get_divisor(port, baud); + quot = uart_get_divisor(port, baud) - ANOMALY_05000230; spin_lock_irqsave(&uart->port.lock, flags); UART_SET_ANOMALY_THRESHOLD(uart, USEC_PER_SEC / baud * 15); -- cgit v1.2.3-59-g8ed1b From 6f95570e407d03c5140a220e054f9b18abdc7041 Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Tue, 7 Apr 2009 16:51:15 +0100 Subject: Change hardware flow control from poll to interrupt driven Only the CTS bit is affected. Signed-off-by: Sonic Zhang Signed-off-by: Bryan Wu Signed-off-by: Andrew Morton Signed-off-by: Alan Cox Signed-off-by: Linus Torvalds --- .../mach-bf527/include/mach/bfin_serial_5xx.h | 26 ---- .../mach-bf533/include/mach/bfin_serial_5xx.h | 20 ---- .../mach-bf537/include/mach/bfin_serial_5xx.h | 27 ----- .../mach-bf548/include/mach/bfin_serial_5xx.h | 45 ------- .../mach-bf561/include/mach/bfin_serial_5xx.h | 20 ---- drivers/serial/bfin_5xx.c | 131 +++++++++++++-------- 6 files changed, 82 insertions(+), 187 deletions(-) (limited to 'drivers/serial/bfin_5xx.c') diff --git a/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h index e8c41fd842b5..d2b160c14f04 100644 --- a/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h +++ b/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h @@ -167,29 +167,3 @@ struct bfin_serial_res bfin_serial_resource[] = { }; #define DRIVER_NAME "bfin-uart" - -static void bfin_serial_hw_init(struct bfin_serial_port *uart) -{ - -#ifdef CONFIG_SERIAL_BFIN_UART0 - peripheral_request(P_UART0_TX, DRIVER_NAME); - peripheral_request(P_UART0_RX, DRIVER_NAME); -#endif - -#ifdef CONFIG_SERIAL_BFIN_UART1 - peripheral_request(P_UART1_TX, DRIVER_NAME); - peripheral_request(P_UART1_RX, DRIVER_NAME); -#endif - -#ifdef CONFIG_SERIAL_BFIN_CTSRTS - if (uart->cts_pin >= 0) { - gpio_request(uart->cts_pin, DRIVER_NAME); - gpio_direction_input(uart->cts_pin); - } - - if (uart->rts_pin >= 0) { - gpio_request(uart->rts_pin, DRIVER_NAME); - gpio_direction_output(uart->rts_pin, 0); - } -#endif -} diff --git a/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h index 5f517f53b0fd..70356ddf8509 100644 --- a/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h +++ b/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h @@ -142,23 +142,3 @@ struct bfin_serial_res bfin_serial_resource[] = { }; #define DRIVER_NAME "bfin-uart" - -static void bfin_serial_hw_init(struct bfin_serial_port *uart) -{ - -#ifdef CONFIG_SERIAL_BFIN_UART0 - peripheral_request(P_UART0_TX, DRIVER_NAME); - peripheral_request(P_UART0_RX, DRIVER_NAME); -#endif - -#ifdef CONFIG_SERIAL_BFIN_CTSRTS - if (uart->cts_pin >= 0) { - gpio_request(uart->cts_pin, DRIVER_NAME); - gpio_direction_input(uart->cts_pin); - } - if (uart->rts_pin >= 0) { - gpio_request(uart->rts_pin, DRIVER_NAME); - gpio_direction_output(uart->rts_pin, 0); - } -#endif -} diff --git a/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h index 9e34700844a2..d46fc4f50cf2 100644 --- a/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h +++ b/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h @@ -99,7 +99,6 @@ struct bfin_serial_port { struct work_struct tx_dma_workqueue; #endif #ifdef CONFIG_SERIAL_BFIN_CTSRTS - struct timer_list cts_timer; int cts_pin; int rts_pin; #endif @@ -167,29 +166,3 @@ struct bfin_serial_res bfin_serial_resource[] = { }; #define DRIVER_NAME "bfin-uart" - -static void bfin_serial_hw_init(struct bfin_serial_port *uart) -{ - -#ifdef CONFIG_SERIAL_BFIN_UART0 - peripheral_request(P_UART0_TX, DRIVER_NAME); - peripheral_request(P_UART0_RX, DRIVER_NAME); -#endif - -#ifdef CONFIG_SERIAL_BFIN_UART1 - peripheral_request(P_UART1_TX, DRIVER_NAME); - peripheral_request(P_UART1_RX, DRIVER_NAME); -#endif - -#ifdef CONFIG_SERIAL_BFIN_CTSRTS - if (uart->cts_pin >= 0) { - gpio_request(uart->cts_pin, DRIVER_NAME); - gpio_direction_input(uart->cts_pin); - } - - if (uart->rts_pin >= 0) { - gpio_request(uart->rts_pin, DRIVER_NAME); - gpio_direction_output(uart->rts_pin, 0); - } -#endif -} diff --git a/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h index c05e79cba257..388e2328aeba 100644 --- a/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h +++ b/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h @@ -181,48 +181,3 @@ struct bfin_serial_res bfin_serial_resource[] = { }; #define DRIVER_NAME "bfin-uart" - -static void bfin_serial_hw_init(struct bfin_serial_port *uart) -{ -#ifdef CONFIG_SERIAL_BFIN_UART0 - peripheral_request(P_UART0_TX, DRIVER_NAME); - peripheral_request(P_UART0_RX, DRIVER_NAME); -#endif - -#ifdef CONFIG_SERIAL_BFIN_UART1 - peripheral_request(P_UART1_TX, DRIVER_NAME); - peripheral_request(P_UART1_RX, DRIVER_NAME); - -#ifdef CONFIG_BFIN_UART1_CTSRTS - peripheral_request(P_UART1_RTS, DRIVER_NAME); - peripheral_request(P_UART1_CTS, DRIVER_NAME); -#endif -#endif - -#ifdef CONFIG_SERIAL_BFIN_UART2 - peripheral_request(P_UART2_TX, DRIVER_NAME); - peripheral_request(P_UART2_RX, DRIVER_NAME); -#endif - -#ifdef CONFIG_SERIAL_BFIN_UART3 - peripheral_request(P_UART3_TX, DRIVER_NAME); - peripheral_request(P_UART3_RX, DRIVER_NAME); - -#ifdef CONFIG_BFIN_UART3_CTSRTS - peripheral_request(P_UART3_RTS, DRIVER_NAME); - peripheral_request(P_UART3_CTS, DRIVER_NAME); -#endif -#endif - SSYNC(); -#ifdef CONFIG_SERIAL_BFIN_CTSRTS - if (uart->cts_pin >= 0) { - gpio_request(uart->cts_pin, DRIVER_NAME); - gpio_direction_input(uart->cts_pin); - } - - if (uart->rts_pin >= 0) { - gpio_request(uart->rts_pin, DRIVER_NAME); - gpio_direction_output(uart->rts_pin, 0); - } -#endif -} diff --git a/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h index ca8c5f645209..d0469e3e16d8 100644 --- a/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h +++ b/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h @@ -142,23 +142,3 @@ struct bfin_serial_res bfin_serial_resource[] = { }; #define DRIVER_NAME "bfin-uart" - -static void bfin_serial_hw_init(struct bfin_serial_port *uart) -{ - -#ifdef CONFIG_SERIAL_BFIN_UART0 - peripheral_request(P_UART0_TX, DRIVER_NAME); - peripheral_request(P_UART0_RX, DRIVER_NAME); -#endif - -#ifdef CONFIG_SERIAL_BFIN_CTSRTS - if (uart->cts_pin >= 0) { - gpio_request(uart->cts_pin, DRIVER_NAME); - gpio_direction_input(uart->cts_pin); - } - if (uart->rts_pin >= 0) { - gpio_request(uart->rts_pin, DRIVER_NAME); - gpio_direction_output(uart->rts_pin, 0); - } -#endif -} diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c index f9b5a72e261a..fbbddb9e73f6 100644 --- a/drivers/serial/bfin_5xx.c +++ b/drivers/serial/bfin_5xx.c @@ -63,7 +63,6 @@ static int kgdboc_break_enabled; #define DMA_RX_YCOUNT (PAGE_SIZE / DMA_RX_XCOUNT) #define DMA_RX_FLUSH_JIFFIES (HZ / 50) -#define CTS_CHECK_JIFFIES (HZ / 50) #ifdef CONFIG_SERIAL_BFIN_DMA static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart); @@ -71,8 +70,6 @@ static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart); static void bfin_serial_tx_chars(struct bfin_serial_port *uart); #endif -static void bfin_serial_mctrl_check(struct bfin_serial_port *uart); - static void bfin_serial_reset_irda(struct uart_port *port); /* @@ -264,12 +261,6 @@ static void bfin_serial_tx_chars(struct bfin_serial_port *uart) { struct circ_buf *xmit = &uart->port.info->xmit; - /* - * Check the modem control lines before - * transmitting anything. - */ - bfin_serial_mctrl_check(uart); - if (uart_circ_empty(xmit) || uart_tx_stopped(&uart->port)) { #ifdef CONFIG_BF54x /* Clear TFI bit */ @@ -328,12 +319,6 @@ static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart) uart->tx_done = 0; - /* - * Check the modem control lines before - * transmitting anything. - */ - bfin_serial_mctrl_check(uart); - if (uart_circ_empty(xmit) || uart_tx_stopped(&uart->port)) { uart->tx_count = 0; uart->tx_done = 1; @@ -524,29 +509,21 @@ static void bfin_serial_set_mctrl(struct uart_port *port, unsigned int mctrl) #endif } +#ifdef CONFIG_SERIAL_BFIN_CTSRTS /* - * Handle any change of modem status signal since we were last called. + * Handle any change of modem status signal. */ -static void bfin_serial_mctrl_check(struct bfin_serial_port *uart) +static irqreturn_t bfin_serial_mctrl_cts_int(int irq, void *dev_id) { -#ifdef CONFIG_SERIAL_BFIN_CTSRTS + struct bfin_serial_port *uart = dev_id; unsigned int status; - struct uart_info *info = uart->port.info; - struct tty_struct *tty = info->port.tty; status = bfin_serial_get_mctrl(&uart->port); uart_handle_cts_change(&uart->port, status & TIOCM_CTS); - if (!(status & TIOCM_CTS)) { - tty->hw_stopped = 1; - uart->cts_timer.data = (unsigned long)(uart); - uart->cts_timer.function = (void *)bfin_serial_mctrl_check; - uart->cts_timer.expires = jiffies + CTS_CHECK_JIFFIES; - add_timer(&(uart->cts_timer)); - } else { - tty->hw_stopped = 0; - } -#endif + + return IRQ_HANDLED; } +#endif /* * Interrupts are always disabled. @@ -606,7 +583,7 @@ static int bfin_serial_startup(struct uart_port *port) uart->rx_dma_timer.expires = jiffies + DMA_RX_FLUSH_JIFFIES; add_timer(&(uart->rx_dma_timer)); #else -#if defined(CONFIG_KGDB_SERIAL_CONSOLE) || \ +# if defined(CONFIG_KGDB_SERIAL_CONSOLE) || \ defined(CONFIG_KGDB_SERIAL_CONSOLE_MODULE) if (kgdboc_port_line == uart->port.line && kgdboc_break_enabled) kgdboc_break_enabled = 0; @@ -661,10 +638,27 @@ static int bfin_serial_startup(struct uart_port *port) } } # endif -#if defined(CONFIG_KGDB_SERIAL_CONSOLE) || \ +# if defined(CONFIG_KGDB_SERIAL_CONSOLE) || \ defined(CONFIG_KGDB_SERIAL_CONSOLE_MODULE) } # endif +#endif + +#ifdef CONFIG_SERIAL_BFIN_CTSRTS + if (uart->cts_pin >= 0) { + if (request_irq(gpio_to_irq(uart->cts_pin), + bfin_serial_mctrl_cts_int, + IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | + IRQF_DISABLED, "BFIN_UART_CTS", uart)) { + uart->cts_pin = -1; + pr_info("Unable to attach BlackFin UART CTS interrupt.\ + So, disable it.\n"); + } + } + if (uart->rts_pin >= 0) { + gpio_request(uart->rts_pin, DRIVER_NAME); + gpio_direction_output(uart->rts_pin, 0); + } #endif UART_SET_IER(uart, ERBFI); return 0; @@ -699,6 +693,13 @@ static void bfin_serial_shutdown(struct uart_port *port) free_irq(uart->port.irq, uart); free_irq(uart->port.irq+1, uart); #endif + +# 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 } static void @@ -864,6 +865,20 @@ static void bfin_serial_set_ldisc(struct uart_port *port) } } +static void bfin_serial_reset_irda(struct uart_port *port) +{ + int line = port->line; + unsigned short val; + + val = UART_GET_GCTL(&bfin_serial_ports[line]); + val &= ~(IREN | RPOLC); + UART_PUT_GCTL(&bfin_serial_ports[line], val); + SSYNC(); + val |= (IREN | RPOLC); + UART_PUT_GCTL(&bfin_serial_ports[line], val); + SSYNC(); +} + #ifdef CONFIG_CONSOLE_POLL static void bfin_serial_poll_put_char(struct uart_port *port, unsigned char chr) { @@ -909,20 +924,6 @@ static int bfin_kgdboc_port_startup(struct uart_port *port) } #endif -static void bfin_serial_reset_irda(struct uart_port *port) -{ - int line = port->line; - unsigned short val; - - val = UART_GET_GCTL(&bfin_serial_ports[line]); - val &= ~(IREN | RPOLC); - UART_PUT_GCTL(&bfin_serial_ports[line], val); - SSYNC(); - val |= (IREN | RPOLC); - UART_PUT_GCTL(&bfin_serial_ports[line], val); - SSYNC(); -} - static struct uart_ops bfin_serial_pops = { .tx_empty = bfin_serial_tx_empty, .set_mctrl = bfin_serial_set_mctrl, @@ -952,6 +953,39 @@ static struct uart_ops bfin_serial_pops = { #endif }; +static void __init bfin_serial_hw_init(void) +{ +#ifdef CONFIG_SERIAL_BFIN_UART0 + peripheral_request(P_UART0_TX, DRIVER_NAME); + peripheral_request(P_UART0_RX, DRIVER_NAME); +#endif + +#ifdef CONFIG_SERIAL_BFIN_UART1 + peripheral_request(P_UART1_TX, DRIVER_NAME); + peripheral_request(P_UART1_RX, DRIVER_NAME); + +# if defined(CONFIG_BFIN_UART1_CTSRTS) && defined(CONFIG_BF54x) + peripheral_request(P_UART1_RTS, DRIVER_NAME); + peripheral_request(P_UART1_CTS, DRIVER_NAME); +# endif +#endif + +#ifdef CONFIG_SERIAL_BFIN_UART2 + peripheral_request(P_UART2_TX, DRIVER_NAME); + peripheral_request(P_UART2_RX, DRIVER_NAME); +#endif + +#ifdef CONFIG_SERIAL_BFIN_UART3 + peripheral_request(P_UART3_TX, DRIVER_NAME); + peripheral_request(P_UART3_RX, DRIVER_NAME); + +# if defined(CONFIG_BFIN_UART3_CTSRTS) && defined(CONFIG_BF54x) + peripheral_request(P_UART3_RTS, DRIVER_NAME); + peripheral_request(P_UART3_CTS, DRIVER_NAME); +# endif +#endif +} + static void __init bfin_serial_init_ports(void) { static int first = 1; @@ -961,6 +995,8 @@ static void __init bfin_serial_init_ports(void) return; first = 0; + bfin_serial_hw_init(); + for (i = 0; i < nr_active_ports; i++) { bfin_serial_ports[i].port.uartclk = get_sclk(); bfin_serial_ports[i].port.fifosize = BFIN_UART_TX_FIFO_SIZE; @@ -984,15 +1020,12 @@ static void __init bfin_serial_init_ports(void) init_timer(&(bfin_serial_ports[i].rx_dma_timer)); #endif #ifdef CONFIG_SERIAL_BFIN_CTSRTS - init_timer(&(bfin_serial_ports[i].cts_timer)); bfin_serial_ports[i].cts_pin = bfin_serial_resource[i].uart_cts_pin; bfin_serial_ports[i].rts_pin = bfin_serial_resource[i].uart_rts_pin; #endif - bfin_serial_hw_init(&bfin_serial_ports[i]); } - } #if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK) -- cgit v1.2.3-59-g8ed1b From d307d36adeaa70074773b3e5eab8d7e1beb008a4 Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Tue, 7 Apr 2009 16:52:26 +0100 Subject: tty: Blackin CTS/RTS Both software emulated and hardware based CTS and RTS are enabled in serial driver. The CTS RTS PIN connection on BF548 UART port is defined as a modem device not as a host device. In order to test it under Linux, please nake a cross UART cable to exchange CTS and RTS signal. Signed-off-by: Sonic Zhang Signed-off-by: Bryan Wu Signed-off-by: Andrew Morton Signed-off-by: Alan Cox Signed-off-by: Linus Torvalds --- .../mach-bf518/include/mach/bfin_serial_5xx.h | 10 +- .../mach-bf527/include/mach/bfin_serial_5xx.h | 10 +- .../mach-bf533/include/mach/bfin_serial_5xx.h | 9 +- .../mach-bf537/include/mach/bfin_serial_5xx.h | 10 +- .../mach-bf538/include/mach/bfin_serial_5xx.h | 10 +- .../mach-bf548/include/mach/bfin_serial_5xx.h | 72 ++++----- .../mach-bf561/include/mach/bfin_serial_5xx.h | 9 +- drivers/serial/Kconfig | 26 +++- drivers/serial/bfin_5xx.c | 169 ++++++++++++++------- 9 files changed, 209 insertions(+), 116 deletions(-) (limited to 'drivers/serial/bfin_5xx.c') diff --git a/arch/blackfin/mach-bf518/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf518/include/mach/bfin_serial_5xx.h index e21c1c3e4ec7..0fb2ce5d840e 100644 --- a/arch/blackfin/mach-bf518/include/mach/bfin_serial_5xx.h +++ b/arch/blackfin/mach-bf518/include/mach/bfin_serial_5xx.h @@ -53,9 +53,9 @@ #define UART_SET_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0) #define UART_CLEAR_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0) -#define UART_GET_CTS(x) gpio_get_value(x->cts_pin) -#define UART_SET_RTS(x) gpio_set_value(x->rts_pin, 1) -#define UART_CLEAR_RTS(x) gpio_set_value(x->rts_pin, 0) +#define UART_GET_CTS(x) (!gpio_get_value(x->cts_pin)) +#define UART_DISABLE_RTS(x) gpio_set_value(x->rts_pin, 1) +#define UART_ENABLE_RTS(x) gpio_set_value(x->rts_pin, 0) #define UART_ENABLE_INTS(x, v) UART_PUT_IER(x, v) #define UART_DISABLE_INTS(x) UART_PUT_IER(x, 0) @@ -87,6 +87,7 @@ struct bfin_serial_port { struct uart_port port; unsigned int old_status; + int status_irq; unsigned int lsr; #ifdef CONFIG_SERIAL_BFIN_DMA int tx_done; @@ -125,6 +126,7 @@ static inline void UART_CLEAR_LSR(struct bfin_serial_port *uart) struct bfin_serial_res { unsigned long uart_base_addr; int uart_irq; + int uart_status_irq; #ifdef CONFIG_SERIAL_BFIN_DMA unsigned int uart_tx_dma_channel; unsigned int uart_rx_dma_channel; @@ -140,6 +142,7 @@ struct bfin_serial_res bfin_serial_resource[] = { { 0xFFC00400, IRQ_UART0_RX, + IRQ_UART0_ERROR, #ifdef CONFIG_SERIAL_BFIN_DMA CH_UART0_TX, CH_UART0_RX, @@ -154,6 +157,7 @@ struct bfin_serial_res bfin_serial_resource[] = { { 0xFFC02000, IRQ_UART1_RX, + IRQ_UART1_ERROR, #ifdef CONFIG_SERIAL_BFIN_DMA CH_UART1_TX, CH_UART1_RX, diff --git a/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h index d2b160c14f04..a625659dd67f 100644 --- a/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h +++ b/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h @@ -53,9 +53,9 @@ #define UART_SET_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0) #define UART_CLEAR_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0) -#define UART_GET_CTS(x) gpio_get_value(x->cts_pin) -#define UART_SET_RTS(x) gpio_set_value(x->rts_pin, 1) -#define UART_CLEAR_RTS(x) gpio_set_value(x->rts_pin, 0) +#define UART_GET_CTS(x) (!gpio_get_value(x->cts_pin)) +#define UART_DISABLE_RTS(x) gpio_set_value(x->rts_pin, 1) +#define UART_ENABLE_RTS(x) gpio_set_value(x->rts_pin, 0) #define UART_ENABLE_INTS(x, v) UART_PUT_IER(x, v) #define UART_DISABLE_INTS(x) UART_PUT_IER(x, 0) @@ -87,6 +87,7 @@ struct bfin_serial_port { struct uart_port port; unsigned int old_status; + int status_irq; unsigned int lsr; #ifdef CONFIG_SERIAL_BFIN_DMA int tx_done; @@ -125,6 +126,7 @@ static inline void UART_CLEAR_LSR(struct bfin_serial_port *uart) struct bfin_serial_res { unsigned long uart_base_addr; int uart_irq; + int uart_status_irq; #ifdef CONFIG_SERIAL_BFIN_DMA unsigned int uart_tx_dma_channel; unsigned int uart_rx_dma_channel; @@ -140,6 +142,7 @@ struct bfin_serial_res bfin_serial_resource[] = { { 0xFFC00400, IRQ_UART0_RX, + IRQ_UART0_ERROR, #ifdef CONFIG_SERIAL_BFIN_DMA CH_UART0_TX, CH_UART0_RX, @@ -154,6 +157,7 @@ struct bfin_serial_res bfin_serial_resource[] = { { 0xFFC02000, IRQ_UART1_RX, + IRQ_UART1_ERROR, #ifdef CONFIG_SERIAL_BFIN_DMA CH_UART1_TX, CH_UART1_RX, diff --git a/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h index 70356ddf8509..a3789d7ccf8c 100644 --- a/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h +++ b/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h @@ -53,9 +53,9 @@ #define UART_SET_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0) #define UART_CLEAR_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0) -#define UART_GET_CTS(x) gpio_get_value(x->cts_pin) -#define UART_SET_RTS(x) gpio_set_value(x->rts_pin, 1) -#define UART_CLEAR_RTS(x) gpio_set_value(x->rts_pin, 0) +#define UART_GET_CTS(x) (!gpio_get_value(x->cts_pin)) +#define UART_DISABLE_RTS(x) gpio_set_value(x->rts_pin, 1) +#define UART_ENABLE_RTS(x) gpio_set_value(x->rts_pin, 0) #define UART_ENABLE_INTS(x, v) UART_PUT_IER(x, v) #define UART_DISABLE_INTS(x) UART_PUT_IER(x, 0) @@ -74,6 +74,7 @@ struct bfin_serial_port { struct uart_port port; unsigned int old_status; + int status_irq; unsigned int lsr; #ifdef CONFIG_SERIAL_BFIN_DMA int tx_done; @@ -116,6 +117,7 @@ static inline void UART_CLEAR_LSR(struct bfin_serial_port *uart) struct bfin_serial_res { unsigned long uart_base_addr; int uart_irq; + int uart_status_irq; #ifdef CONFIG_SERIAL_BFIN_DMA unsigned int uart_tx_dma_channel; unsigned int uart_rx_dma_channel; @@ -130,6 +132,7 @@ struct bfin_serial_res bfin_serial_resource[] = { { 0xFFC00400, IRQ_UART_RX, + IRQ_UART_ERROR, #ifdef CONFIG_SERIAL_BFIN_DMA CH_UART_TX, CH_UART_RX, diff --git a/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h index d46fc4f50cf2..b86662fb9de7 100644 --- a/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h +++ b/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h @@ -53,9 +53,9 @@ #define UART_SET_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0) #define UART_CLEAR_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0) -#define UART_GET_CTS(x) gpio_get_value(x->cts_pin) -#define UART_SET_RTS(x) gpio_set_value(x->rts_pin, 1) -#define UART_CLEAR_RTS(x) gpio_set_value(x->rts_pin, 0) +#define UART_GET_CTS(x) (!gpio_get_value(x->cts_pin)) +#define UART_DISABLE_RTS(x) gpio_set_value(x->rts_pin, 1) +#define UART_ENABLE_RTS(x) gpio_set_value(x->rts_pin, 0) #define UART_ENABLE_INTS(x, v) UART_PUT_IER(x, v) #define UART_DISABLE_INTS(x) UART_PUT_IER(x, 0) @@ -87,6 +87,7 @@ struct bfin_serial_port { struct uart_port port; unsigned int old_status; + int status_irq; unsigned int lsr; #ifdef CONFIG_SERIAL_BFIN_DMA int tx_done; @@ -124,6 +125,7 @@ static inline void UART_CLEAR_LSR(struct bfin_serial_port *uart) struct bfin_serial_res { unsigned long uart_base_addr; int uart_irq; + int uart_status_irq; #ifdef CONFIG_SERIAL_BFIN_DMA unsigned int uart_tx_dma_channel; unsigned int uart_rx_dma_channel; @@ -139,6 +141,7 @@ struct bfin_serial_res bfin_serial_resource[] = { { 0xFFC00400, IRQ_UART0_RX, + IRQ_UART0_ERROR, #ifdef CONFIG_SERIAL_BFIN_DMA CH_UART0_TX, CH_UART0_RX, @@ -153,6 +156,7 @@ struct bfin_serial_res bfin_serial_resource[] = { { 0xFFC02000, IRQ_UART1_RX, + IRQ_UART1_ERROR, #ifdef CONFIG_SERIAL_BFIN_DMA CH_UART1_TX, CH_UART1_RX, diff --git a/arch/blackfin/mach-bf538/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf538/include/mach/bfin_serial_5xx.h index 3c2811ebecdd..c536551eb4b8 100644 --- a/arch/blackfin/mach-bf538/include/mach/bfin_serial_5xx.h +++ b/arch/blackfin/mach-bf538/include/mach/bfin_serial_5xx.h @@ -53,9 +53,9 @@ #define UART_SET_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0) #define UART_CLEAR_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0) -#define UART_GET_CTS(x) gpio_get_value(x->cts_pin) -#define UART_SET_RTS(x) gpio_set_value(x->rts_pin, 1) -#define UART_CLEAR_RTS(x) gpio_set_value(x->rts_pin, 0) +#define UART_GET_CTS(x) (!gpio_get_value(x->cts_pin)) +#define UART_DISABLE_RTS(x) gpio_set_value(x->rts_pin, 1) +#define UART_ENABLE_RTS(x) gpio_set_value(x->rts_pin, 0) #define UART_ENABLE_INTS(x, v) UART_PUT_IER(x, v) #define UART_DISABLE_INTS(x) UART_PUT_IER(x, 0) @@ -87,6 +87,7 @@ struct bfin_serial_port { struct uart_port port; unsigned int old_status; + int status_irq; unsigned int lsr; #ifdef CONFIG_SERIAL_BFIN_DMA int tx_done; @@ -125,6 +126,7 @@ static inline void UART_CLEAR_LSR(struct bfin_serial_port *uart) struct bfin_serial_res { unsigned long uart_base_addr; int uart_irq; + int uart_status_irq; #ifdef CONFIG_SERIAL_BFIN_DMA unsigned int uart_tx_dma_channel; unsigned int uart_rx_dma_channel; @@ -140,6 +142,7 @@ struct bfin_serial_res bfin_serial_resource[] = { { 0xFFC00400, IRQ_UART0_RX, + IRQ_UART0_ERROR, #ifdef CONFIG_SERIAL_BFIN_DMA CH_UART0_TX, CH_UART0_RX, @@ -154,6 +157,7 @@ struct bfin_serial_res bfin_serial_resource[] = { { 0xFFC02000, IRQ_UART1_RX, + IRQ_UART1_ERROR, #ifdef CONFIG_SERIAL_BFIN_DMA CH_UART1_TX, CH_UART1_RX, diff --git a/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h index 388e2328aeba..2d1b5fa3cca0 100644 --- a/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h +++ b/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h @@ -46,41 +46,27 @@ #define UART_PUT_CHAR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_THR),v) #define UART_PUT_DLL(uart,v) bfin_write16(((uart)->port.membase + OFFSET_DLL),v) #define UART_SET_IER(uart,v) bfin_write16(((uart)->port.membase + OFFSET_IER_SET),v) -#define UART_CLEAR_IER(uart,v) bfin_write16(((uart)->port.membase + OFFSET_IER_CLEAR),v) +#define UART_CLEAR_IER(uart,v) bfin_write16(((uart)->port.membase + OFFSET_IER_CLEAR),v) #define UART_PUT_DLH(uart,v) bfin_write16(((uart)->port.membase + OFFSET_DLH),v) #define UART_PUT_LSR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_LSR),v) #define UART_PUT_LCR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_LCR),v) #define UART_CLEAR_LSR(uart) bfin_write16(((uart)->port.membase + OFFSET_LSR), -1) #define UART_PUT_GCTL(uart,v) bfin_write16(((uart)->port.membase + OFFSET_GCTL),v) #define UART_PUT_MCR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_MCR),v) +#define UART_CLEAR_SCTS(uart) bfin_write16(((uart)->port.membase + OFFSET_MSR),SCTS) #define UART_SET_DLAB(uart) /* MMRs not muxed on BF54x */ #define UART_CLEAR_DLAB(uart) /* MMRs not muxed on BF54x */ #define UART_GET_CTS(x) (UART_GET_MSR(x) & CTS) -#define UART_SET_RTS(x) (UART_PUT_MCR(x, UART_GET_MCR(x) | MRTS)) -#define UART_CLEAR_RTS(x) (UART_PUT_MCR(x, UART_GET_MCR(x) & ~MRTS)) +#define UART_DISABLE_RTS(x) UART_PUT_MCR(x, UART_GET_MCR(x) & ~(ARTS|MRTS)) +#define UART_ENABLE_RTS(x) UART_PUT_MCR(x, UART_GET_MCR(x) | MRTS | ARTS) #define UART_ENABLE_INTS(x, v) UART_SET_IER(x, v) #define UART_DISABLE_INTS(x) UART_CLEAR_IER(x, 0xF) -#if defined(CONFIG_BFIN_UART0_CTSRTS) || defined(CONFIG_BFIN_UART2_CTSRTS) -# define CONFIG_SERIAL_BFIN_CTSRTS - -# ifndef CONFIG_UART0_CTS_PIN -# define CONFIG_UART0_CTS_PIN -1 -# endif - -# ifndef CONFIG_UART0_RTS_PIN -# define CONFIG_UART0_RTS_PIN -1 -# endif - -# ifndef CONFIG_UART2_CTS_PIN -# define CONFIG_UART2_CTS_PIN -1 -# endif - -# ifndef CONFIG_UART2_RTS_PIN -# define CONFIG_UART2_RTS_PIN -1 -# endif +#if defined(CONFIG_BFIN_UART0_CTSRTS) || defined(CONFIG_BFIN_UART1_CTSRTS) || \ + defined(CONFIG_BFIN_UART2_CTSRTS) || defined(CONFIG_BFIN_UART3_CTSRTS) +# define CONFIG_SERIAL_BFIN_HARD_CTSRTS #endif #define BFIN_UART_TX_FIFO_SIZE 2 @@ -91,6 +77,7 @@ struct bfin_serial_port { struct uart_port port; unsigned int old_status; + int status_irq; #ifdef CONFIG_SERIAL_BFIN_DMA int tx_done; int tx_count; @@ -101,23 +88,24 @@ struct bfin_serial_port { unsigned int rx_dma_channel; struct work_struct tx_dma_workqueue; #endif -#ifdef CONFIG_SERIAL_BFIN_CTSRTS - struct timer_list cts_timer; - int cts_pin; - int rts_pin; +#ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS + int scts; + int cts_pin; + int rts_pin; #endif }; struct bfin_serial_res { unsigned long uart_base_addr; int uart_irq; + int uart_status_irq; #ifdef CONFIG_SERIAL_BFIN_DMA unsigned int uart_tx_dma_channel; unsigned int uart_rx_dma_channel; #endif -#ifdef CONFIG_SERIAL_BFIN_CTSRTS - int uart_cts_pin; - int uart_rts_pin; +#ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS + int uart_cts_pin; + int uart_rts_pin; #endif }; @@ -126,13 +114,14 @@ struct bfin_serial_res bfin_serial_resource[] = { { 0xFFC00400, IRQ_UART0_RX, + IRQ_UART0_ERROR, #ifdef CONFIG_SERIAL_BFIN_DMA CH_UART0_TX, CH_UART0_RX, #endif -#ifdef CONFIG_SERIAL_BFIN_CTSRTS - CONFIG_UART0_CTS_PIN, - CONFIG_UART0_RTS_PIN, +#ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS + 0, + 0, #endif }, #endif @@ -140,13 +129,14 @@ struct bfin_serial_res bfin_serial_resource[] = { { 0xFFC02000, IRQ_UART1_RX, + IRQ_UART1_ERROR, #ifdef CONFIG_SERIAL_BFIN_DMA CH_UART1_TX, CH_UART1_RX, #endif -#ifdef CONFIG_SERIAL_BFIN_CTSRTS - 0, - 0, +#ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS + GPIO_PE10, + GPIO_PE9, #endif }, #endif @@ -154,13 +144,14 @@ struct bfin_serial_res bfin_serial_resource[] = { { 0xFFC02100, IRQ_UART2_RX, + IRQ_UART2_ERROR, #ifdef CONFIG_SERIAL_BFIN_DMA CH_UART2_TX, CH_UART2_RX, #endif -#ifdef CONFIG_SERIAL_BFIN_CTSRTS - CONFIG_UART2_CTS_PIN, - CONFIG_UART2_RTS_PIN, +#ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS + 0, + 0, #endif }, #endif @@ -168,13 +159,14 @@ struct bfin_serial_res bfin_serial_resource[] = { { 0xFFC03100, IRQ_UART3_RX, + IRQ_UART3_ERROR, #ifdef CONFIG_SERIAL_BFIN_DMA CH_UART3_TX, CH_UART3_RX, #endif -#ifdef CONFIG_SERIAL_BFIN_CTSRTS - 0, - 0, +#ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS + GPIO_PB3, + GPIO_PB2, #endif }, #endif diff --git a/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h index d0469e3e16d8..a1b50878553f 100644 --- a/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h +++ b/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h @@ -53,9 +53,9 @@ #define UART_SET_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0) #define UART_CLEAR_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0) -#define UART_GET_CTS(x) gpio_get_value(x->cts_pin) -#define UART_SET_RTS(x) gpio_set_value(x->rts_pin, 1) -#define UART_CLEAR_RTS(x) gpio_set_value(x->rts_pin, 0) +#define UART_GET_CTS(x) (!gpio_get_value(x->cts_pin)) +#define UART_DISABLE_RTS(x) gpio_set_value(x->rts_pin, 1) +#define UART_ENABLE_RTS(x) gpio_set_value(x->rts_pin, 0) #define UART_ENABLE_INTS(x, v) UART_PUT_IER(x, v) #define UART_DISABLE_INTS(x) UART_PUT_IER(x, 0) @@ -74,6 +74,7 @@ struct bfin_serial_port { struct uart_port port; unsigned int old_status; + int status_irq; unsigned int lsr; #ifdef CONFIG_SERIAL_BFIN_DMA int tx_done; @@ -116,6 +117,7 @@ static inline void UART_CLEAR_LSR(struct bfin_serial_port *uart) struct bfin_serial_res { unsigned long uart_base_addr; int uart_irq; + int uart_status_irq; #ifdef CONFIG_SERIAL_BFIN_DMA unsigned int uart_tx_dma_channel; unsigned int uart_rx_dma_channel; @@ -130,6 +132,7 @@ struct bfin_serial_res bfin_serial_resource[] = { { 0xFFC00400, IRQ_UART_RX, + IRQ_UART_ERROR, #ifdef CONFIG_SERIAL_BFIN_DMA CH_UART_TX, CH_UART_RX, diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index d89972beb12c..f2e5736ad0c8 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -734,7 +734,7 @@ config BFIN_UART0_CTSRTS config UART0_CTS_PIN int "UART0 CTS pin" - depends on BFIN_UART0_CTSRTS + depends on BFIN_UART0_CTSRTS && !BF548 default 23 help The default pin is GPIO_GP7. @@ -742,7 +742,7 @@ config UART0_CTS_PIN config UART0_RTS_PIN int "UART0 RTS pin" - depends on BFIN_UART0_CTSRTS + depends on BFIN_UART0_CTSRTS && !BF548 default 22 help The default pin is GPIO_GP6. @@ -763,14 +763,14 @@ config BFIN_UART1_CTSRTS config UART1_CTS_PIN int "UART1 CTS pin" - depends on BFIN_UART1_CTSRTS && !BF54x + depends on BFIN_UART1_CTSRTS && !BF548 default -1 help Refer to ./include/asm-blackfin/gpio.h to see the GPIO map. config UART1_RTS_PIN int "UART1 RTS pin" - depends on BFIN_UART1_CTSRTS && !BF54x + depends on BFIN_UART1_CTSRTS && !BF548 default -1 help Refer to ./include/asm-blackfin/gpio.h to see the GPIO map. @@ -790,14 +790,14 @@ config BFIN_UART2_CTSRTS config UART2_CTS_PIN int "UART2 CTS pin" - depends on BFIN_UART2_CTSRTS + depends on BFIN_UART2_CTSRTS && !BF548 default -1 help Refer to ./include/asm-blackfin/gpio.h to see the GPIO map. config UART2_RTS_PIN int "UART2 RTS pin" - depends on BFIN_UART2_CTSRTS + depends on BFIN_UART2_CTSRTS && !BF548 default -1 help Refer to ./include/asm-blackfin/gpio.h to see the GPIO map. @@ -815,6 +815,20 @@ config BFIN_UART3_CTSRTS Enable hardware flow control in the driver. Using GPIO emulate the CTS/RTS signal. +config UART3_CTS_PIN + int "UART3 CTS pin" + depends on BFIN_UART3_CTSRTS && !BF548 + default -1 + help + Refer to ./include/asm-blackfin/gpio.h to see the GPIO map. + +config UART3_RTS_PIN + int "UART3 RTS pin" + depends on BFIN_UART3_CTSRTS && !BF548 + default -1 + help + Refer to ./include/asm-blackfin/gpio.h to see the GPIO map. + config SERIAL_IMX bool "IMX serial port support" depends on ARM && (ARCH_IMX || ARCH_MXC) diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c index fbbddb9e73f6..18ba812a4f84 100644 --- a/drivers/serial/bfin_5xx.c +++ b/drivers/serial/bfin_5xx.c @@ -72,6 +72,63 @@ static void bfin_serial_tx_chars(struct bfin_serial_port *uart); static void bfin_serial_reset_irda(struct uart_port *port); +#if defined(CONFIG_SERIAL_BFIN_CTSRTS) || \ + defined(CONFIG_SERIAL_BFIN_HARD_CTSRTS) +static unsigned int bfin_serial_get_mctrl(struct uart_port *port) +{ + struct bfin_serial_port *uart = (struct bfin_serial_port *)port; + if (uart->cts_pin < 0) + return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR; + + /* CTS PIN is negative assertive. */ + if (UART_GET_CTS(uart)) + return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR; + else + return TIOCM_DSR | TIOCM_CAR; +} + +static void bfin_serial_set_mctrl(struct uart_port *port, unsigned int mctrl) +{ + struct bfin_serial_port *uart = (struct bfin_serial_port *)port; + if (uart->rts_pin < 0) + return; + + /* RTS PIN is negative assertive. */ + if (mctrl & TIOCM_RTS) + UART_ENABLE_RTS(uart); + else + UART_DISABLE_RTS(uart); +} + +/* + * Handle any change of modem status signal. + */ +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); +#ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS + uart->scts = 1; + UART_CLEAR_SCTS(uart); + UART_CLEAR_IER(uart, EDSSI); +#endif + + return IRQ_HANDLED; +} +#else +static unsigned int bfin_serial_get_mctrl(struct uart_port *port) +{ + return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR; +} + +static void bfin_serial_set_mctrl(struct uart_port *port, unsigned int mctrl) +{ +} +#endif + /* * interrupts are disabled on entry */ @@ -108,6 +165,13 @@ 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.info->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. @@ -303,6 +367,12 @@ 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); @@ -433,6 +503,13 @@ 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.info->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); @@ -481,53 +558,6 @@ static unsigned int bfin_serial_tx_empty(struct uart_port *port) return 0; } -static unsigned int bfin_serial_get_mctrl(struct uart_port *port) -{ -#ifdef CONFIG_SERIAL_BFIN_CTSRTS - struct bfin_serial_port *uart = (struct bfin_serial_port *)port; - if (uart->cts_pin < 0) - return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR; - - if (UART_GET_CTS(uart)) - return TIOCM_DSR | TIOCM_CAR; - else -#endif - return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR; -} - -static void bfin_serial_set_mctrl(struct uart_port *port, unsigned int mctrl) -{ -#ifdef CONFIG_SERIAL_BFIN_CTSRTS - struct bfin_serial_port *uart = (struct bfin_serial_port *)port; - if (uart->rts_pin < 0) - return; - - if (mctrl & TIOCM_RTS) - UART_CLEAR_RTS(uart); - else - UART_SET_RTS(uart); -#endif -} - -#ifdef CONFIG_SERIAL_BFIN_CTSRTS -/* - * Handle any change of modem status signal. - */ -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); - - return IRQ_HANDLED; -} -#endif - -/* - * Interrupts are always disabled. - */ static void bfin_serial_break_ctl(struct uart_port *port, int break_state) { struct bfin_serial_port *uart = (struct bfin_serial_port *)port; @@ -660,6 +690,28 @@ static int bfin_serial_startup(struct uart_port *port) gpio_direction_output(uart->rts_pin, 0); } #endif +#ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS + if (request_irq(uart->status_irq, + bfin_serial_mctrl_cts_int, + IRQF_DISABLED, "BFIN_UART_MODEM_STATUS", uart)) { + pr_info("Unable to attach BlackFin UART Modem \ + Status interrupt.\n"); + } + + if (uart->cts_pin >= 0) { + gpio_request(uart->cts_pin, DRIVER_NAME); + gpio_direction_output(uart->cts_pin, 1); + } + if (uart->rts_pin >= 0) { + gpio_request(uart->rts_pin, DRIVER_NAME); + gpio_direction_output(uart->rts_pin, 0); + } + + /* CTS RTS PINs are negative assertive. */ + UART_PUT_MCR(uart, ACTS); + UART_SET_IER(uart, EDSSI); +#endif + UART_SET_IER(uart, ERBFI); return 0; } @@ -694,12 +746,20 @@ static void bfin_serial_shutdown(struct uart_port *port) free_irq(uart->port.irq+1, uart); #endif -# ifdef CONFIG_SERIAL_BFIN_CTSRTS +#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 +#endif +#ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS + if (uart->cts_pin >= 0) + gpio_free(uart->cts_pin); + if (uart->rts_pin >= 0) + gpio_free(uart->rts_pin); + if (UART_GET_IER(uart) && EDSSI) + free_irq(uart->status_irq, uart); +#endif } static void @@ -1009,6 +1069,8 @@ static void __init bfin_serial_init_ports(void) bfin_serial_resource[i].uart_base_addr; bfin_serial_ports[i].port.irq = bfin_serial_resource[i].uart_irq; + bfin_serial_ports[i].status_irq = + bfin_serial_resource[i].uart_status_irq; bfin_serial_ports[i].port.flags = UPF_BOOT_AUTOCONF; #ifdef CONFIG_SERIAL_BFIN_DMA bfin_serial_ports[i].tx_done = 1; @@ -1019,7 +1081,8 @@ static void __init bfin_serial_init_ports(void) bfin_serial_resource[i].uart_rx_dma_channel; init_timer(&(bfin_serial_ports[i].rx_dma_timer)); #endif -#ifdef CONFIG_SERIAL_BFIN_CTSRTS +#if defined(CONFIG_SERIAL_BFIN_CTSRTS) || \ + defined(CONFIG_SERIAL_BFIN_HARD_CTSRTS) bfin_serial_ports[i].cts_pin = bfin_serial_resource[i].uart_cts_pin; bfin_serial_ports[i].rts_pin = @@ -1082,7 +1145,8 @@ bfin_serial_console_setup(struct console *co, char *options) int baud = 57600; int bits = 8; int parity = 'n'; -# ifdef CONFIG_SERIAL_BFIN_CTSRTS +# if defined(CONFIG_SERIAL_BFIN_CTSRTS) || \ + defined(CONFIG_SERIAL_BFIN_HARD_CTSRTS) int flow = 'r'; # else int flow = 'n'; @@ -1279,7 +1343,8 @@ static int bfin_serial_remove(struct platform_device *dev) continue; uart_remove_one_port(&bfin_serial_reg, &bfin_serial_ports[i].port); bfin_serial_ports[i].port.dev = NULL; -#ifdef CONFIG_SERIAL_BFIN_CTSRTS +#if defined(CONFIG_SERIAL_BFIN_CTSRTS) || \ + defined(CONFIG_SERIAL_BFIN_HARD_CTSRTS) gpio_free(bfin_serial_ports[i].cts_pin); gpio_free(bfin_serial_ports[i].rts_pin); #endif -- cgit v1.2.3-59-g8ed1b From daba0280fdebce0761088cf541d6e6dd7c232850 Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Tue, 21 Apr 2009 12:24:58 -0700 Subject: bfin_5xx: misplaced parentheses `!' has a higher precedence than `&', parentheses are misplaced. Signed-off-by: Roel Kluin Cc: Alan Cox Acked-by: Sonic Zhang Cc: Bryan Wu Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/serial/bfin_5xx.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/serial/bfin_5xx.c') diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c index 18ba812a4f84..d86123e03391 100644 --- a/drivers/serial/bfin_5xx.c +++ b/drivers/serial/bfin_5xx.c @@ -166,7 +166,7 @@ static void bfin_serial_start_tx(struct uart_port *port) struct tty_struct *tty = uart->port.info->port.tty; #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS - if (uart->scts && (!bfin_serial_get_mctrl(&uart->port)&TIOCM_CTS)) { + if (uart->scts && !(bfin_serial_get_mctrl(&uart->port) & TIOCM_CTS)) { uart->scts = 0; uart_handle_cts_change(&uart->port, uart->scts); } @@ -368,7 +368,7 @@ 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)) { + if (uart->scts && !(bfin_serial_get_mctrl(&uart->port) & TIOCM_CTS)) { uart->scts = 0; uart_handle_cts_change(&uart->port, uart->scts); } @@ -504,7 +504,7 @@ static irqreturn_t bfin_serial_dma_tx_int(int irq, void *dev_id) struct circ_buf *xmit = &uart->port.info->xmit; #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS - if (uart->scts && (!bfin_serial_get_mctrl(&uart->port)&TIOCM_CTS)) { + if (uart->scts && !(bfin_serial_get_mctrl(&uart->port)&TIOCM_CTS)) { uart->scts = 0; uart_handle_cts_change(&uart->port, uart->scts); } -- cgit v1.2.3-59-g8ed1b