summaryrefslogtreecommitdiff
path: root/drivers/tty/serial
diff options
context:
space:
mode:
authorMichael Spang <spang@chromium.org>2013-03-27 23:34:24 (GMT)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-03-28 23:04:19 (GMT)
commitd09a7308e9887a83abfd3176f4416d4142a265dc (patch)
tree383fc1796fc1179e2a742381bc4d9e98af13f8d8 /drivers/tty/serial
parentb6ad29355560beef6d127c6d33fb10ec0113bd85 (diff)
downloadlinux-fsl-qoriq-d09a7308e9887a83abfd3176f4416d4142a265dc.tar.xz
serial: samsung: Restore IRQ mask during noirq resume
This closes a window where the system may hang in resume as soon as the UART interrupt is enabled and before the mask is restored. The hang occurs because the driver can't handle IRQs it thinks are masked. Signed-off-by: Michael Spang <spang@chromium.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty/serial')
-rw-r--r--drivers/tty/serial/samsung.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c
index b386fc8..78d9c55 100644
--- a/drivers/tty/serial/samsung.c
+++ b/drivers/tty/serial/samsung.c
@@ -1311,9 +1311,29 @@ static int s3c24xx_serial_resume(struct device *dev)
return 0;
}
+static int s3c24xx_serial_resume_noirq(struct device *dev)
+{
+ struct uart_port *port = s3c24xx_dev_to_port(dev);
+
+ if (port) {
+ /* restore IRQ mask */
+ if (s3c24xx_serial_has_interrupt_mask(port)) {
+ unsigned int uintm = 0xf;
+ if (tx_enabled(port))
+ uintm &= ~S3C64XX_UINTM_TXD_MSK;
+ if (rx_enabled(port))
+ uintm &= ~S3C64XX_UINTM_RXD_MSK;
+ wr_regl(port, S3C64XX_UINTM, uintm);
+ }
+ }
+
+ return 0;
+}
+
static const struct dev_pm_ops s3c24xx_serial_pm_ops = {
.suspend = s3c24xx_serial_suspend,
.resume = s3c24xx_serial_resume,
+ .resume_noirq = s3c24xx_serial_resume_noirq,
};
#define SERIAL_SAMSUNG_PM_OPS (&s3c24xx_serial_pm_ops)