diff options
author | Luis R. Rodriguez <lrodriguez@atheros.com> | 2009-10-06 21:19:09 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-10-07 16:39:52 -0400 |
commit | 2568835cb44d6fe976e977d96aeca73c9fe1642c (patch) | |
tree | abf665608afe444d80427cbda689f9536b9984fc /drivers/net/wireless | |
parent | 7fda16665152851fe65ee73e24afdcaf67acba59 (diff) |
ath9k: add a helper to clean the core driver upon module unload
The core driver needs to be stopped and then as a last step the
hardware needs to be stopped and its structure free'd. We do this
by moving the core driver cleanup to a new helper ath_clean_core()
and have ath_cleanup() call it. Only as a last step does
ath_cleanup() now free the hw.
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/main.c | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index e6842dd83ce2..39b278053056 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -1313,16 +1313,21 @@ static void ath_start_rfkill_poll(struct ath_softc *sc) | |||
1313 | wiphy_rfkill_start_polling(sc->hw->wiphy); | 1313 | wiphy_rfkill_start_polling(sc->hw->wiphy); |
1314 | } | 1314 | } |
1315 | 1315 | ||
1316 | static void ath_clean_core(struct ath_softc *sc); | ||
1317 | static void ath9k_uninit_hw(struct ath_softc *sc); | ||
1318 | |||
1316 | void ath_cleanup(struct ath_softc *sc) | 1319 | void ath_cleanup(struct ath_softc *sc) |
1317 | { | 1320 | { |
1318 | struct ath_hw *ah = sc->sc_ah; | 1321 | struct ath_hw *ah = sc->sc_ah; |
1319 | struct ath_common *common = ath9k_hw_common(ah); | 1322 | struct ath_common *common = ath9k_hw_common(ah); |
1320 | 1323 | ||
1321 | ath_detach(sc); | 1324 | ath_clean_core(sc); |
1322 | free_irq(sc->irq, sc); | 1325 | free_irq(sc->irq, sc); |
1323 | ath_bus_cleanup(common); | 1326 | ath_bus_cleanup(common); |
1324 | kfree(sc->sec_wiphy); | 1327 | kfree(sc->sec_wiphy); |
1325 | ieee80211_free_hw(sc->hw); | 1328 | ieee80211_free_hw(sc->hw); |
1329 | |||
1330 | ath9k_uninit_hw(sc); | ||
1326 | } | 1331 | } |
1327 | 1332 | ||
1328 | static void ath9k_uninit_hw(struct ath_softc *sc) | 1333 | static void ath9k_uninit_hw(struct ath_softc *sc) |
@@ -1336,7 +1341,7 @@ static void ath9k_uninit_hw(struct ath_softc *sc) | |||
1336 | sc->sc_ah = NULL; | 1341 | sc->sc_ah = NULL; |
1337 | } | 1342 | } |
1338 | 1343 | ||
1339 | void ath_detach(struct ath_softc *sc) | 1344 | static void ath_clean_core(struct ath_softc *sc) |
1340 | { | 1345 | { |
1341 | struct ieee80211_hw *hw = sc->hw; | 1346 | struct ieee80211_hw *hw = sc->hw; |
1342 | struct ath_hw *ah = sc->sc_ah; | 1347 | struct ath_hw *ah = sc->sc_ah; |
@@ -1375,7 +1380,11 @@ void ath_detach(struct ath_softc *sc) | |||
1375 | if ((sc->btcoex.no_stomp_timer) && | 1380 | if ((sc->btcoex.no_stomp_timer) && |
1376 | ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) | 1381 | ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) |
1377 | ath_gen_timer_free(ah, sc->btcoex.no_stomp_timer); | 1382 | ath_gen_timer_free(ah, sc->btcoex.no_stomp_timer); |
1383 | } | ||
1378 | 1384 | ||
1385 | void ath_detach(struct ath_softc *sc) | ||
1386 | { | ||
1387 | ath_clean_core(sc); | ||
1379 | ath9k_uninit_hw(sc); | 1388 | ath9k_uninit_hw(sc); |
1380 | } | 1389 | } |
1381 | 1390 | ||