b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -524,6 +524,7 @@ struct brcmf_sdio {
bool txglom; /* host tx glomming enable flag */
u16 head_align; /* buffer pointer alignment */
u16 sgentry_align; /* scatter-gather buffer alignment */
+ struct mutex dpc_mutex;
};
/* clkstate */
@@ -3724,6 +3725,7 @@ static void brcmf_sdio_bus_watchdog(struct
brcmf_sdio *bus)
}
#endif /* DEBUG */
+ mutex_lock(&bus->dpc_mutex);
/* On idle timeout clear activity flag and/or turn off clock */
if (!bus->dpc_triggered) {
Use mutex to prevent sdio bus to be put to sleep by the sdio_bus_watchdog while sdio dataworker handles sdio_dpc data transfers. Signed-off-by: Nikolay Nikolov <nikolay.nikolov@bench.com> drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 6 ++++++ 1 file changed, 6 insertions(+) rmb(); @@ -3748,6 +3750,7 @@ static void brcmf_sdio_bus_watchdog(struct brcmf_sdio *bus) } else { bus->idlecount = 0; } + mutex_unlock(&bus->dpc_mutex); } static void brcmf_sdio_dataworker(struct work_struct *work) @@ -3755,6 +3758,7 @@ static void brcmf_sdio_dataworker(struct work_struct *work) struct brcmf_sdio *bus = container_of(work, struct brcmf_sdio, datawork); + mutex_lock(&bus->dpc_mutex); bus->dpc_running = true; wmb(); while (READ_ONCE(bus->dpc_triggered)) { @@ -3763,6 +3767,7 @@ static void brcmf_sdio_dataworker(struct work_struct *work) bus->idlecount = 0; } bus->dpc_running = false; + mutex_unlock(&bus->dpc_mutex); if (brcmf_sdiod_freezing(bus->sdiodev)) { brcmf_sdiod_change_state(bus->sdiodev, BRCMF_SDIOD_DOWN); brcmf_sdiod_try_freeze(bus->sdiodev); @@ -4525,6 +4530,7 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev) /* SR state */ bus->sr_enabled = false; + mutex_init(&bus->dpc_mutex); brcmf_dbg(INFO, "completed!!\n");