diff options
author | John W. Linville <linville@tuxdriver.com> | 2011-01-28 16:23:14 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-01-28 16:23:14 -0500 |
commit | 3e11210d46a4f252f41db6e442b46026aeddbb59 (patch) | |
tree | b258375de649a5e04e8d567c850b47c41f8ceb11 /drivers/net/wireless/ath/ath9k/main.c | |
parent | 3bf63e59e577cbecd41334c866f501c4cc5d54c5 (diff) | |
parent | c7c1806098752c1f46943d8db2c69aff07f5d4bc (diff) | |
download | kernel_samsung_tuna-3e11210d46a4f252f41db6e442b46026aeddbb59.zip kernel_samsung_tuna-3e11210d46a4f252f41db6e442b46026aeddbb59.tar.gz kernel_samsung_tuna-3e11210d46a4f252f41db6e442b46026aeddbb59.tar.bz2 |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6
Conflicts:
drivers/net/wireless/ath/ath9k/init.c
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/main.c')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/main.c | 19 |
1 files changed, 14 insertions, 5 deletions
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 91af57c..20c70ba 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -611,14 +611,12 @@ void ath9k_tasklet(unsigned long data) u32 status = sc->intrstatus; u32 rxmask; - ath9k_ps_wakeup(sc); - if (status & ATH9K_INT_FATAL) { ath_reset(sc, true); - ath9k_ps_restore(sc); return; } + ath9k_ps_wakeup(sc); spin_lock(&sc->sc_pcu_lock); /* @@ -939,8 +937,6 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw) spin_unlock_bh(&sc->sc_pcu_lock); ath9k_ps_restore(sc); - - ath9k_setpower(sc, ATH9K_PM_FULL_SLEEP); } int ath_reset(struct ath_softc *sc, bool retry_tx) @@ -953,6 +949,7 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) /* Stop ANI */ del_timer_sync(&common->ani.timer); + ath9k_ps_wakeup(sc); spin_lock_bh(&sc->sc_pcu_lock); ieee80211_stop_queues(hw); @@ -999,6 +996,7 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) /* Start ANI */ ath_start_ani(common); + ath9k_ps_restore(sc); return r; } @@ -1220,6 +1218,9 @@ static void ath9k_stop(struct ieee80211_hw *hw) spin_lock_bh(&sc->sc_pcu_lock); + /* prevent tasklets to enable interrupts once we disable them */ + ah->imask &= ~ATH9K_INT_GLOBAL; + /* make sure h/w will not generate any interrupt * before setting the invalid flag. */ ath9k_hw_disable_interrupts(ah); @@ -1242,6 +1243,12 @@ static void ath9k_stop(struct ieee80211_hw *hw) spin_unlock_bh(&sc->sc_pcu_lock); + /* we can now sync irq and kill any running tasklets, since we already + * disabled interrupts and not holding a spin lock */ + synchronize_irq(sc->irq); + tasklet_kill(&sc->intr_tq); + tasklet_kill(&sc->bcon_tasklet); + ath9k_ps_restore(sc); sc->ps_idle = true; @@ -1706,7 +1713,9 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) if (changed & IEEE80211_CONF_CHANGE_POWER) { sc->config.txpowlimit = 2 * conf->power_level; + ath9k_ps_wakeup(sc); ath_update_txpow(sc); + ath9k_ps_restore(sc); } if (disable_radio) { |