From 62d96185bd5faccf0fb45ccae5057b81c5eb6584 Mon Sep 17 00:00:00 2001 From: Huibin Hong Date: Tue, 15 Jan 2019 19:46:01 +0800 Subject: [PATCH] serial: 8250_dw: uart wake up Add wakeup-source to uart dts node to enable uart wake up system when it receives data. Change-Id: If4e82a4d3dbaca708209553dc3693089864c782f Signed-off-by: Huibin Hong --- drivers/tty/serial/8250/8250_dw.c | 40 ++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c index a3a0154da567..88d866862f0b 100644 --- a/drivers/tty/serial/8250/8250_dw.c +++ b/drivers/tty/serial/8250/8250_dw.c @@ -49,6 +49,11 @@ struct dw8250_data { struct work_struct clk_work; struct reset_control *rst; +#ifdef CONFIG_ARCH_ROCKCHIP + int irq; + int irq_wake; + int enable_wakeup; +#endif unsigned int skip_autocfg:1; unsigned int uart_16550_compatible:1; }; @@ -480,6 +485,9 @@ static int dw8250_probe(struct platform_device *pdev) data->data.dma.fn = dw8250_fallback_dma_filter; data->usr_reg = DW_UART_USR; p->private_data = &data->data; +#ifdef CONFIG_ARCH_ROCKCHIP + data->irq = irq; +#endif data->uart_16550_compatible = device_property_read_bool(dev, "snps,uart-16550-compatible"); @@ -519,6 +527,13 @@ static int dw8250_probe(struct platform_device *pdev) data->msr_mask_off |= UART_MSR_TERI; } +#ifdef CONFIG_ARCH_ROCKCHIP + if (device_property_read_bool(p->dev, "wakeup-source")) + data->enable_wakeup = 1; + else + data->enable_wakeup = 0; +#endif + /* Always ask for fixed clock rate from a property. */ device_property_read_u32(dev, "clock-frequency", &p->uartclk); @@ -599,7 +614,10 @@ static int dw8250_probe(struct platform_device *pdev) else queue_work(system_unbound_wq, &data->clk_work); } - +#ifdef CONFIG_ARCH_ROCKCHIP + if (data->enable_wakeup) + device_init_wakeup(&pdev->dev, true); +#endif platform_set_drvdata(pdev, data); pm_runtime_set_active(dev); @@ -642,6 +660,10 @@ static int dw8250_remove(struct platform_device *pdev) pm_runtime_disable(dev); pm_runtime_put_noidle(dev); +#ifdef CONFIG_ARCH_ROCKCHIP + if (data->enable_wakeup) + device_init_wakeup(&pdev->dev, false); +#endif return 0; } @@ -652,6 +674,13 @@ static int dw8250_suspend(struct device *dev) struct dw8250_data *data = dev_get_drvdata(dev); serial8250_suspend_port(data->data.line); +#ifdef CONFIG_ARCH_ROCKCHIP + if (device_may_wakeup(dev)) { + if (!enable_irq_wake(data->irq)) + data->irq_wake = 1; + return 0; + } +#endif return 0; } @@ -661,6 +690,15 @@ static int dw8250_resume(struct device *dev) struct dw8250_data *data = dev_get_drvdata(dev); serial8250_resume_port(data->data.line); +#ifdef CONFIG_ARCH_ROCKCHIP + if (device_may_wakeup(dev)) { + if (data->irq_wake) { + disable_irq_wake(data->irq); + data->irq_wake = 0; + } + return 0; + } +#endif return 0; }