aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/serial/bfin_sport_uart.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/serial/bfin_sport_uart.c')
-rw-r--r--drivers/serial/bfin_sport_uart.c111
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
53static void sport_uart_tx_chars(struct sport_uart_port *up); 57static 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
206static 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
219static 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 */
235static 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
246static 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
252static 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 */
202static int sport_startup(struct uart_port *port) 259static 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
286static 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
292static void sport_set_mctrl(struct uart_port *port, unsigned int mctrl)
293{
294 pr_debug("%s enter\n", __func__);
295}
296
297static void sport_stop_tx(struct uart_port *port) 358static 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
369static const char *sport_type(struct uart_port *port) 434static 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);