|
@@ -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;
|