patches: refresh c6.1 + c6.2 (init UNKNOWN; always run wsm_set_operational_mode)

This commit is contained in:
2026-04-28 15:51:58 +02:00
parent e6a942a5df
commit c9057cac2c
4 changed files with 116 additions and 82 deletions
@@ -1,4 +1,4 @@
From 699e4b59a90c396dc95df8cf8a233824f9c0fedf Mon Sep 17 00:00:00 2001 From bc6236ce926a8da6f568a86fb65541034b1e074b Mon Sep 17 00:00:00 2001
From: Markus Fritsche <fritsche.markus@gmail.com> From: Markus Fritsche <fritsche.markus@gmail.com>
Date: Tue, 28 Apr 2026 15:05:27 +0200 Date: Tue, 28 Apr 2026 15:05:27 +0200
Subject: [PATCH] bes2600: gate PM indication completion on pending request and Subject: [PATCH] bes2600: gate PM indication completion on pending request and
@@ -72,7 +72,7 @@ Signed-off-by: Markus Fritsche <fritsche.markus@gmail.com>
2 files changed, 74 insertions(+), 7 deletions(-) 2 files changed, 74 insertions(+), 7 deletions(-)
diff --git a/drivers/staging/bes2600/bes_pwr.c b/drivers/staging/bes2600/bes_pwr.c diff --git a/drivers/staging/bes2600/bes_pwr.c b/drivers/staging/bes2600/bes_pwr.c
index f62ae226d295..0da1be272392 100644 index f62ae226d295..ec0e0cc14ea4 100644
--- a/drivers/staging/bes2600/bes_pwr.c --- a/drivers/staging/bes2600/bes_pwr.c
+++ b/drivers/staging/bes2600/bes_pwr.c +++ b/drivers/staging/bes2600/bes_pwr.c
@@ -524,7 +524,17 @@ static int bes2600_pwr_enter_lp_mode(struct bes2600_common *hw_priv) @@ -524,7 +524,17 @@ static int bes2600_pwr_enter_lp_mode(struct bes2600_common *hw_priv)
@@ -135,7 +135,7 @@ index f62ae226d295..0da1be272392 100644
hw_priv->bes_power.power_up_task = NULL; hw_priv->bes_power.power_up_task = NULL;
mutex_init(&hw_priv->bes_power.pwr_mutex); mutex_init(&hw_priv->bes_power.pwr_mutex);
atomic_set(&hw_priv->bes_power.dev_state, 0); atomic_set(&hw_priv->bes_power.dev_state, 0);
+ atomic_set(&hw_priv->bes_power.chip_pm_state, BES2600_CHIP_PM_ACTIVE); + atomic_set(&hw_priv->bes_power.chip_pm_state, BES2600_CHIP_PM_UNKNOWN);
init_completion(&hw_priv->bes_power.pm_enter_cmpl); init_completion(&hw_priv->bes_power.pm_enter_cmpl);
sema_init(&hw_priv->bes_power.sync_lock, 1); sema_init(&hw_priv->bes_power.sync_lock, 1);
device_set_wakeup_capable(hw_priv->pdev, true); device_set_wakeup_capable(hw_priv->pdev, true);
@@ -1,4 +1,4 @@
From 3853aadb48ae5f328d583a0ff2349c20589dd80b Mon Sep 17 00:00:00 2001 From 44c520fdc0c196f44d7825ef60fa7932d2a60882 Mon Sep 17 00:00:00 2001
From: Markus Fritsche <fritsche.markus@gmail.com> From: Markus Fritsche <fritsche.markus@gmail.com>
Date: Tue, 28 Apr 2026 15:05:27 +0200 Date: Tue, 28 Apr 2026 15:05:27 +0200
Subject: [PATCH] bes2600: gate PM indication completion on pending request and Subject: [PATCH] bes2600: gate PM indication completion on pending request and
@@ -72,7 +72,7 @@ Signed-off-by: Markus Fritsche <fritsche.markus@gmail.com>
2 files changed, 74 insertions(+), 7 deletions(-) 2 files changed, 74 insertions(+), 7 deletions(-)
diff --git a/bes2600/bes_pwr.c b/bes2600/bes_pwr.c diff --git a/bes2600/bes_pwr.c b/bes2600/bes_pwr.c
index 474b6f1..cd1b8cd 100644 index 474b6f1..820449c 100644
--- a/bes2600/bes_pwr.c --- a/bes2600/bes_pwr.c
+++ b/bes2600/bes_pwr.c +++ b/bes2600/bes_pwr.c
@@ -524,7 +524,17 @@ static int bes2600_pwr_enter_lp_mode(struct bes2600_common *hw_priv) @@ -524,7 +524,17 @@ static int bes2600_pwr_enter_lp_mode(struct bes2600_common *hw_priv)
@@ -135,7 +135,7 @@ index 474b6f1..cd1b8cd 100644
hw_priv->bes_power.power_up_task = NULL; hw_priv->bes_power.power_up_task = NULL;
mutex_init(&hw_priv->bes_power.pwr_mutex); mutex_init(&hw_priv->bes_power.pwr_mutex);
atomic_set(&hw_priv->bes_power.dev_state, 0); atomic_set(&hw_priv->bes_power.dev_state, 0);
+ atomic_set(&hw_priv->bes_power.chip_pm_state, BES2600_CHIP_PM_ACTIVE); + atomic_set(&hw_priv->bes_power.chip_pm_state, BES2600_CHIP_PM_UNKNOWN);
init_completion(&hw_priv->bes_power.pm_enter_cmpl); init_completion(&hw_priv->bes_power.pm_enter_cmpl);
sema_init(&hw_priv->bes_power.sync_lock, 1); sema_init(&hw_priv->bes_power.sync_lock, 1);
device_set_wakeup_capable(hw_priv->pdev, true); device_set_wakeup_capable(hw_priv->pdev, true);
@@ -1,4 +1,4 @@
From 1c5a06832f1cf7605aaf6a45cd029d1dad40b055 Mon Sep 17 00:00:00 2001 From aea2b411713a192db26c3144abcda21914520705 Mon Sep 17 00:00:00 2001
From: Markus Fritsche <fritsche.markus@gmail.com> From: Markus Fritsche <fritsche.markus@gmail.com>
Date: Tue, 28 Apr 2026 15:23:35 +0200 Date: Tue, 28 Apr 2026 15:23:35 +0200
Subject: [PATCH] bes2600: short-circuit wake handshake when chip is confirmed 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> Signed-off-by: Markus Fritsche <fritsche.markus@gmail.com>
--- ---
drivers/staging/bes2600/bes2600_sdio.c | 15 ++++++++++-- drivers/staging/bes2600/bes2600_sdio.c | 15 ++++++-
drivers/staging/bes2600/bes_pwr.c | 34 +++++++++++++++++++++++++- drivers/staging/bes2600/bes_pwr.c | 58 ++++++++++++++++++++++----
2 files changed, 46 insertions(+), 3 deletions(-) 2 files changed, 63 insertions(+), 10 deletions(-)
diff --git a/drivers/staging/bes2600/bes2600_sdio.c b/drivers/staging/bes2600/bes2600_sdio.c diff --git a/drivers/staging/bes2600/bes2600_sdio.c b/drivers/staging/bes2600/bes2600_sdio.c
index b9d836fab7af..929503547cfd 100644 index b9d836fab7af..929503547cfd 100644
@@ -113,10 +113,10 @@ index b9d836fab7af..929503547cfd 100644
return; return;
} }
diff --git a/drivers/staging/bes2600/bes_pwr.c b/drivers/staging/bes2600/bes_pwr.c diff --git a/drivers/staging/bes2600/bes_pwr.c b/drivers/staging/bes2600/bes_pwr.c
index 0da1be272392..e5e4d4d8944c 100644 index ec0e0cc14ea4..43087ca3b0ed 100644
--- a/drivers/staging/bes2600/bes_pwr.c --- a/drivers/staging/bes2600/bes_pwr.c
+++ b/drivers/staging/bes2600/bes_pwr.c +++ b/drivers/staging/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) static void bes2600_pwr_device_exit_lp_mode(struct bes2600_common *hw_priv)
{ {
int ret = 0; int ret = 0;
@@ -126,45 +126,62 @@ index 0da1be272392..e5e4d4d8944c 100644
.disableMoreFlagUsage = true, .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(). + * Consult chip_pm_state set by bes2600_pwr_notify_ps_changed().
+ * If we last saw the firmware confirm ACTIVE, skip the wake-up + * If we last saw the firmware confirm ACTIVE, skip ONLY the
+ * handshake entirely - the GPIO is already asserted, the SDIO + * gpio_wake + sbus_active wake handshake - the GPIO is already
+ * MCU subsystem is already running, and another sbus_active() + * asserted high and the SDIO MCU subsystem is already running,
+ * round-trip just hits its 200x2ms timeout because the firmware + * so another sbus_active() round-trip just hits its 200x2ms
+ * has nothing to do. This is the deterministic source of the + * timeout because the firmware has nothing to do.
+ * "active mcu fail" cycle in dmesg when an enter_lp_mode timeout + *
+ * left bookkeeping desynced. + * 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); + state = atomic_read(&hw_priv->bes_power.chip_pm_state);
+ if (state == BES2600_CHIP_PM_ACTIVE) { + if (state == BES2600_CHIP_PM_ACTIVE) {
+ bes_devel("device_exit_lp_mode: chip already ACTIVE, skipping wake handshake\n"); + 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->sbus_active) {
if(hw_priv->sbus_ops->gpio_wake) + ret = hw_priv->sbus_ops->sbus_active(hw_priv->sbus_priv,
hw_priv->sbus_ops->gpio_wake(hw_priv->sbus_priv, GPIO_WAKE_FLAG_MCU); + SUBSYSTEM_MCU);
+ if (ret) {
if(hw_priv->sbus_ops->sbus_active) { + /*
ret = hw_priv->sbus_ops->sbus_active(hw_priv->sbus_priv, SUBSYSTEM_MCU); + * MCU_WAKEUP_READY did not arrive within
- if (ret) + * the SDIO handshake window. Record state
+ if (ret) { + * as UNKNOWN so the next exit_lp_mode call
+ /* + * also runs the full wake sequence (no
+ * The firmware did not raise MCU_WAKEUP_READY within + * skip), but still send operational_mode
+ * the SDIO handshake window. Mark chip state UNKNOWN + * below to match pre-c6 behaviour - the
+ * and bail out before issuing wsm_set_operational_mode + * WSM may succeed even if the SDIO active
+ * over a wedged bus - that would just compound the + * confirm was lost, and if it fails too,
+ * failure. The next exit_lp_mode call will see UNKNOWN + * we just emit a second devel-level error.
+ * and try the wake again from scratch; if it stays + * Repeated UNKNOWN is the signal for the
+ * UNKNOWN across multiple cycles, the LMAC active- + * LMAC active-monitor to eventually
+ * monitor will eventually escalate to bus_reset + * escalate to bus_reset (c5.2's
+ * (c5.2's mmc_hw_reset path). + * mmc_hw_reset path).
+ */ + */
bes_err("%s, active mcu fail\n", __func__); + bes_err("%s, active mcu fail\n", __func__);
+ atomic_set(&hw_priv->bes_power.chip_pm_state, + atomic_set(&hw_priv->bes_power.chip_pm_state,
+ BES2600_CHIP_PM_UNKNOWN); + BES2600_CHIP_PM_UNKNOWN);
+ return; + }
+ } + }
} }
@@ -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> From: Markus Fritsche <fritsche.markus@gmail.com>
Date: Tue, 28 Apr 2026 15:23:34 +0200 Date: Tue, 28 Apr 2026 15:23:34 +0200
Subject: [PATCH] bes2600: short-circuit wake handshake when chip is confirmed 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> Signed-off-by: Markus Fritsche <fritsche.markus@gmail.com>
--- ---
bes2600/bes2600_sdio.c | 15 +++++++++++++-- bes2600/bes2600_sdio.c | 15 +++++++++--
bes2600/bes_pwr.c | 34 +++++++++++++++++++++++++++++++++- bes2600/bes_pwr.c | 58 ++++++++++++++++++++++++++++++++++++------
2 files changed, 46 insertions(+), 3 deletions(-) 2 files changed, 63 insertions(+), 10 deletions(-)
diff --git a/bes2600/bes2600_sdio.c b/bes2600/bes2600_sdio.c diff --git a/bes2600/bes2600_sdio.c b/bes2600/bes2600_sdio.c
index 3e04e8c..acc0f19 100644 index 3e04e8c..acc0f19 100644
@@ -113,10 +113,10 @@ index 3e04e8c..acc0f19 100644
return; return;
} }
diff --git a/bes2600/bes_pwr.c b/bes2600/bes_pwr.c 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 --- a/bes2600/bes_pwr.c
+++ b/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) static void bes2600_pwr_device_exit_lp_mode(struct bes2600_common *hw_priv)
{ {
int ret = 0; int ret = 0;
@@ -126,45 +126,62 @@ index cd1b8cd..22074db 100644
.disableMoreFlagUsage = true, .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(). + * Consult chip_pm_state set by bes2600_pwr_notify_ps_changed().
+ * If we last saw the firmware confirm ACTIVE, skip the wake-up + * If we last saw the firmware confirm ACTIVE, skip ONLY the
+ * handshake entirely - the GPIO is already asserted, the SDIO + * gpio_wake + sbus_active wake handshake - the GPIO is already
+ * MCU subsystem is already running, and another sbus_active() + * asserted high and the SDIO MCU subsystem is already running,
+ * round-trip just hits its 200x2ms timeout because the firmware + * so another sbus_active() round-trip just hits its 200x2ms
+ * has nothing to do. This is the deterministic source of the + * timeout because the firmware has nothing to do.
+ * "active mcu fail" cycle in dmesg when an enter_lp_mode timeout + *
+ * left bookkeeping desynced. + * 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); + state = atomic_read(&hw_priv->bes_power.chip_pm_state);
+ if (state == BES2600_CHIP_PM_ACTIVE) { + if (state == BES2600_CHIP_PM_ACTIVE) {
+ bes_devel("device_exit_lp_mode: chip already ACTIVE, skipping wake handshake\n"); + 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->sbus_active) {
if(hw_priv->sbus_ops->gpio_wake) + ret = hw_priv->sbus_ops->sbus_active(hw_priv->sbus_priv,
hw_priv->sbus_ops->gpio_wake(hw_priv->sbus_priv, GPIO_WAKE_FLAG_MCU); + SUBSYSTEM_MCU);
+ if (ret) {
if(hw_priv->sbus_ops->sbus_active) { + /*
ret = hw_priv->sbus_ops->sbus_active(hw_priv->sbus_priv, SUBSYSTEM_MCU); + * MCU_WAKEUP_READY did not arrive within
- if (ret) + * the SDIO handshake window. Record state
+ if (ret) { + * as UNKNOWN so the next exit_lp_mode call
+ /* + * also runs the full wake sequence (no
+ * The firmware did not raise MCU_WAKEUP_READY within + * skip), but still send operational_mode
+ * the SDIO handshake window. Mark chip state UNKNOWN + * below to match pre-c6 behaviour - the
+ * and bail out before issuing wsm_set_operational_mode + * WSM may succeed even if the SDIO active
+ * over a wedged bus - that would just compound the + * confirm was lost, and if it fails too,
+ * failure. The next exit_lp_mode call will see UNKNOWN + * we just emit a second devel-level error.
+ * and try the wake again from scratch; if it stays + * Repeated UNKNOWN is the signal for the
+ * UNKNOWN across multiple cycles, the LMAC active- + * LMAC active-monitor to eventually
+ * monitor will eventually escalate to bus_reset + * escalate to bus_reset (c5.2's
+ * (c5.2's mmc_hw_reset path). + * mmc_hw_reset path).
+ */ + */
bes_err("%s, active mcu fail\n", __func__); + bes_err("%s, active mcu fail\n", __func__);
+ atomic_set(&hw_priv->bes_power.chip_pm_state, + atomic_set(&hw_priv->bes_power.chip_pm_state,
+ BES2600_CHIP_PM_UNKNOWN); + BES2600_CHIP_PM_UNKNOWN);
+ return; + }
+ } + }
} }