aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLorenzo Bianconi <lorenzo@kernel.org>2021-12-27 14:08:52 +0100
committerFelix Fietkau <nbd@nbd.name>2022-02-03 13:57:58 +0100
commit6e39e9a19cbe640897a4232dd67ae6836a224c0a (patch)
tree1fe53a5dfdb8924d9a8cb8a01254097b34cfe42b
parentmt76: mt7921: set EDCA parameters with the MCU CE command (diff)
downloadlinux-dev-6e39e9a19cbe640897a4232dd67ae6836a224c0a.tar.xz
linux-dev-6e39e9a19cbe640897a4232dd67ae6836a224c0a.zip
mt76: mt7615: fix a possible race enabling/disabling runtime-pm
Similar to mt7921 driver, fix a possible race enabling/disabling runtime-pm between mt7615_pm_set() and mt7615_poll_rx(). mt7615_pm_wake_work() always schedules rx-napi callback and it will trigger mt7615_pm_power_save_work routine putting the chip in low-power state even if we are disabling runtime-pm deferring the actual chip wake at the next access. Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> Signed-off-by: Felix Fietkau <nbd@nbd.name>
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7615/debugfs.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/debugfs.c b/drivers/net/wireless/mediatek/mt76/mt7615/debugfs.c
index b53528014fbc..ca7efca1543f 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/debugfs.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/debugfs.c
@@ -105,10 +105,10 @@ mt7615_pm_set(void *data, u64 val)
if (!mt7615_firmware_offload(dev) || mt76_is_usb(&dev->mt76))
return -EOPNOTSUPP;
- if (val == pm->enable)
- return 0;
+ mutex_lock(&dev->mt76.mutex);
- mt7615_mutex_acquire(dev);
+ if (val == pm->enable)
+ goto out;
if (dev->phy.n_beacon_vif) {
ret = -EBUSY;
@@ -119,9 +119,16 @@ mt7615_pm_set(void *data, u64 val)
pm->stats.last_wake_event = jiffies;
pm->stats.last_doze_event = jiffies;
}
+ /* make sure the chip is awake here and ps_work is scheduled
+ * just at end of the this routine.
+ */
+ pm->enable = false;
+ mt76_connac_pm_wake(&dev->mphy, pm);
+
pm->enable = val;
+ mt76_connac_power_save_sched(&dev->mphy, pm);
out:
- mt7615_mutex_release(dev);
+ mutex_unlock(&dev->mt76.mutex);
return ret;
}