diff options
-rw-r--r-- | drivers/net/wireless/bcm43xx/bcm43xx_main.c | 28 | ||||
-rw-r--r-- | drivers/net/wireless/bcm43xx/bcm43xx_main.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c | 2 |
3 files changed, 22 insertions, 10 deletions
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c index c5d6753a55ea..dfbd01eaaf34 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c | |||
@@ -3183,6 +3183,9 @@ static void bcm43xx_periodic_work_handler(struct work_struct *work) | |||
3183 | unsigned long orig_trans_start = 0; | 3183 | unsigned long orig_trans_start = 0; |
3184 | 3184 | ||
3185 | mutex_lock(&bcm->mutex); | 3185 | mutex_lock(&bcm->mutex); |
3186 | /* keep from doing and rearming periodic work if shutting down */ | ||
3187 | if (bcm43xx_status(bcm) == BCM43xx_STAT_UNINIT) | ||
3188 | goto unlock_mutex; | ||
3186 | if (unlikely(bcm->periodic_state % 60 == 0)) { | 3189 | if (unlikely(bcm->periodic_state % 60 == 0)) { |
3187 | /* Periodic work will take a long time, so we want it to | 3190 | /* Periodic work will take a long time, so we want it to |
3188 | * be preemtible. | 3191 | * be preemtible. |
@@ -3228,14 +3231,10 @@ static void bcm43xx_periodic_work_handler(struct work_struct *work) | |||
3228 | mmiowb(); | 3231 | mmiowb(); |
3229 | bcm->periodic_state++; | 3232 | bcm->periodic_state++; |
3230 | spin_unlock_irqrestore(&bcm->irq_lock, flags); | 3233 | spin_unlock_irqrestore(&bcm->irq_lock, flags); |
3234 | unlock_mutex: | ||
3231 | mutex_unlock(&bcm->mutex); | 3235 | mutex_unlock(&bcm->mutex); |
3232 | } | 3236 | } |
3233 | 3237 | ||
3234 | void bcm43xx_periodic_tasks_delete(struct bcm43xx_private *bcm) | ||
3235 | { | ||
3236 | cancel_rearming_delayed_work(&bcm->periodic_work); | ||
3237 | } | ||
3238 | |||
3239 | void bcm43xx_periodic_tasks_setup(struct bcm43xx_private *bcm) | 3238 | void bcm43xx_periodic_tasks_setup(struct bcm43xx_private *bcm) |
3240 | { | 3239 | { |
3241 | struct delayed_work *work = &bcm->periodic_work; | 3240 | struct delayed_work *work = &bcm->periodic_work; |
@@ -3285,6 +3284,14 @@ static int bcm43xx_rng_init(struct bcm43xx_private *bcm) | |||
3285 | return err; | 3284 | return err; |
3286 | } | 3285 | } |
3287 | 3286 | ||
3287 | void bcm43xx_cancel_work(struct bcm43xx_private *bcm) | ||
3288 | { | ||
3289 | /* The system must be unlocked when this routine is entered. | ||
3290 | * If not, the next 2 steps may deadlock */ | ||
3291 | cancel_work_sync(&bcm->restart_work); | ||
3292 | cancel_delayed_work_sync(&bcm->periodic_work); | ||
3293 | } | ||
3294 | |||
3288 | static int bcm43xx_shutdown_all_wireless_cores(struct bcm43xx_private *bcm) | 3295 | static int bcm43xx_shutdown_all_wireless_cores(struct bcm43xx_private *bcm) |
3289 | { | 3296 | { |
3290 | int ret = 0; | 3297 | int ret = 0; |
@@ -3321,7 +3328,12 @@ static void bcm43xx_free_board(struct bcm43xx_private *bcm) | |||
3321 | { | 3328 | { |
3322 | bcm43xx_rng_exit(bcm); | 3329 | bcm43xx_rng_exit(bcm); |
3323 | bcm43xx_sysfs_unregister(bcm); | 3330 | bcm43xx_sysfs_unregister(bcm); |
3324 | bcm43xx_periodic_tasks_delete(bcm); | 3331 | |
3332 | mutex_lock(&(bcm)->mutex); | ||
3333 | bcm43xx_set_status(bcm, BCM43xx_STAT_UNINIT); | ||
3334 | mutex_unlock(&(bcm)->mutex); | ||
3335 | |||
3336 | bcm43xx_cancel_work(bcm); | ||
3325 | 3337 | ||
3326 | mutex_lock(&(bcm)->mutex); | 3338 | mutex_lock(&(bcm)->mutex); |
3327 | bcm43xx_shutdown_all_wireless_cores(bcm); | 3339 | bcm43xx_shutdown_all_wireless_cores(bcm); |
@@ -4016,7 +4028,7 @@ static int bcm43xx_net_stop(struct net_device *net_dev) | |||
4016 | err = bcm43xx_disable_interrupts_sync(bcm); | 4028 | err = bcm43xx_disable_interrupts_sync(bcm); |
4017 | assert(!err); | 4029 | assert(!err); |
4018 | bcm43xx_free_board(bcm); | 4030 | bcm43xx_free_board(bcm); |
4019 | flush_scheduled_work(); | 4031 | bcm43xx_cancel_work(bcm); |
4020 | 4032 | ||
4021 | return 0; | 4033 | return 0; |
4022 | } | 4034 | } |
@@ -4148,9 +4160,9 @@ static void bcm43xx_chip_reset(struct work_struct *work) | |||
4148 | struct bcm43xx_phyinfo *phy; | 4160 | struct bcm43xx_phyinfo *phy; |
4149 | int err = -ENODEV; | 4161 | int err = -ENODEV; |
4150 | 4162 | ||
4163 | bcm43xx_cancel_work(bcm); | ||
4151 | mutex_lock(&(bcm)->mutex); | 4164 | mutex_lock(&(bcm)->mutex); |
4152 | if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) { | 4165 | if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) { |
4153 | bcm43xx_periodic_tasks_delete(bcm); | ||
4154 | phy = bcm43xx_current_phy(bcm); | 4166 | phy = bcm43xx_current_phy(bcm); |
4155 | err = bcm43xx_select_wireless_core(bcm, phy->type); | 4167 | err = bcm43xx_select_wireless_core(bcm, phy->type); |
4156 | if (!err) | 4168 | if (!err) |
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.h b/drivers/net/wireless/bcm43xx/bcm43xx_main.h index c8f3c532bab5..14cfbeb582ef 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_main.h +++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.h | |||
@@ -122,7 +122,7 @@ void bcm43xx_wireless_core_reset(struct bcm43xx_private *bcm, int connect_phy); | |||
122 | void bcm43xx_mac_suspend(struct bcm43xx_private *bcm); | 122 | void bcm43xx_mac_suspend(struct bcm43xx_private *bcm); |
123 | void bcm43xx_mac_enable(struct bcm43xx_private *bcm); | 123 | void bcm43xx_mac_enable(struct bcm43xx_private *bcm); |
124 | 124 | ||
125 | void bcm43xx_periodic_tasks_delete(struct bcm43xx_private *bcm); | 125 | void bcm43xx_cancel_work(struct bcm43xx_private *bcm); |
126 | void bcm43xx_periodic_tasks_setup(struct bcm43xx_private *bcm); | 126 | void bcm43xx_periodic_tasks_setup(struct bcm43xx_private *bcm); |
127 | 127 | ||
128 | void bcm43xx_controller_restart(struct bcm43xx_private *bcm, const char *reason); | 128 | void bcm43xx_controller_restart(struct bcm43xx_private *bcm, const char *reason); |
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c b/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c index c71b998a3694..8ab5f93d192a 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c | |||
@@ -327,7 +327,7 @@ static ssize_t bcm43xx_attr_phymode_store(struct device *dev, | |||
327 | goto out; | 327 | goto out; |
328 | } | 328 | } |
329 | 329 | ||
330 | bcm43xx_periodic_tasks_delete(bcm); | 330 | bcm43xx_cancel_work(bcm); |
331 | mutex_lock(&(bcm)->mutex); | 331 | mutex_lock(&(bcm)->mutex); |
332 | err = bcm43xx_select_wireless_core(bcm, phytype); | 332 | err = bcm43xx_select_wireless_core(bcm, phytype); |
333 | if (!err) | 333 | if (!err) |