diff options
Diffstat (limited to 'drivers/tty/serial/atmel_serial.c')
-rw-r--r-- | drivers/tty/serial/atmel_serial.c | 49 |
1 files changed, 31 insertions, 18 deletions
diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index a49f10d269b2..91c0d8839570 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c | |||
@@ -35,21 +35,18 @@ | |||
35 | #include <linux/platform_device.h> | 35 | #include <linux/platform_device.h> |
36 | #include <linux/of.h> | 36 | #include <linux/of.h> |
37 | #include <linux/of_device.h> | 37 | #include <linux/of_device.h> |
38 | #include <linux/of_gpio.h> | ||
38 | #include <linux/dma-mapping.h> | 39 | #include <linux/dma-mapping.h> |
39 | #include <linux/atmel_pdc.h> | 40 | #include <linux/atmel_pdc.h> |
40 | #include <linux/atmel_serial.h> | 41 | #include <linux/atmel_serial.h> |
41 | #include <linux/uaccess.h> | 42 | #include <linux/uaccess.h> |
42 | #include <linux/platform_data/atmel.h> | 43 | #include <linux/platform_data/atmel.h> |
43 | #include <linux/timer.h> | 44 | #include <linux/timer.h> |
45 | #include <linux/gpio.h> | ||
44 | 46 | ||
45 | #include <asm/io.h> | 47 | #include <asm/io.h> |
46 | #include <asm/ioctls.h> | 48 | #include <asm/ioctls.h> |
47 | 49 | ||
48 | #ifdef CONFIG_ARM | ||
49 | #include <mach/cpu.h> | ||
50 | #include <asm/gpio.h> | ||
51 | #endif | ||
52 | |||
53 | #define PDC_BUFFER_SIZE 512 | 50 | #define PDC_BUFFER_SIZE 512 |
54 | /* Revisit: We should calculate this based on the actual port settings */ | 51 | /* Revisit: We should calculate this based on the actual port settings */ |
55 | #define PDC_RX_TIMEOUT (3 * 10) /* 3 bytes */ | 52 | #define PDC_RX_TIMEOUT (3 * 10) /* 3 bytes */ |
@@ -168,6 +165,7 @@ struct atmel_uart_port { | |||
168 | struct circ_buf rx_ring; | 165 | struct circ_buf rx_ring; |
169 | 166 | ||
170 | struct serial_rs485 rs485; /* rs485 settings */ | 167 | struct serial_rs485 rs485; /* rs485 settings */ |
168 | int rts_gpio; /* optional RTS GPIO */ | ||
171 | unsigned int tx_done_mask; | 169 | unsigned int tx_done_mask; |
172 | bool is_usart; /* usart or uart */ | 170 | bool is_usart; /* usart or uart */ |
173 | struct timer_list uart_timer; /* uart timer */ | 171 | struct timer_list uart_timer; /* uart timer */ |
@@ -301,20 +299,16 @@ static void atmel_set_mctrl(struct uart_port *port, u_int mctrl) | |||
301 | unsigned int mode; | 299 | unsigned int mode; |
302 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); | 300 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); |
303 | 301 | ||
304 | #ifdef CONFIG_ARCH_AT91RM9200 | 302 | /* |
305 | if (cpu_is_at91rm9200()) { | 303 | * AT91RM9200 Errata #39: RTS0 is not internally connected |
306 | /* | 304 | * to PA21. We need to drive the pin as a GPIO. |
307 | * AT91RM9200 Errata #39: RTS0 is not internally connected | 305 | */ |
308 | * to PA21. We need to drive the pin manually. | 306 | if (gpio_is_valid(atmel_port->rts_gpio)) { |
309 | */ | 307 | if (mctrl & TIOCM_RTS) |
310 | if (port->mapbase == AT91RM9200_BASE_US0) { | 308 | gpio_set_value(atmel_port->rts_gpio, 0); |
311 | if (mctrl & TIOCM_RTS) | 309 | else |
312 | at91_set_gpio_value(AT91_PIN_PA21, 0); | 310 | gpio_set_value(atmel_port->rts_gpio, 1); |
313 | else | ||
314 | at91_set_gpio_value(AT91_PIN_PA21, 1); | ||
315 | } | ||
316 | } | 311 | } |
317 | #endif | ||
318 | 312 | ||
319 | if (mctrl & TIOCM_RTS) | 313 | if (mctrl & TIOCM_RTS) |
320 | control |= ATMEL_US_RTSEN; | 314 | control |= ATMEL_US_RTSEN; |
@@ -2389,6 +2383,25 @@ static int atmel_serial_probe(struct platform_device *pdev) | |||
2389 | port = &atmel_ports[ret]; | 2383 | port = &atmel_ports[ret]; |
2390 | port->backup_imr = 0; | 2384 | port->backup_imr = 0; |
2391 | port->uart.line = ret; | 2385 | port->uart.line = ret; |
2386 | port->rts_gpio = -EINVAL; /* Invalid, zero could be valid */ | ||
2387 | if (pdata) | ||
2388 | port->rts_gpio = pdata->rts_gpio; | ||
2389 | else if (np) | ||
2390 | port->rts_gpio = of_get_named_gpio(np, "rts-gpios", 0); | ||
2391 | |||
2392 | if (gpio_is_valid(port->rts_gpio)) { | ||
2393 | ret = devm_gpio_request(&pdev->dev, port->rts_gpio, "RTS"); | ||
2394 | if (ret) { | ||
2395 | dev_err(&pdev->dev, "error requesting RTS GPIO\n"); | ||
2396 | goto err; | ||
2397 | } | ||
2398 | /* Default to 1 as RTS is active low */ | ||
2399 | ret = gpio_direction_output(port->rts_gpio, 1); | ||
2400 | if (ret) { | ||
2401 | dev_err(&pdev->dev, "error setting up RTS GPIO\n"); | ||
2402 | goto err; | ||
2403 | } | ||
2404 | } | ||
2392 | 2405 | ||
2393 | ret = atmel_init_port(port, pdev); | 2406 | ret = atmel_init_port(port, pdev); |
2394 | if (ret) | 2407 | if (ret) |