summaryrefslogtreecommitdiff
path: root/drivers/tty
diff options
context:
space:
mode:
authorYuan Yao <yao.yuan@freescale.com>2015-01-23 09:16:24 (GMT)
committerZhengxiong Jin <Jason.Jin@freescale.com>2015-02-05 08:23:30 (GMT)
commitfe1c3f4aed0bdde6a6c6855ad3638995e0b3f0ab (patch)
treeff6dcdc0b36ab8ea8b3b0a609ad16bc513904ece /drivers/tty
parent425d2732e9617965fd1cded565ac16f923ef9873 (diff)
downloadlinux-fsl-qoriq-fe1c3f4aed0bdde6a6c6855ad3638995e0b3f0ab.tar.xz
serial: fsl-lpuart: disable interrupt when suspend
For power management support, we should disable TX and TX interrupt so that kernel can prepare for deep sleep. Retain RX and RX interrupt for wakeup the kernel when receive the input character. Signed-off-by: Yuan Yao <yao.yuan@freescale.com> Change-Id: I5fd917c5c68da9a2ba16c3d1237f3f38e343539d Reviewed-on: http://git.am.freescale.net:8181/28842 Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com> Reviewed-by: Zhengxiong Jin <Jason.Jin@freescale.com>
Diffstat (limited to 'drivers/tty')
-rw-r--r--drivers/tty/serial/fsl_lpuart.c27
1 files changed, 25 insertions, 2 deletions
diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
index 1c5d020..3e5958a 100644
--- a/drivers/tty/serial/fsl_lpuart.c
+++ b/drivers/tty/serial/fsl_lpuart.c
@@ -721,8 +721,8 @@ static int lpuart_startup(struct uart_port *port)
unsigned long flags;
unsigned char temp;
- ret = devm_request_irq(port->dev, port->irq, lpuart_int, 0,
- DRIVER_NAME, sport);
+ ret = devm_request_irq(port->dev, port->irq, lpuart_int,
+ IRQF_NO_SUSPEND, DRIVER_NAME, sport);
if (ret)
return ret;
@@ -1431,6 +1431,12 @@ static int lpuart_probe(struct platform_device *pdev)
return ret;
}
+ /*
+ * Make device's PM flags reflect the wake-up capability, but
+ * let the user space enable it to wake up the system as needed.
+ */
+ device_set_wakeup_capable(&pdev->dev, true);
+
return 0;
}
@@ -1449,6 +1455,23 @@ static int lpuart_remove(struct platform_device *pdev)
static int lpuart_suspend(struct device *dev)
{
struct lpuart_port *sport = dev_get_drvdata(dev);
+ unsigned long temp;
+
+ if (sport->lpuart32) {
+ /* disable Rx/Tx and interrupts */
+ temp = lpuart32_read(sport->port.membase + UARTCTRL);
+ temp &= ~(UARTCTRL_TE | UARTCTRL_TIE | UARTCTRL_TCIE);
+ if (!device_may_wakeup(dev))
+ temp &= ~(UARTCTRL_RIE | UARTCTRL_RE);
+ lpuart32_write(temp, sport->port.membase + UARTCTRL);
+ } else {
+ /* disable Rx/Tx and interrupts */
+ temp = readb(sport->port.membase + UARTCR2);
+ temp &= ~(UARTCR2_TE | UARTCR2_TIE | UARTCR2_TCIE);
+ if (!device_may_wakeup(dev))
+ temp &= ~(UARTCR2_RIE | UARTCR2_RE);
+ writeb(temp, sport->port.membase + UARTCR2);
+ }
uart_suspend_port(&lpuart_reg, &sport->port);