linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Martin Kaiser <martin@kaiser.cx>
To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Fabio Estevam <festevam@gmail.com>,
	Sascha Hauer <kernel@pengutronix.de>,
	Jiri Slaby <jslaby@suse.com>,
	Philipp Zabel <p.zabel@pengutronix.de>
Cc: Shawn Guo <shawnguo@kernel.org>,
	linux-kernel <linux-kernel@vger.kernel.org>,
	linux-serial@vger.kernel.org, Martin Kaiser <martin@kaiser.cx>
Subject: [PATCH v2] serial: imx: fix endless loop during suspend
Date: Fri,  5 Jan 2018 17:46:43 +0100	[thread overview]
Message-ID: <1515170803-31662-1-git-send-email-martin@kaiser.cx> (raw)
In-Reply-To: <1514395632-15390-1-git-send-email-martin@kaiser.cx>

Before we go into suspend mode, we enable the imx uart's interrupt for
the awake bit in the UART Status Register 1. If, for some reason, the
awake bit is already set before we enter suspend mode, we get an
interrupt immediately when we enable interrupts for awake. The uart's
clk_ipg is disabled at this point (unless there's an ongoing transfer).
We end up in the interrupt handler, which usually tries to clear the
awake bit. This doesn't work with the clock disabled. Therefore, we
keep getting interrupts forever, resulting in an endless loop.

Clear the awake bit before setting the awaken bit to signal that we want
an imx interrupt when the awake bit will be set. This ensures that we're
not woken up by events that happened before we started going into
suspend mode.

Change the clock handling so that suspend prepares and enables the clock
and suspend_noirq disables it. Revert these operations in resume_noirq and
resume.

With these preparations in place, we can now modify awake and awaken in
the suspend function when the actual imx interrupt is disabled and the
required clk_ipg is active.

Update the thaw and freeze functions to use the new clock handling since
we share the suspend_noirq function between suspend and hibernate.

Signed-off-by: Martin Kaiser <martin@kaiser.cx>
---
changes in v2
 call serial_imx_enable_wakeup() in suspend, not in suspend_noirq
 keep the clock enalbed between suspend and suspend_noirq and
  between resume_noirq and resume

Hi Fabio and all,

here's a different approach for fixing the awake issue that I see on my
board. I tried to stick as much as possible to the original order in
which the operations were done. Could you do a quick check on imx6q?

Thanks,
   Martin

 drivers/tty/serial/imx.c | 32 +++++++++++++++-----------------
 1 file changed, 15 insertions(+), 17 deletions(-)

diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index 145ed61..e5d5250 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -2221,8 +2221,10 @@ static void serial_imx_enable_wakeup(struct imx_port *sport, bool on)
 	unsigned int val;
 
 	val = readl(sport->port.membase + UCR3);
-	if (on)
+	if (on) {
+		writel(USR1_AWAKE, sport->port.membase + USR1);
 		val |= UCR3_AWAKEN;
+	}
 	else
 		val &= ~UCR3_AWAKEN;
 	writel(val, sport->port.membase + UCR3);
@@ -2239,11 +2241,6 @@ 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;
 
 	serial_imx_save_context(sport);
 
@@ -2264,8 +2261,6 @@ static int imx_serial_port_resume_noirq(struct device *dev)
 
 	serial_imx_restore_context(sport);
 
-	clk_disable(sport->clk_ipg);
-
 	return 0;
 }
 
@@ -2273,15 +2268,19 @@ 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);
-
-	/* enable wakeup from i.MX UART */
-	serial_imx_enable_wakeup(sport, true);
+	int ret;
 
 	uart_suspend_port(&imx_reg, &sport->port);
 	disable_irq(sport->port.irq);
 
-	/* Needed to enable clock in suspend_noirq */
-	return clk_prepare(sport->clk_ipg);
+	ret = clk_prepare_enable(sport->clk_ipg);
+	if (ret)
+		return ret;
+
+	/* enable wakeup from i.MX UART */
+	serial_imx_enable_wakeup(sport, true);
+
+	return 0;
 }
 
 static int imx_serial_port_resume(struct device *dev)
@@ -2295,7 +2294,7 @@ static int imx_serial_port_resume(struct device *dev)
 	uart_resume_port(&imx_reg, &sport->port);
 	enable_irq(sport->port.irq);
 
-	clk_unprepare(sport->clk_ipg);
+	clk_disable_unprepare(sport->clk_ipg);
 
 	return 0;
 }
@@ -2307,8 +2306,7 @@ static int imx_serial_port_freeze(struct device *dev)
 
 	uart_suspend_port(&imx_reg, &sport->port);
 
-	/* Needed to enable clock in suspend_noirq */
-	return clk_prepare(sport->clk_ipg);
+	return clk_prepare_enable(sport->clk_ipg);
 }
 
 static int imx_serial_port_thaw(struct device *dev)
@@ -2318,7 +2316,7 @@ static int imx_serial_port_thaw(struct device *dev)
 
 	uart_resume_port(&imx_reg, &sport->port);
 
-	clk_unprepare(sport->clk_ipg);
+	clk_disable_unprepare(sport->clk_ipg);
 
 	return 0;
 }
-- 
2.1.4

  parent reply	other threads:[~2018-01-05 16:49 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-12-27 17:27 [PATCH 1/2] serial: imx: edd a .freeze_noirq function Martin Kaiser
2017-12-27 17:27 ` [PATCH 2/2] serial: imx: fix endless loop during suspend Martin Kaiser
2017-12-31 11:53   ` Fabio Estevam
2018-01-02 16:15     ` Martin Kaiser
2018-01-02 19:31       ` Fabio Estevam
2018-01-03 16:20       ` Fabio Estevam
2018-01-03 21:43         ` Martin Kaiser
2018-01-05 16:46 ` Martin Kaiser [this message]
2018-01-05 17:31   ` [PATCH v2] " Fabio Estevam

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1515170803-31662-1-git-send-email-martin@kaiser.cx \
    --to=martin@kaiser.cx \
    --cc=festevam@gmail.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=jslaby@suse.com \
    --cc=kernel@pengutronix.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-serial@vger.kernel.org \
    --cc=p.zabel@pengutronix.de \
    --cc=shawnguo@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).