From 841c7e339c4775f4cc614c92aaea82f70fcafbdb Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Sun, 21 Jun 2009 16:59:53 +0200 Subject: [PATCH 1/3] ath9k: serialize ath9k_hw_setpower calls Because ath9k_setpower is called from various contexts, we have to protect it against concurrent calls. Changes-licensed-under: ISC Signed-off-by: Gabor Juhos --- drivers/net/wireless/ath/ath9k/ath9k.h | 1 + drivers/net/wireless/ath/ath9k/hw.c | 15 ++++++++++++++- drivers/net/wireless/ath/ath9k/main.c | 1 + 3 files changed, 16 insertions(+), 1 deletions(-) --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -544,6 +544,7 @@ struct ath_softc { int irq; spinlock_t sc_resetlock; spinlock_t sc_serial_rw; + spinlock_t sc_pm_lock; struct mutex mutex; u8 curbssid[ETH_ALEN]; --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -2738,7 +2738,8 @@ static bool ath9k_hw_set_power_awake(str return true; } -bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode) +static bool ath9k_hw_setpower_nolock(struct ath_hw *ah, + enum ath9k_power_mode mode) { int status = true, setChip = true; static const char *modes[] = { @@ -2772,6 +2773,18 @@ bool ath9k_hw_setpower(struct ath_hw *ah return status; } +bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode) +{ + unsigned long flags; + bool ret; + + spin_lock_irqsave(&ah->ah_sc->sc_pm_lock, flags); + ret = ath9k_hw_setpower_nolock(ah, mode); + spin_unlock_irqrestore(&ah->ah_sc->sc_pm_lock, flags); + + return ret; +} + /* * Helper for ASPM support. * --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1317,6 +1317,7 @@ static int ath_init(u16 devid, struct at spin_lock_init(&sc->wiphy_lock); spin_lock_init(&sc->sc_resetlock); spin_lock_init(&sc->sc_serial_rw); + spin_lock_init(&sc->sc_pm_lock); mutex_init(&sc->mutex); tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc); tasklet_init(&sc->bcon_tasklet, ath_beacon_tasklet,