Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 822a5f1bab |
+13
-2
@@ -1388,7 +1388,14 @@ static void bes2600_gpio_wakeup_mcu(struct sbus_priv *self, int flag)
|
|||||||
|
|
||||||
/* error check */
|
/* error check */
|
||||||
if((self->gpio_wakup_flags & BIT(flag)) != 0) {
|
if((self->gpio_wakup_flags & BIT(flag)) != 0) {
|
||||||
bes_err( "repeat set gpio_wake_flag, sub_sys:%d", flag);
|
/*
|
||||||
|
* Multiple subsystems holding wake is the steady-state case
|
||||||
|
* (e.g. WIFI + BT both want MCU awake). Demoted from bes_err
|
||||||
|
* to bes_devel since it isn't an error - the GPIO is already
|
||||||
|
* asserted high and the subsystem is now also tracked.
|
||||||
|
*/
|
||||||
|
bes_devel("repeat set gpio_wake_flag, sub_sys:%d\n", flag);
|
||||||
|
self->gpio_wakup_flags |= BIT(flag);
|
||||||
mutex_unlock(&self->io_mutex);
|
mutex_unlock(&self->io_mutex);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1420,7 +1427,11 @@ static void bes2600_gpio_allow_mcu_sleep(struct sbus_priv *self, int flag)
|
|||||||
|
|
||||||
/* error check */
|
/* error check */
|
||||||
if((self->gpio_wakup_flags & BIT(flag)) == 0) {
|
if((self->gpio_wakup_flags & BIT(flag)) == 0) {
|
||||||
bes_err( "repeat clear gpio_wake_flag, sub_sys:%d", flag);
|
/*
|
||||||
|
* Mirror of the wake path: a clear when the bit is already
|
||||||
|
* clear is racy bookkeeping, not a hardware error.
|
||||||
|
*/
|
||||||
|
bes_devel("repeat clear gpio_wake_flag, sub_sys:%d\n", flag);
|
||||||
mutex_unlock(&self->io_mutex);
|
mutex_unlock(&self->io_mutex);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
+47
-5
@@ -621,19 +621,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;
|
||||||
|
enum bes2600_chip_pm_state state;
|
||||||
struct wsm_operational_mode mode = {
|
struct wsm_operational_mode mode = {
|
||||||
.power_mode = wsm_power_mode_active,
|
.power_mode = wsm_power_mode_active,
|
||||||
.disableMoreFlagUsage = true,
|
.disableMoreFlagUsage = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Consult chip_pm_state set by bes2600_pwr_notify_ps_changed().
|
||||||
|
* 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");
|
||||||
|
} else {
|
||||||
bes_devel("host lock lmac\n");
|
bes_devel("host lock lmac\n");
|
||||||
if(hw_priv->sbus_ops->gpio_wake)
|
if (hw_priv->sbus_ops->gpio_wake)
|
||||||
hw_priv->sbus_ops->gpio_wake(hw_priv->sbus_priv, GPIO_WAKE_FLAG_MCU);
|
hw_priv->sbus_ops->gpio_wake(hw_priv->sbus_priv,
|
||||||
|
GPIO_WAKE_FLAG_MCU);
|
||||||
|
|
||||||
if(hw_priv->sbus_ops->sbus_active) {
|
if (hw_priv->sbus_ops->sbus_active) {
|
||||||
ret = hw_priv->sbus_ops->sbus_active(hw_priv->sbus_priv, SUBSYSTEM_MCU);
|
ret = hw_priv->sbus_ops->sbus_active(hw_priv->sbus_priv,
|
||||||
if (ret)
|
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__);
|
bes_err("%s, active mcu fail\n", __func__);
|
||||||
|
atomic_set(&hw_priv->bes_power.chip_pm_state,
|
||||||
|
BES2600_CHIP_PM_UNKNOWN);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = wsm_set_operational_mode(hw_priv, &mode, 0);
|
ret = wsm_set_operational_mode(hw_priv, &mode, 0);
|
||||||
|
|||||||
Reference in New Issue
Block a user