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 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)