diff options
Diffstat (limited to 'drivers/tty/serial/omap-serial.c')
| -rw-r--r-- | drivers/tty/serial/omap-serial.c | 35 | 
1 files changed, 34 insertions, 1 deletions
diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index d3cda0cb2df..aa603f221c6 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -39,6 +39,7 @@  #include <linux/irq.h>  #include <linux/pm_runtime.h>  #include <linux/of.h> +#include <linux/gpio.h>  #include <plat/dma.h>  #include <plat/dmtimer.h> @@ -507,6 +508,16 @@ static void serial_omap_set_mctrl(struct uart_port *port, unsigned int mctrl)  	up->mcr |= mcr;  	serial_out(up, UART_MCR, up->mcr);  	pm_runtime_put(&up->pdev->dev); + +	if (gpio_is_valid(up->DTR_gpio) && +	    !!(mctrl & TIOCM_DTR) != up->DTR_active) { +		up->DTR_active = !up->DTR_active; +		if (gpio_cansleep(up->DTR_gpio)) +			schedule_work(&up->qos_work); +		else +			gpio_set_value(up->DTR_gpio, +				       up->DTR_active != up->DTR_inverted); +	}  }  static void serial_omap_break_ctl(struct uart_port *port, int break_state) @@ -715,6 +726,9 @@ static void serial_omap_uart_qos_work(struct work_struct *work)  						qos_work);  	pm_qos_update_request(&up->pm_qos_request, up->latency); +	if (gpio_is_valid(up->DTR_gpio)) +		gpio_set_value_cansleep(up->DTR_gpio, +					up->DTR_active != up->DTR_inverted);  }  static void @@ -1435,7 +1449,7 @@ static int serial_omap_probe(struct platform_device *pdev)  	struct uart_omap_port	*up;  	struct resource		*mem, *irq, *dma_tx, *dma_rx;  	struct omap_uart_port_info *omap_up_info = pdev->dev.platform_data; -	int ret = -ENOSPC; +	int ret;  	if (pdev->dev.of_node)  		omap_up_info = of_get_uart_port_info(&pdev->dev); @@ -1466,10 +1480,29 @@ static int serial_omap_probe(struct platform_device *pdev)  	if (!dma_tx)  		return -ENXIO; +	if (gpio_is_valid(omap_up_info->DTR_gpio) && +	    omap_up_info->DTR_present) { +		ret = gpio_request(omap_up_info->DTR_gpio, "omap-serial"); +		if (ret < 0) +			return ret; +		ret = gpio_direction_output(omap_up_info->DTR_gpio, +					    omap_up_info->DTR_inverted); +		if (ret < 0) +			return ret; +	} +  	up = devm_kzalloc(&pdev->dev, sizeof(*up), GFP_KERNEL);  	if (!up)  		return -ENOMEM; +	if (gpio_is_valid(omap_up_info->DTR_gpio) && +	    omap_up_info->DTR_present) { +		up->DTR_gpio = omap_up_info->DTR_gpio; +		up->DTR_inverted = omap_up_info->DTR_inverted; +	} else +		up->DTR_gpio = -EINVAL; +	up->DTR_active = 0; +  	up->pdev = pdev;  	up->port.dev = &pdev->dev;  	up->port.type = PORT_OMAP;  |