[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250904212455.3729029-4-k-willis@ti.com>
Date: Thu, 4 Sep 2025 16:24:55 -0500
From: Kendall Willis <k-willis@...com>
To: <gregkh@...uxfoundation.org>, <jirislaby@...nel.org>, <robh@...nel.org>,
<krzk+dt@...nel.org>, <conor+dt@...nel.org>, <vigneshr@...com>,
<linux-kernel@...r.kernel.org>, <linux-serial@...r.kernel.org>,
<devicetree@...r.kernel.org>
CC: <d-gole@...com>, <vishalm@...com>, <sebin.francis@...com>,
<msp@...libre.com>, <khilman@...libre.com>, <a-kaur@...com>,
<k-willis@...com>, <john.ogness@...utronix.de>,
<andriy.shevchenko@...ux.intel.com>, <yujiaoliang@...o.com>,
<b-liu@...com>, <u.kleine-koenig@...libre.com>
Subject: [PATCH 3/3] serial: 8250: omap: Support wakeup pinctrl state on suspend
From: Markus Schneider-Pargmann <msp@...libre.com>
UART can be used as a wakeup source for am62 from suspend to ram states.
To enable wakeup from UART am62 requires a wakeup flag being set in the
pinctrl.
If the device is marked as wakeup enabled, select the 'wakeup' pinctrl
state on suspend and restore the default pinctrl state on resume.
Signed-off-by: Markus Schneider-Pargmann <msp@...libre.com>
Signed-off-by: Kendall Willis <k-willis@...com>
---
drivers/tty/serial/8250/8250_omap.c | 36 +++++++++++++++++++++++++++++
1 file changed, 36 insertions(+)
diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c
index bb23afdd63f29..9e49ef48b851b 100644
--- a/drivers/tty/serial/8250/8250_omap.c
+++ b/drivers/tty/serial/8250/8250_omap.c
@@ -27,6 +27,8 @@
#include <linux/pm_wakeirq.h>
#include <linux/dma-mapping.h>
#include <linux/sys_soc.h>
+#include <linux/reboot.h>
+#include <linux/pinctrl/consumer.h>
#include "8250.h"
@@ -145,6 +147,9 @@ struct omap8250_priv {
spinlock_t rx_dma_lock;
bool rx_dma_broken;
bool throttled;
+
+ struct pinctrl *pinctrl;
+ struct pinctrl_state *pinctrl_wakeup;
};
struct omap8250_dma_params {
@@ -1349,6 +1354,18 @@ static int omap8250_no_handle_irq(struct uart_port *port)
return 0;
}
+static int omap8250_select_wakeup_pinctrl(struct device *dev,
+ struct omap8250_priv *priv)
+{
+ if (IS_ERR_OR_NULL(priv->pinctrl_wakeup))
+ return 0;
+
+ if (!device_may_wakeup(dev))
+ return 0;
+
+ return pinctrl_select_state(priv->pinctrl, priv->pinctrl_wakeup);
+}
+
static struct omap8250_dma_params am654_dma = {
.rx_size = SZ_2K,
.rx_trigger = 1,
@@ -1573,6 +1590,11 @@ static int omap8250_probe(struct platform_device *pdev)
priv->line = ret;
pm_runtime_mark_last_busy(&pdev->dev);
pm_runtime_put_autosuspend(&pdev->dev);
+
+ priv->pinctrl = devm_pinctrl_get(&pdev->dev);
+ if (!IS_ERR_OR_NULL(priv->pinctrl))
+ priv->pinctrl_wakeup = pinctrl_lookup_state(priv->pinctrl, "wakeup");
+
return 0;
err:
pm_runtime_dont_use_autosuspend(&pdev->dev);
@@ -1630,6 +1652,13 @@ static int omap8250_suspend(struct device *dev)
struct uart_8250_port *up = serial8250_get_port(priv->line);
int err = 0;
+ err = omap8250_select_wakeup_pinctrl(dev, priv);
+ if (err) {
+ dev_err(dev, "Failed to select wakeup pinctrl, aborting suspend %pe\n",
+ ERR_PTR(err));
+ return err;
+ }
+
serial8250_suspend_port(priv->line);
err = pm_runtime_resume_and_get(dev);
@@ -1651,6 +1680,13 @@ static int omap8250_resume(struct device *dev)
struct uart_8250_port *up = serial8250_get_port(priv->line);
int err;
+ err = pinctrl_select_default_state(dev);
+ if (err) {
+ dev_err(dev, "Failed to select default pinctrl state on resume: %pe\n",
+ ERR_PTR(err));
+ return err;
+ }
+
if (uart_console(&up->port) && console_suspend_enabled) {
err = pm_runtime_force_resume(dev);
if (err)
--
2.34.1
Powered by blists - more mailing lists