diff --git a/drivers/tty/serial/8250/8250_mtk.c b/drivers/tty/serial/8250/8250_mtk.c index f470dedceba96..b411ba4eb5e95 100644 --- a/drivers/tty/serial/8250/8250_mtk.c +++ b/drivers/tty/serial/8250/8250_mtk.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -69,6 +70,7 @@ struct mtk8250_data { #ifdef CONFIG_SERIAL_8250_DMA enum dma_rx_status rx_status; #endif + int rx_wakeup_irq; }; /* flow control mode */ @@ -542,6 +544,8 @@ static int mtk8250_probe(struct platform_device *pdev) pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev); + data->rx_wakeup_irq = platform_get_irq(pdev, 1); + return 0; } @@ -563,15 +567,35 @@ static int mtk8250_remove(struct platform_device *pdev) static int __maybe_unused mtk8250_suspend(struct device *dev) { struct mtk8250_data *data = dev_get_drvdata(dev); + int irq = data->rx_wakeup_irq; + int err; serial8250_suspend_port(data->line); + pinctrl_pm_select_sleep_state(dev); + if (irq >= 0) { + err = enable_irq_wake(irq); + if (err) { + dev_err(dev, + "failed to enable irq wake on IRQ %d: %d\n", + irq, err); + pinctrl_pm_select_default_state(dev); + serial8250_resume_port(data->line); + return err; + } + } + return 0; } static int __maybe_unused mtk8250_resume(struct device *dev) { struct mtk8250_data *data = dev_get_drvdata(dev); + int irq = data->rx_wakeup_irq; + + if (irq >= 0) + disable_irq_wake(irq); + pinctrl_pm_select_default_state(dev); serial8250_resume_port(data->line);