Commit ed68411e authored by Markus Schneider-Pargmann's avatar Markus Schneider-Pargmann Committed by Greg Kroah-Hartman
Browse files

serial: 8250: omap: Support wakeup pinctrl state on suspend



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: default avatarMarkus Schneider-Pargmann <msp@baylibre.com>
Signed-off-by: default avatarKendall Willis <k-willis@ti.com>
Link: https://lore.kernel.org/r/20250910-uart-daisy-chain-8250-omap-v2-2-e90d44c1a9ac@ti.com


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 49fce073
Loading
Loading
Loading
Loading
+36 −0
Original line number Diff line number Diff line
@@ -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)