summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGabor Juhos <juhosg@openwrt.org>2009-07-14 20:17:13 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-07-24 15:05:18 -0400
commit04717ccd80e5acc500239222684fcf8d2c759a84 (patch)
treea506fc7ab3bca88e39a54952b822006d97765920
parentebaa24534ef54a8f665558536dbef3a761a9b841 (diff)
downloadblackbird-op-linux-04717ccd80e5acc500239222684fcf8d2c759a84.tar.gz
blackbird-op-linux-04717ccd80e5acc500239222684fcf8d2c759a84.zip
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 <juhosg@openwrt.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c15
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c1
3 files changed, 16 insertions, 1 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 20bf4a7f896d..b37eb592b524 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -559,6 +559,7 @@ struct ath_softc {
spinlock_t sc_resetlock;
spinlock_t sc_serial_rw;
spinlock_t ani_lock;
+ spinlock_t sc_pm_lock;
struct mutex mutex;
u8 curbssid[ETH_ALEN];
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index a115c8ceabe3..6740a6b98a62 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -2728,7 +2728,8 @@ static bool ath9k_hw_set_power_awake(struct ath_hw *ah, int setChip)
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[] = {
@@ -2762,6 +2763,18 @@ bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode)
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.
*
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 90cecce8d5ff..d14f8c9cef68 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1316,6 +1316,7 @@ static int ath_init(u16 devid, struct ath_softc *sc)
spin_lock_init(&sc->sc_resetlock);
spin_lock_init(&sc->sc_serial_rw);
spin_lock_init(&sc->ani_lock);
+ 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,
OpenPOWER on IntegriCloud