unsigned int            tx_bytes;
        unsigned int            dma_tx_nents;
        wait_queue_head_t       dma_wait;
+       unsigned int            saved_reg[10];
 };
 
 struct imx_port_ucrs {
        .cons           = IMX_CONSOLE,
 };
 
-static int serial_imx_suspend(struct platform_device *dev, pm_message_t state)
-{
-       struct imx_port *sport = platform_get_drvdata(dev);
-       unsigned int val;
-
-       /* enable wakeup from i.MX UART */
-       val = readl(sport->port.membase + UCR3);
-       val |= UCR3_AWAKEN;
-       writel(val, sport->port.membase + UCR3);
-
-       uart_suspend_port(&imx_reg, &sport->port);
-
-       return 0;
-}
-
-static int serial_imx_resume(struct platform_device *dev)
-{
-       struct imx_port *sport = platform_get_drvdata(dev);
-       unsigned int val;
-
-       /* disable wakeup from i.MX UART */
-       val = readl(sport->port.membase + UCR3);
-       val &= ~UCR3_AWAKEN;
-       writel(val, sport->port.membase + UCR3);
-
-       uart_resume_port(&imx_reg, &sport->port);
-
-       return 0;
-}
-
 #ifdef CONFIG_OF
 /*
  * This function returns 1 iff pdev isn't a device instatiated by dt, 0 iff it
        return uart_remove_one_port(&imx_reg, &sport->port);
 }
 
+static int imx_serial_port_suspend_noirq(struct device *dev)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+       struct imx_port *sport = platform_get_drvdata(pdev);
+       int ret;
+
+       ret = clk_enable(sport->clk_ipg);
+       if (ret)
+               return ret;
+
+       /* Save necessary regs */
+       sport->saved_reg[0] = readl(sport->port.membase + UCR1);
+       sport->saved_reg[1] = readl(sport->port.membase + UCR2);
+       sport->saved_reg[2] = readl(sport->port.membase + UCR3);
+       sport->saved_reg[3] = readl(sport->port.membase + UCR4);
+       sport->saved_reg[4] = readl(sport->port.membase + UFCR);
+       sport->saved_reg[5] = readl(sport->port.membase + UESC);
+       sport->saved_reg[6] = readl(sport->port.membase + UTIM);
+       sport->saved_reg[7] = readl(sport->port.membase + UBIR);
+       sport->saved_reg[8] = readl(sport->port.membase + UBMR);
+       sport->saved_reg[9] = readl(sport->port.membase + IMX21_UTS);
+
+       clk_disable(sport->clk_ipg);
+
+       return 0;
+}
+
+static int imx_serial_port_resume_noirq(struct device *dev)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+       struct imx_port *sport = platform_get_drvdata(pdev);
+       int ret;
+
+       ret = clk_enable(sport->clk_ipg);
+       if (ret)
+               return ret;
+
+       writel(sport->saved_reg[4], sport->port.membase + UFCR);
+       writel(sport->saved_reg[5], sport->port.membase + UESC);
+       writel(sport->saved_reg[6], sport->port.membase + UTIM);
+       writel(sport->saved_reg[7], sport->port.membase + UBIR);
+       writel(sport->saved_reg[8], sport->port.membase + UBMR);
+       writel(sport->saved_reg[9], sport->port.membase + IMX21_UTS);
+       writel(sport->saved_reg[0], sport->port.membase + UCR1);
+       writel(sport->saved_reg[1] | UCR2_SRST, sport->port.membase + UCR2);
+       writel(sport->saved_reg[2], sport->port.membase + UCR3);
+       writel(sport->saved_reg[3], sport->port.membase + UCR4);
+
+       clk_disable(sport->clk_ipg);
+
+       return 0;
+}
+
+static int imx_serial_port_suspend(struct device *dev)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+       struct imx_port *sport = platform_get_drvdata(pdev);
+       unsigned int val;
+
+       /* enable wakeup from i.MX UART */
+       val = readl(sport->port.membase + UCR3);
+       val |= UCR3_AWAKEN;
+       writel(val, sport->port.membase + UCR3);
+
+       uart_suspend_port(&imx_reg, &sport->port);
+
+       return 0;
+}
+
+static int imx_serial_port_resume(struct device *dev)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+       struct imx_port *sport = platform_get_drvdata(pdev);
+       unsigned int val;
+
+       /* disable wakeup from i.MX UART */
+       val = readl(sport->port.membase + UCR3);
+       val &= ~UCR3_AWAKEN;
+       writel(val, sport->port.membase + UCR3);
+
+       uart_resume_port(&imx_reg, &sport->port);
+
+       return 0;
+}
+
+static const struct dev_pm_ops imx_serial_port_pm_ops = {
+       .suspend_noirq = imx_serial_port_suspend_noirq,
+       .resume_noirq = imx_serial_port_resume_noirq,
+       .suspend = imx_serial_port_suspend,
+       .resume = imx_serial_port_resume,
+};
+
 static struct platform_driver serial_imx_driver = {
        .probe          = serial_imx_probe,
        .remove         = serial_imx_remove,
 
-       .suspend        = serial_imx_suspend,
-       .resume         = serial_imx_resume,
        .id_table       = imx_uart_devtype,
        .driver         = {
                .name   = "imx-uart",
                .of_match_table = imx_uart_dt_ids,
+               .pm     = &imx_serial_port_pm_ops,
        },
 };