* [PATCH 1/1] Serial: imx: add dev_pm_ops to support suspend to ram/disk
@ 2015-07-17 20:30 Shenwei Wang
2015-07-22 18:11 ` Shenwei Wang
2015-07-24 0:37 ` Greg KH
0 siblings, 2 replies; 4+ messages in thread
From: Shenwei Wang @ 2015-07-17 20:30 UTC (permalink / raw)
To: gregkh; +Cc: linux-arm-kernel, linux-serial
When system goes into low power states like SUSPEND_MEM and
HIBERNATION, the hardware IP block may be powered off to reduce
the power consumption. This power down may cause problems on
some imx platforms, because the hardware settings are reset to
its power on default values which may differ from the ones when
it power off. This patch added the dev_pm_ops and implemented
two callbacks: suspend_noirq and resume_noirq, which will save
the necessory hardware parameters right before power down and
recover them before system uses the hardware.
Signed-off-by: Shenwei Wang <shenwei.wang@freescale.com>
---
drivers/tty/serial/imx.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 54 insertions(+)
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index c8cfa06..acaaa68 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -216,6 +216,7 @@ struct imx_port {
unsigned int tx_bytes;
unsigned int dma_tx_nents;
wait_queue_head_t dma_wait;
+ unsigned int saved_reg[10];
};
struct imx_port_ucrs {
@@ -1986,6 +1987,58 @@ static int serial_imx_remove(struct platform_device *pdev)
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);
+
+ /* Save necessary regs */
+ clk_enable(sport->clk_ipg);
+ 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);
+
+ pr_debug("0x%p (%d)\r\n", sport->port.membase, sport->port.line);
+
+ 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);
+
+ clk_enable(sport->clk_ipg);
+ 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] | 0x1, 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);
+
+ pr_debug("0x%p (%d)\r\n", sport->port.membase, sport->port.line);
+
+ 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,
+};
+
static struct platform_driver serial_imx_driver = {
.probe = serial_imx_probe,
.remove = serial_imx_remove,
@@ -1996,6 +2049,7 @@ static struct platform_driver serial_imx_driver = {
.driver = {
.name = "imx-uart",
.of_match_table = imx_uart_dt_ids,
+ .pm = &imx_serial_port_pm_ops,
},
};
--
2.5.0.rc2
^ permalink raw reply related [flat|nested] 4+ messages in thread
* RE: [PATCH 1/1] Serial: imx: add dev_pm_ops to support suspend to ram/disk
2015-07-17 20:30 [PATCH 1/1] Serial: imx: add dev_pm_ops to support suspend to ram/disk Shenwei Wang
@ 2015-07-22 18:11 ` Shenwei Wang
2015-07-24 0:37 ` Greg KH
1 sibling, 0 replies; 4+ messages in thread
From: Shenwei Wang @ 2015-07-22 18:11 UTC (permalink / raw)
To: gregkh@linuxfoundation.org
Cc: linux-serial@vger.kernel.org,
linux-arm-kernel@lists.infradead.org
Kind PING.
> -----Original Message-----
> From: linux-arm-kernel [mailto:linux-arm-kernel-bounces@lists.infradead.org] On
> Behalf Of Shenwei Wang
> Sent: 2015年7月17日 15:30
> To: gregkh@linuxfoundation.org
> Cc: linux-arm-kernel@lists.infradead.org; linux-serial@vger.kernel.org
> Subject: [PATCH 1/1] Serial: imx: add dev_pm_ops to support suspend to ram/disk
>
> When system goes into low power states like SUSPEND_MEM and HIBERNATION,
> the hardware IP block may be powered off to reduce the power consumption.
> This power down may cause problems on some imx platforms, because the
> hardware settings are reset to its power on default values which may differ from
> the ones when it power off. This patch added the dev_pm_ops and implemented
> two callbacks: suspend_noirq and resume_noirq, which will save the necessory
> hardware parameters right before power down and recover them before system
> uses the hardware.
>
> Signed-off-by: Shenwei Wang <shenwei.wang@freescale.com>
> ---
> drivers/tty/serial/imx.c | 54
> ++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 54 insertions(+)
>
> diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index
> c8cfa06..acaaa68 100644
> --- a/drivers/tty/serial/imx.c
> +++ b/drivers/tty/serial/imx.c
> @@ -216,6 +216,7 @@ struct imx_port {
> unsigned int tx_bytes;
> unsigned int dma_tx_nents;
> wait_queue_head_t dma_wait;
> + unsigned int saved_reg[10];
> };
>
> struct imx_port_ucrs {
> @@ -1986,6 +1987,58 @@ static int serial_imx_remove(struct platform_device
> *pdev)
> 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);
> +
> + /* Save necessary regs */
> + clk_enable(sport->clk_ipg);
> + 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);
> +
> + pr_debug("0x%p (%d)\r\n", sport->port.membase, sport->port.line);
> +
> + 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);
> +
> + clk_enable(sport->clk_ipg);
> + 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] | 0x1, 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);
> +
> + pr_debug("0x%p (%d)\r\n", sport->port.membase, sport->port.line);
> +
> + 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, };
> +
> static struct platform_driver serial_imx_driver = {
> .probe = serial_imx_probe,
> .remove = serial_imx_remove,
> @@ -1996,6 +2049,7 @@ static struct platform_driver serial_imx_driver = {
> .driver = {
> .name = "imx-uart",
> .of_match_table = imx_uart_dt_ids,
> + .pm = &imx_serial_port_pm_ops,
> },
> };
>
> --
> 2.5.0.rc2
>
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH 1/1] Serial: imx: add dev_pm_ops to support suspend to ram/disk
2015-07-17 20:30 [PATCH 1/1] Serial: imx: add dev_pm_ops to support suspend to ram/disk Shenwei Wang
2015-07-22 18:11 ` Shenwei Wang
@ 2015-07-24 0:37 ` Greg KH
2015-07-24 17:16 ` Shenwei Wang
1 sibling, 1 reply; 4+ messages in thread
From: Greg KH @ 2015-07-24 0:37 UTC (permalink / raw)
To: Shenwei Wang; +Cc: linux-arm-kernel, linux-serial
On Fri, Jul 17, 2015 at 03:30:18PM -0500, Shenwei Wang wrote:
> When system goes into low power states like SUSPEND_MEM and
> HIBERNATION, the hardware IP block may be powered off to reduce
> the power consumption. This power down may cause problems on
> some imx platforms, because the hardware settings are reset to
> its power on default values which may differ from the ones when
> it power off. This patch added the dev_pm_ops and implemented
> two callbacks: suspend_noirq and resume_noirq, which will save
> the necessory hardware parameters right before power down and
> recover them before system uses the hardware.
>
> Signed-off-by: Shenwei Wang <shenwei.wang@freescale.com>
> ---
> drivers/tty/serial/imx.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 54 insertions(+)
>
> diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
> index c8cfa06..acaaa68 100644
> --- a/drivers/tty/serial/imx.c
> +++ b/drivers/tty/serial/imx.c
> @@ -216,6 +216,7 @@ struct imx_port {
> unsigned int tx_bytes;
> unsigned int dma_tx_nents;
> wait_queue_head_t dma_wait;
> + unsigned int saved_reg[10];
> };
>
> struct imx_port_ucrs {
> @@ -1986,6 +1987,58 @@ static int serial_imx_remove(struct platform_device *pdev)
> 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);
> +
> + /* Save necessary regs */
> + clk_enable(sport->clk_ipg);
> + 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);
> +
> + pr_debug("0x%p (%d)\r\n", sport->port.membase, sport->port.line);
You have a struct device, please use dev_dbg() instead.
> +
> + 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);
> +
> + clk_enable(sport->clk_ipg);
> + 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] | 0x1, 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);
> +
> + pr_debug("0x%p (%d)\r\n", sport->port.membase, sport->port.line);
Same here, please use dev_dbg()
^ permalink raw reply [flat|nested] 4+ messages in thread
* RE: [PATCH 1/1] Serial: imx: add dev_pm_ops to support suspend to ram/disk
2015-07-24 0:37 ` Greg KH
@ 2015-07-24 17:16 ` Shenwei Wang
0 siblings, 0 replies; 4+ messages in thread
From: Shenwei Wang @ 2015-07-24 17:16 UTC (permalink / raw)
To: Greg KH; +Cc: linux-arm-kernel@lists.infradead.org,
linux-serial@vger.kernel.org
> -----Original Message-----
> From: Greg KH [mailto:gregkh@linuxfoundation.org]
> Sent: 2015年7月23日 19:37
> To: Wang Shenwei-B38339
> Cc: linux-serial@vger.kernel.org; linux-arm-kernel@lists.infradead.org
> Subject: Re: [PATCH 1/1] Serial: imx: add dev_pm_ops to support suspend to
> ram/disk
> > + 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);
> > +
> > + pr_debug("0x%p (%d)\r\n", sport->port.membase, sport->port.line);
>
> You have a struct device, please use dev_dbg() instead.
Adopted in PATCH v2.
>
> > +
> > + return 0;
> > +}
> > +
> > + writel(sport->saved_reg[2], sport->port.membase + UCR3);
> > + writel(sport->saved_reg[3], sport->port.membase + UCR4);
> > + clk_disable(sport->clk_ipg);
> > +
> > + pr_debug("0x%p (%d)\r\n", sport->port.membase, sport->port.line);
>
> Same here, please use dev_dbg()
Adopted in PATCH v2.
Thanks,
Shenwei
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2015-07-24 17:16 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-07-17 20:30 [PATCH 1/1] Serial: imx: add dev_pm_ops to support suspend to ram/disk Shenwei Wang
2015-07-22 18:11 ` Shenwei Wang
2015-07-24 0:37 ` Greg KH
2015-07-24 17:16 ` Shenwei Wang
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).