serial: 8250_omap: Set the console genpd always on if no console suspend
authorThomas Richard <thomas.richard@bootlin.com>
Tue, 17 Oct 2023 13:05:40 +0000 (15:05 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 21 Oct 2023 16:34:34 +0000 (18:34 +0200)
If the console suspend is disabled, the genpd of the console shall not
be powered-off during suspend.
Set the flag GENPD_FLAG_ALWAYS_ON to the corresponding genpd during
suspend, and restore the original value during the resume.

Signed-off-by: Thomas Richard <thomas.richard@bootlin.com>
Link: https://lore.kernel.org/r/20231017130540.1149721-1-thomas.richard@bootlin.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/tty/serial/8250/8250_omap.c

index 4b33f4529aed1742f1a5c1f7f1b99845cf9f48a6..2d42f485c987669280c692b71be8b440fe1aa17f 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/pm_wakeirq.h>
 #include <linux/dma-mapping.h>
 #include <linux/sys_soc.h>
+#include <linux/pm_domain.h>
 
 #include "8250.h"
 
 /* RX FIFO occupancy indicator */
 #define UART_OMAP_RX_LVL               0x19
 
+/*
+ * Copy of the genpd flags for the console.
+ * Only used if console suspend is disabled
+ */
+static unsigned int genpd_flags_console;
+
 struct omap8250_priv {
        void __iomem *membase;
        int line;
@@ -1623,6 +1630,7 @@ static int omap8250_suspend(struct device *dev)
 {
        struct omap8250_priv *priv = dev_get_drvdata(dev);
        struct uart_8250_port *up = serial8250_get_port(priv->line);
+       struct generic_pm_domain *genpd = pd_to_genpd(dev->pm_domain);
        int err = 0;
 
        serial8250_suspend_port(priv->line);
@@ -1633,8 +1641,19 @@ static int omap8250_suspend(struct device *dev)
        if (!device_may_wakeup(dev))
                priv->wer = 0;
        serial_out(up, UART_OMAP_WER, priv->wer);
-       if (uart_console(&up->port) && console_suspend_enabled)
-               err = pm_runtime_force_suspend(dev);
+       if (uart_console(&up->port)) {
+               if (console_suspend_enabled)
+                       err = pm_runtime_force_suspend(dev);
+               else {
+                       /*
+                        * The pd shall not be powered-off (no console suspend).
+                        * Make copy of genpd flags before to set it always on.
+                        * The original value is restored during the resume.
+                        */
+                       genpd_flags_console = genpd->flags;
+                       genpd->flags |= GENPD_FLAG_ALWAYS_ON;
+               }
+       }
        flush_work(&priv->qos_work);
 
        return err;
@@ -1644,12 +1663,16 @@ static int omap8250_resume(struct device *dev)
 {
        struct omap8250_priv *priv = dev_get_drvdata(dev);
        struct uart_8250_port *up = serial8250_get_port(priv->line);
+       struct generic_pm_domain *genpd = pd_to_genpd(dev->pm_domain);
        int err;
 
        if (uart_console(&up->port) && console_suspend_enabled) {
-               err = pm_runtime_force_resume(dev);
-               if (err)
-                       return err;
+               if (console_suspend_enabled) {
+                       err = pm_runtime_force_resume(dev);
+                       if (err)
+                               return err;
+               } else
+                       genpd->flags = genpd_flags_console;
        }
 
        serial8250_resume_port(priv->line);