diff options
Diffstat (limited to 'drivers/serial/bfin_sport_uart.c')
-rw-r--r-- | drivers/serial/bfin_sport_uart.c | 111 |
1 files changed, 100 insertions, 11 deletions
diff --git a/drivers/serial/bfin_sport_uart.c b/drivers/serial/bfin_sport_uart.c index 79252664f70..8cb0a40c2ba 100644 --- a/drivers/serial/bfin_sport_uart.c +++ b/drivers/serial/bfin_sport_uart.c | |||
@@ -48,6 +48,10 @@ struct sport_uart_port { | |||
48 | unsigned short txmask2; | 48 | unsigned short txmask2; |
49 | unsigned char stopb; | 49 | unsigned char stopb; |
50 | /* unsigned char parib; */ | 50 | /* unsigned char parib; */ |
51 | #ifdef CONFIG_SERIAL_BFIN_SPORT_CTSRTS | ||
52 | int cts_pin; | ||
53 | int rts_pin; | ||
54 | #endif | ||
51 | }; | 55 | }; |
52 | 56 | ||
53 | static void sport_uart_tx_chars(struct sport_uart_port *up); | 57 | static void sport_uart_tx_chars(struct sport_uart_port *up); |
@@ -198,6 +202,59 @@ static irqreturn_t sport_uart_err_irq(int irq, void *dev_id) | |||
198 | return IRQ_HANDLED; | 202 | return IRQ_HANDLED; |
199 | } | 203 | } |
200 | 204 | ||
205 | #ifdef CONFIG_SERIAL_BFIN_SPORT_CTSRTS | ||
206 | static unsigned int sport_get_mctrl(struct uart_port *port) | ||
207 | { | ||
208 | struct sport_uart_port *up = (struct sport_uart_port *)port; | ||
209 | if (up->cts_pin < 0) | ||
210 | return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR; | ||
211 | |||
212 | /* CTS PIN is negative assertive. */ | ||
213 | if (SPORT_UART_GET_CTS(up)) | ||
214 | return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR; | ||
215 | else | ||
216 | return TIOCM_DSR | TIOCM_CAR; | ||
217 | } | ||
218 | |||
219 | static void sport_set_mctrl(struct uart_port *port, unsigned int mctrl) | ||
220 | { | ||
221 | struct sport_uart_port *up = (struct sport_uart_port *)port; | ||
222 | if (up->rts_pin < 0) | ||
223 | return; | ||
224 | |||
225 | /* RTS PIN is negative assertive. */ | ||
226 | if (mctrl & TIOCM_RTS) | ||
227 | SPORT_UART_ENABLE_RTS(up); | ||
228 | else | ||
229 | SPORT_UART_DISABLE_RTS(up); | ||
230 | } | ||
231 | |||
232 | /* | ||
233 | * Handle any change of modem status signal. | ||
234 | */ | ||
235 | static irqreturn_t sport_mctrl_cts_int(int irq, void *dev_id) | ||
236 | { | ||
237 | struct sport_uart_port *up = (struct sport_uart_port *)dev_id; | ||
238 | unsigned int status; | ||
239 | |||
240 | status = sport_get_mctrl(&up->port); | ||
241 | uart_handle_cts_change(&up->port, status & TIOCM_CTS); | ||
242 | |||
243 | return IRQ_HANDLED; | ||
244 | } | ||
245 | #else | ||
246 | static unsigned int sport_get_mctrl(struct uart_port *port) | ||
247 | { | ||
248 | pr_debug("%s enter\n", __func__); | ||
249 | return TIOCM_CTS | TIOCM_CD | TIOCM_DSR; | ||
250 | } | ||
251 | |||
252 | static void sport_set_mctrl(struct uart_port *port, unsigned int mctrl) | ||
253 | { | ||
254 | pr_debug("%s enter\n", __func__); | ||
255 | } | ||
256 | #endif | ||
257 | |||
201 | /* Reqeust IRQ, Setup clock */ | 258 | /* Reqeust IRQ, Setup clock */ |
202 | static int sport_startup(struct uart_port *port) | 259 | static int sport_startup(struct uart_port *port) |
203 | { | 260 | { |
@@ -226,6 +283,21 @@ static int sport_startup(struct uart_port *port) | |||
226 | goto fail2; | 283 | goto fail2; |
227 | } | 284 | } |
228 | 285 | ||
286 | #ifdef CONFIG_SERIAL_BFIN_SPORT_CTSRTS | ||
287 | if (up->cts_pin >= 0) { | ||
288 | if (request_irq(gpio_to_irq(up->cts_pin), | ||
289 | sport_mctrl_cts_int, | ||
290 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | | ||
291 | IRQF_DISABLED, "BFIN_SPORT_UART_CTS", up)) { | ||
292 | up->cts_pin = -1; | ||
293 | dev_info(port->dev, "Unable to attach BlackFin UART \ | ||
294 | over SPORT CTS interrupt. So, disable it.\n"); | ||
295 | } | ||
296 | } | ||
297 | if (up->rts_pin >= 0) | ||
298 | gpio_direction_output(up->rts_pin, 0); | ||
299 | #endif | ||
300 | |||
229 | return 0; | 301 | return 0; |
230 | fail2: | 302 | fail2: |
231 | free_irq(up->port.irq+1, up); | 303 | free_irq(up->port.irq+1, up); |
@@ -283,17 +355,6 @@ static unsigned int sport_tx_empty(struct uart_port *port) | |||
283 | return 0; | 355 | return 0; |
284 | } | 356 | } |
285 | 357 | ||
286 | static unsigned int sport_get_mctrl(struct uart_port *port) | ||
287 | { | ||
288 | pr_debug("%s enter\n", __func__); | ||
289 | return (TIOCM_CTS | TIOCM_CD | TIOCM_DSR); | ||
290 | } | ||
291 | |||
292 | static void sport_set_mctrl(struct uart_port *port, unsigned int mctrl) | ||
293 | { | ||
294 | pr_debug("%s enter\n", __func__); | ||
295 | } | ||
296 | |||
297 | static void sport_stop_tx(struct uart_port *port) | 358 | static void sport_stop_tx(struct uart_port *port) |
298 | { | 359 | { |
299 | struct sport_uart_port *up = (struct sport_uart_port *)port; | 360 | struct sport_uart_port *up = (struct sport_uart_port *)port; |
@@ -364,6 +425,10 @@ static void sport_shutdown(struct uart_port *port) | |||
364 | free_irq(up->port.irq, up); | 425 | free_irq(up->port.irq, up); |
365 | free_irq(up->port.irq+1, up); | 426 | free_irq(up->port.irq+1, up); |
366 | free_irq(up->err_irq, up); | 427 | free_irq(up->err_irq, up); |
428 | #ifdef CONFIG_SERIAL_BFIN_SPORT_CTSRTS | ||
429 | if (up->cts_pin >= 0) | ||
430 | free_irq(gpio_to_irq(up->cts_pin), up); | ||
431 | #endif | ||
367 | } | 432 | } |
368 | 433 | ||
369 | static const char *sport_type(struct uart_port *port) | 434 | static const char *sport_type(struct uart_port *port) |
@@ -536,7 +601,11 @@ sport_uart_console_setup(struct console *co, char *options) | |||
536 | int baud = 57600; | 601 | int baud = 57600; |
537 | int bits = 8; | 602 | int bits = 8; |
538 | int parity = 'n'; | 603 | int parity = 'n'; |
604 | # ifdef CONFIG_SERIAL_BFIN_SPORT_CTSRTS | ||
605 | int flow = 'r'; | ||
606 | # else | ||
539 | int flow = 'n'; | 607 | int flow = 'n'; |
608 | # endif | ||
540 | 609 | ||
541 | /* Check whether an invalid uart number has been specified */ | 610 | /* Check whether an invalid uart number has been specified */ |
542 | if (co->index < 0 || co->index >= BFIN_SPORT_UART_MAX_PORTS) | 611 | if (co->index < 0 || co->index >= BFIN_SPORT_UART_MAX_PORTS) |
@@ -729,6 +798,22 @@ static int __devinit sport_uart_probe(struct platform_device *pdev) | |||
729 | ret = -ENOENT; | 798 | ret = -ENOENT; |
730 | goto out_error_unmap; | 799 | goto out_error_unmap; |
731 | } | 800 | } |
801 | #ifdef CONFIG_SERIAL_BFIN_SPORT_CTSRTS | ||
802 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); | ||
803 | if (res == NULL) | ||
804 | sport->cts_pin = -1; | ||
805 | else | ||
806 | sport->cts_pin = res->start; | ||
807 | |||
808 | res = platform_get_resource(pdev, IORESOURCE_IO, 1); | ||
809 | if (res == NULL) | ||
810 | sport->rts_pin = -1; | ||
811 | else | ||
812 | sport->rts_pin = res->start; | ||
813 | |||
814 | if (sport->rts_pin >= 0) | ||
815 | gpio_request(sport->rts_pin, DRV_NAME); | ||
816 | #endif | ||
732 | } | 817 | } |
733 | 818 | ||
734 | #ifdef CONFIG_SERIAL_BFIN_SPORT_CONSOLE | 819 | #ifdef CONFIG_SERIAL_BFIN_SPORT_CONSOLE |
@@ -767,6 +852,10 @@ static int __devexit sport_uart_remove(struct platform_device *pdev) | |||
767 | 852 | ||
768 | if (sport) { | 853 | if (sport) { |
769 | uart_remove_one_port(&sport_uart_reg, &sport->port); | 854 | uart_remove_one_port(&sport_uart_reg, &sport->port); |
855 | #ifdef CONFIG_SERIAL_BFIN_CTSRTS | ||
856 | if (sport->rts_pin >= 0) | ||
857 | gpio_free(sport->rts_pin); | ||
858 | #endif | ||
770 | iounmap(sport->port.membase); | 859 | iounmap(sport->port.membase); |
771 | peripheral_free_list( | 860 | peripheral_free_list( |
772 | (unsigned short *)pdev->dev.platform_data); | 861 | (unsigned short *)pdev->dev.platform_data); |