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 b0603e1f7d82..53eeea13ff16 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 */ |
@@ -165,6 +162,7 @@ struct atmel_uart_port { | |||
165 | struct circ_buf rx_ring; | 162 | struct circ_buf rx_ring; |
166 | 163 | ||
167 | struct serial_rs485 rs485; /* rs485 settings */ | 164 | struct serial_rs485 rs485; /* rs485 settings */ |
165 | int rts_gpio; /* optional RTS GPIO */ | ||
168 | unsigned int tx_done_mask; | 166 | unsigned int tx_done_mask; |
169 | bool is_usart; /* usart or uart */ | 167 | bool is_usart; /* usart or uart */ |
170 | struct timer_list uart_timer; /* uart timer */ | 168 | struct timer_list uart_timer; /* uart timer */ |
@@ -298,20 +296,16 @@ static void atmel_set_mctrl(struct uart_port *port, u_int mctrl) | |||
298 | unsigned int mode; | 296 | unsigned int mode; |
299 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); | 297 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); |
300 | 298 | ||
301 | #ifdef CONFIG_ARCH_AT91RM9200 | 299 | /* |
302 | if (cpu_is_at91rm9200()) { | 300 | * AT91RM9200 Errata #39: RTS0 is not internally connected |
303 | /* | 301 | * to PA21. We need to drive the pin as a GPIO. |
304 | * AT91RM9200 Errata #39: RTS0 is not internally connected | 302 | */ |
305 | * to PA21. We need to drive the pin manually. | 303 | if (gpio_is_valid(atmel_port->rts_gpio)) { |
306 | */ | 304 | if (mctrl & TIOCM_RTS) |
307 | if (port->mapbase == AT91RM9200_BASE_US0) { | 305 | gpio_set_value(atmel_port->rts_gpio, 0); |
308 | if (mctrl & TIOCM_RTS) | 306 | else |
309 | at91_set_gpio_value(AT91_PIN_PA21, 0); | 307 | gpio_set_value(atmel_port->rts_gpio, 1); |
310 | else | ||
311 | at91_set_gpio_value(AT91_PIN_PA21, 1); | ||
312 | } | ||
313 | } | 308 | } |
314 | #endif | ||
315 | 309 | ||
316 | if (mctrl & TIOCM_RTS) | 310 | if (mctrl & TIOCM_RTS) |
317 | control |= ATMEL_US_RTSEN; | 311 | control |= ATMEL_US_RTSEN; |
@@ -2365,6 +2359,25 @@ static int atmel_serial_probe(struct platform_device *pdev) | |||
2365 | port = &atmel_ports[ret]; | 2359 | port = &atmel_ports[ret]; |
2366 | port->backup_imr = 0; | 2360 | port->backup_imr = 0; |
2367 | port->uart.line = ret; | 2361 | port->uart.line = ret; |
2362 | port->rts_gpio = -EINVAL; /* Invalid, zero could be valid */ | ||
2363 | if (pdata) | ||
2364 | port->rts_gpio = pdata->rts_gpio; | ||
2365 | else if (np) | ||
2366 | port->rts_gpio = of_get_named_gpio(np, "rts-gpios", 0); | ||
2367 | |||
2368 | if (gpio_is_valid(port->rts_gpio)) { | ||
2369 | ret = devm_gpio_request(&pdev->dev, port->rts_gpio, "RTS"); | ||
2370 | if (ret) { | ||
2371 | dev_err(&pdev->dev, "error requesting RTS GPIO\n"); | ||
2372 | goto err; | ||
2373 | } | ||
2374 | /* Default to 1 as RTS is active low */ | ||
2375 | ret = gpio_direction_output(port->rts_gpio, 1); | ||
2376 | if (ret) { | ||
2377 | dev_err(&pdev->dev, "error setting up RTS GPIO\n"); | ||
2378 | goto err; | ||
2379 | } | ||
2380 | } | ||
2368 | 2381 | ||
2369 | ret = atmel_init_port(port, pdev); | 2382 | ret = atmel_init_port(port, pdev); |
2370 | if (ret) | 2383 | if (ret) |