aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/serial/atmel_serial.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/tty/serial/atmel_serial.c')
-rw-r--r--drivers/tty/serial/atmel_serial.c49
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)