|
@@ -216,6 +216,7 @@ struct imx_port {
|
|
unsigned int tx_bytes;
|
|
unsigned int tx_bytes;
|
|
unsigned int dma_tx_nents;
|
|
unsigned int dma_tx_nents;
|
|
wait_queue_head_t dma_wait;
|
|
wait_queue_head_t dma_wait;
|
|
|
|
+ unsigned int saved_reg[10];
|
|
};
|
|
};
|
|
|
|
|
|
struct imx_port_ucrs {
|
|
struct imx_port_ucrs {
|
|
@@ -1815,36 +1816,6 @@ static struct uart_driver imx_reg = {
|
|
.cons = IMX_CONSOLE,
|
|
.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
|
|
#ifdef CONFIG_OF
|
|
/*
|
|
/*
|
|
* This function returns 1 iff pdev isn't a device instatiated by dt, 0 iff it
|
|
* This function returns 1 iff pdev isn't a device instatiated by dt, 0 iff it
|
|
@@ -2009,16 +1980,107 @@ static int serial_imx_remove(struct platform_device *pdev)
|
|
return uart_remove_one_port(&imx_reg, &sport->port);
|
|
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 = {
|
|
static struct platform_driver serial_imx_driver = {
|
|
.probe = serial_imx_probe,
|
|
.probe = serial_imx_probe,
|
|
.remove = serial_imx_remove,
|
|
.remove = serial_imx_remove,
|
|
|
|
|
|
- .suspend = serial_imx_suspend,
|
|
|
|
- .resume = serial_imx_resume,
|
|
|
|
.id_table = imx_uart_devtype,
|
|
.id_table = imx_uart_devtype,
|
|
.driver = {
|
|
.driver = {
|
|
.name = "imx-uart",
|
|
.name = "imx-uart",
|
|
.of_match_table = imx_uart_dt_ids,
|
|
.of_match_table = imx_uart_dt_ids,
|
|
|
|
+ .pm = &imx_serial_port_pm_ops,
|
|
},
|
|
},
|
|
};
|
|
};
|
|
|
|
|