diff options
author | Felix Fietkau <nbd@openwrt.org> | 2011-09-02 23:40:25 (GMT) |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-09-14 17:56:20 (GMT) |
commit | 236de5149b9cbec3e76aef00a4663a8de7feeebe (patch) | |
tree | 3086a9d4b4bcd0e5a5ccfba94b02545e765f56bc /drivers/net/wireless/ath/ath9k/main.c | |
parent | e8cfe9f8c488f5b345ab557148c7af57af4fbe25 (diff) | |
download | linux-fsl-qoriq-236de5149b9cbec3e76aef00a4663a8de7feeebe.tar.xz |
ath9k: always call ath_reset from workqueue context
This makes it much easier to add further rework to avoid race conditions
between reset and other work items.
Move other functions to make ath_reset static.
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/main.c')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/main.c | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 9ff73e0..9a6db29 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -236,6 +236,7 @@ static int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, del_timer_sync(&common->ani.timer); cancel_work_sync(&sc->paprd_work); cancel_work_sync(&sc->hw_check_work); + cancel_work_sync(&sc->hw_reset_work); cancel_delayed_work_sync(&sc->tx_complete_work); cancel_delayed_work_sync(&sc->hw_pll_work); @@ -608,9 +609,7 @@ void ath9k_tasklet(unsigned long data) if ((status & ATH9K_INT_FATAL) || (status & ATH9K_INT_BB_WATCHDOG)) { - spin_lock(&sc->sc_pcu_lock); - ath_reset(sc, true); - spin_unlock(&sc->sc_pcu_lock); + ieee80211_queue_work(sc->hw, &sc->hw_reset_work); return; } @@ -901,7 +900,7 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw) ath9k_ps_restore(sc); } -int ath_reset(struct ath_softc *sc, bool retry_tx) +static int ath_reset(struct ath_softc *sc, bool retry_tx) { struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(ah); @@ -969,6 +968,15 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) return r; } +void ath_reset_work(struct work_struct *work) +{ + struct ath_softc *sc = container_of(work, struct ath_softc, hw_reset_work); + + spin_lock_bh(&sc->sc_pcu_lock); + ath_reset(sc, true); + spin_unlock_bh(&sc->sc_pcu_lock); +} + void ath_hw_check(struct work_struct *work) { struct ath_softc *sc = container_of(work, struct ath_softc, hw_check_work); @@ -1230,6 +1238,7 @@ static void ath9k_stop(struct ieee80211_hw *hw) cancel_delayed_work_sync(&sc->hw_pll_work); cancel_work_sync(&sc->paprd_work); cancel_work_sync(&sc->hw_check_work); + cancel_work_sync(&sc->hw_reset_work); if (sc->sc_flags & SC_OP_INVALID) { ath_dbg(common, ATH_DBG_ANY, "Device not present\n"); |