Commit d09a7308 authored by Michael Spang's avatar Michael Spang Committed by Greg Kroah-Hartman

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: default avatarMichael Spang <spang@chromium.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent b6ad2935
...@@ -1311,9 +1311,29 @@ static int s3c24xx_serial_resume(struct device *dev) ...@@ -1311,9 +1311,29 @@ static int s3c24xx_serial_resume(struct device *dev)
return 0; 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 = { static const struct dev_pm_ops s3c24xx_serial_pm_ops = {
.suspend = s3c24xx_serial_suspend, .suspend = s3c24xx_serial_suspend,
.resume = s3c24xx_serial_resume, .resume = s3c24xx_serial_resume,
.resume_noirq = s3c24xx_serial_resume_noirq,
}; };
#define SERIAL_SAMSUNG_PM_OPS (&s3c24xx_serial_pm_ops) #define SERIAL_SAMSUNG_PM_OPS (&s3c24xx_serial_pm_ops)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment