patches: refresh c6.1 + c6.2 (init UNKNOWN; always run wsm_set_operational_mode)
This commit is contained in:
+55
-38
@@ -1,4 +1,4 @@
|
||||
From b6608f14fe81f38f53b5c3e7e6a739cdf20237f8 Mon Sep 17 00:00:00 2001
|
||||
From 1e6ccf95bba799e8599ae37c936aab76b9fc9018 Mon Sep 17 00:00:00 2001
|
||||
From: Markus Fritsche <fritsche.markus@gmail.com>
|
||||
Date: Tue, 28 Apr 2026 15:23:34 +0200
|
||||
Subject: [PATCH] bes2600: short-circuit wake handshake when chip is confirmed
|
||||
@@ -75,9 +75,9 @@ field added in the prerequisite patch.
|
||||
|
||||
Signed-off-by: Markus Fritsche <fritsche.markus@gmail.com>
|
||||
---
|
||||
bes2600/bes2600_sdio.c | 15 +++++++++++++--
|
||||
bes2600/bes_pwr.c | 34 +++++++++++++++++++++++++++++++++-
|
||||
2 files changed, 46 insertions(+), 3 deletions(-)
|
||||
bes2600/bes2600_sdio.c | 15 +++++++++--
|
||||
bes2600/bes_pwr.c | 58 ++++++++++++++++++++++++++++++++++++------
|
||||
2 files changed, 63 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/bes2600/bes2600_sdio.c b/bes2600/bes2600_sdio.c
|
||||
index 3e04e8c..acc0f19 100644
|
||||
@@ -113,10 +113,10 @@ index 3e04e8c..acc0f19 100644
|
||||
return;
|
||||
}
|
||||
diff --git a/bes2600/bes_pwr.c b/bes2600/bes_pwr.c
|
||||
index cd1b8cd..22074db 100644
|
||||
index 820449c..2839ce7 100644
|
||||
--- a/bes2600/bes_pwr.c
|
||||
+++ b/bes2600/bes_pwr.c
|
||||
@@ -597,19 +597,51 @@ static int bes2600_pwr_enter_lp_mode(struct bes2600_common *hw_priv)
|
||||
@@ -597,19 +597,61 @@ static int bes2600_pwr_enter_lp_mode(struct bes2600_common *hw_priv)
|
||||
static void bes2600_pwr_device_exit_lp_mode(struct bes2600_common *hw_priv)
|
||||
{
|
||||
int ret = 0;
|
||||
@@ -126,45 +126,62 @@ index cd1b8cd..22074db 100644
|
||||
.disableMoreFlagUsage = true,
|
||||
};
|
||||
|
||||
- bes_devel("host lock lmac\n");
|
||||
- if(hw_priv->sbus_ops->gpio_wake)
|
||||
- hw_priv->sbus_ops->gpio_wake(hw_priv->sbus_priv, GPIO_WAKE_FLAG_MCU);
|
||||
-
|
||||
- if(hw_priv->sbus_ops->sbus_active) {
|
||||
- ret = hw_priv->sbus_ops->sbus_active(hw_priv->sbus_priv, SUBSYSTEM_MCU);
|
||||
- if (ret)
|
||||
- bes_err("%s, active mcu fail\n", __func__);
|
||||
+ /*
|
||||
+ * Consult chip_pm_state set by bes2600_pwr_notify_ps_changed().
|
||||
+ * If we last saw the firmware confirm ACTIVE, skip the wake-up
|
||||
+ * handshake entirely - the GPIO is already asserted, the SDIO
|
||||
+ * MCU subsystem is already running, and another sbus_active()
|
||||
+ * round-trip just hits its 200x2ms timeout because the firmware
|
||||
+ * has nothing to do. This is the deterministic source of the
|
||||
+ * "active mcu fail" cycle in dmesg when an enter_lp_mode timeout
|
||||
+ * left bookkeeping desynced.
|
||||
+ * If we last saw the firmware confirm ACTIVE, skip ONLY the
|
||||
+ * gpio_wake + sbus_active wake handshake - the GPIO is already
|
||||
+ * asserted high and the SDIO MCU subsystem is already running,
|
||||
+ * so another sbus_active() round-trip just hits its 200x2ms
|
||||
+ * timeout because the firmware has nothing to do.
|
||||
+ *
|
||||
+ * wsm_set_operational_mode() below is NOT part of the wake
|
||||
+ * handshake; it is the operational-mode setter the firmware
|
||||
+ * tracks per call. Skipping it leaves the chip's SDIO state
|
||||
+ * machine without a fresh operational-mode update, which on
|
||||
+ * PineTab2 wedges the bus (-EBUSY on next sdio_rx_work read)
|
||||
+ * within a few seconds of probe completion. So it must run
|
||||
+ * unconditionally.
|
||||
+ */
|
||||
+ state = atomic_read(&hw_priv->bes_power.chip_pm_state);
|
||||
+ if (state == BES2600_CHIP_PM_ACTIVE) {
|
||||
+ bes_devel("device_exit_lp_mode: chip already ACTIVE, skipping wake handshake\n");
|
||||
+ return;
|
||||
+ }
|
||||
+ } else {
|
||||
+ bes_devel("host lock lmac\n");
|
||||
+ if (hw_priv->sbus_ops->gpio_wake)
|
||||
+ hw_priv->sbus_ops->gpio_wake(hw_priv->sbus_priv,
|
||||
+ GPIO_WAKE_FLAG_MCU);
|
||||
+
|
||||
bes_devel("host lock lmac\n");
|
||||
if(hw_priv->sbus_ops->gpio_wake)
|
||||
hw_priv->sbus_ops->gpio_wake(hw_priv->sbus_priv, GPIO_WAKE_FLAG_MCU);
|
||||
|
||||
if(hw_priv->sbus_ops->sbus_active) {
|
||||
ret = hw_priv->sbus_ops->sbus_active(hw_priv->sbus_priv, SUBSYSTEM_MCU);
|
||||
- if (ret)
|
||||
+ if (ret) {
|
||||
+ /*
|
||||
+ * The firmware did not raise MCU_WAKEUP_READY within
|
||||
+ * the SDIO handshake window. Mark chip state UNKNOWN
|
||||
+ * and bail out before issuing wsm_set_operational_mode
|
||||
+ * over a wedged bus - that would just compound the
|
||||
+ * failure. The next exit_lp_mode call will see UNKNOWN
|
||||
+ * and try the wake again from scratch; if it stays
|
||||
+ * UNKNOWN across multiple cycles, the LMAC active-
|
||||
+ * monitor will eventually escalate to bus_reset
|
||||
+ * (c5.2's mmc_hw_reset path).
|
||||
+ */
|
||||
bes_err("%s, active mcu fail\n", __func__);
|
||||
+ atomic_set(&hw_priv->bes_power.chip_pm_state,
|
||||
+ BES2600_CHIP_PM_UNKNOWN);
|
||||
+ return;
|
||||
+ if (hw_priv->sbus_ops->sbus_active) {
|
||||
+ ret = hw_priv->sbus_ops->sbus_active(hw_priv->sbus_priv,
|
||||
+ SUBSYSTEM_MCU);
|
||||
+ if (ret) {
|
||||
+ /*
|
||||
+ * MCU_WAKEUP_READY did not arrive within
|
||||
+ * the SDIO handshake window. Record state
|
||||
+ * as UNKNOWN so the next exit_lp_mode call
|
||||
+ * also runs the full wake sequence (no
|
||||
+ * skip), but still send operational_mode
|
||||
+ * below to match pre-c6 behaviour - the
|
||||
+ * WSM may succeed even if the SDIO active
|
||||
+ * confirm was lost, and if it fails too,
|
||||
+ * we just emit a second devel-level error.
|
||||
+ * Repeated UNKNOWN is the signal for the
|
||||
+ * LMAC active-monitor to eventually
|
||||
+ * escalate to bus_reset (c5.2's
|
||||
+ * mmc_hw_reset path).
|
||||
+ */
|
||||
+ bes_err("%s, active mcu fail\n", __func__);
|
||||
+ atomic_set(&hw_priv->bes_power.chip_pm_state,
|
||||
+ BES2600_CHIP_PM_UNKNOWN);
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user