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 d3cda0c..aa603f2 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; |