bus: ti-sysc: Fix SYSC_QUIRK_SWSUP_SIDLE_ACT handling for uart wake-up
authorTony Lindgren <tony@atomide.com>
Thu, 7 Sep 2023 05:53:28 +0000 (08:53 +0300)
committerTony Lindgren <tony@atomide.com>
Wed, 13 Sep 2023 07:24:53 +0000 (10:24 +0300)
The uarts should be tagged with SYSC_QUIRK_SWSUP_SIDLE instead of
SYSC_QUIRK_SWSUP_SIDLE_ACT. The difference is that SYSC_QUIRK_SWSUP_SIDLE
is used to force idle target modules rather than block idle during usage.

The SYSC_QUIRK_SWSUP_SIDLE_ACT should disable autoidle and wake-up when
a target module is active, and configure autoidle and wake-up when a
target module is inactive. We are missing configuring the target module
on sysc_disable_module(), and missing toggling of the wake-up bit.

Let's fix the issue to allow uart wake-up to work.

Fixes: fb685f1c190e ("bus: ti-sysc: Handle swsup idle mode quirks")
Tested-by: Dhruva Gole <d-gole@ti.com>
Tested-by: Kevin Hilman <khilman@baylibre.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
drivers/bus/ti-sysc.c

index 33e8d780b04ba34ac83bb5f45132c6ac3636438c..d57bc066dce6b4c5bd97f5a662928b2b590f7221 100644 (file)
@@ -1098,6 +1098,11 @@ static int sysc_enable_module(struct device *dev)
        if (ddata->cfg.quirks & (SYSC_QUIRK_SWSUP_SIDLE |
                                 SYSC_QUIRK_SWSUP_SIDLE_ACT)) {
                best_mode = SYSC_IDLE_NO;
+
+               /* Clear WAKEUP */
+               if (regbits->enwkup_shift >= 0 &&
+                   ddata->cfg.sysc_val & BIT(regbits->enwkup_shift))
+                       reg &= ~BIT(regbits->enwkup_shift);
        } else {
                best_mode = fls(ddata->cfg.sidlemodes) - 1;
                if (best_mode > SYSC_IDLE_MASK) {
@@ -1225,6 +1230,13 @@ set_sidle:
                }
        }
 
+       if (ddata->cfg.quirks & SYSC_QUIRK_SWSUP_SIDLE_ACT) {
+               /* Set WAKEUP */
+               if (regbits->enwkup_shift >= 0 &&
+                   ddata->cfg.sysc_val & BIT(regbits->enwkup_shift))
+                       reg |= BIT(regbits->enwkup_shift);
+       }
+
        reg &= ~(SYSC_IDLE_MASK << regbits->sidle_shift);
        reg |= best_mode << regbits->sidle_shift;
        if (regbits->autoidle_shift >= 0 &&
@@ -1519,16 +1531,16 @@ struct sysc_revision_quirk {
 static const struct sysc_revision_quirk sysc_revision_quirks[] = {
        /* These drivers need to be fixed to not use pm_runtime_irq_safe() */
        SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x00000046, 0xffffffff,
-                  SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_LEGACY_IDLE),
+                  SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE),
        SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x00000052, 0xffffffff,
-                  SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_LEGACY_IDLE),
+                  SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE),
        /* Uarts on omap4 and later */
        SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x50411e03, 0xffff00ff,
-                  SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_LEGACY_IDLE),
+                  SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE),
        SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x47422e03, 0xffffffff,
-                  SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_LEGACY_IDLE),
+                  SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE),
        SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x47424e03, 0xffffffff,
-                  SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_LEGACY_IDLE),
+                  SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE),
 
        /* Quirks that need to be set based on the module address */
        SYSC_QUIRK("mcpdm", 0x40132000, 0, 0x10, -ENODEV, 0x50000800, 0xffffffff,