Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 49dc6fcd authored by Tony Lindgren's avatar Tony Lindgren Committed by Greg Kroah-Hartman
Browse files

bus: ti-sysc: Fix SYSC_QUIRK_SWSUP_SIDLE_ACT handling for uart wake-up



[ Upstream commit e5deb8f76e64d94ccef715e75ebafffd0c312d80 ]

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: fb685f1c ("bus: ti-sysc: Handle swsup idle mode quirks")
Tested-by: default avatarDhruva Gole <d-gole@ti.com>
Tested-by: default avatarKevin Hilman <khilman@baylibre.com>
Signed-off-by: default avatarTony Lindgren <tony@atomide.com>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent 84173318
Loading
Loading
Loading
Loading
+17 −5
Original line number Diff line number Diff line
@@ -1023,6 +1023,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) {
@@ -1143,6 +1148,13 @@ static int sysc_disable_module(struct device *dev)
		}
	}

	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 &&
@@ -1371,16 +1383,16 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = {
	SYSC_QUIRK("timer", 0, 0, 0x10, -ENODEV, 0x4fff1301, 0xffff00ff,
		   0),
	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,