unsigned long orig_trans_start = 0;
 
        mutex_lock(&bcm->mutex);
+       /* keep from doing and rearming periodic work if shutting down */
+       if (bcm43xx_status(bcm) == BCM43xx_STAT_UNINIT)
+               goto unlock_mutex;
        if (unlikely(bcm->periodic_state % 60 == 0)) {
                /* Periodic work will take a long time, so we want it to
                 * be preemtible.
        mmiowb();
        bcm->periodic_state++;
        spin_unlock_irqrestore(&bcm->irq_lock, flags);
+unlock_mutex:
        mutex_unlock(&bcm->mutex);
 }
 
-void bcm43xx_periodic_tasks_delete(struct bcm43xx_private *bcm)
-{
-       cancel_rearming_delayed_work(&bcm->periodic_work);
-}
-
 void bcm43xx_periodic_tasks_setup(struct bcm43xx_private *bcm)
 {
        struct delayed_work *work = &bcm->periodic_work;
        return err;
 }
 
+void bcm43xx_cancel_work(struct bcm43xx_private *bcm)
+{
+       /* The system must be unlocked when this routine is entered.
+        * If not, the next 2 steps may deadlock */
+       cancel_work_sync(&bcm->restart_work);
+       cancel_delayed_work_sync(&bcm->periodic_work);
+}
+
 static int bcm43xx_shutdown_all_wireless_cores(struct bcm43xx_private *bcm)
 {
        int ret = 0;
 {
        bcm43xx_rng_exit(bcm);
        bcm43xx_sysfs_unregister(bcm);
-       bcm43xx_periodic_tasks_delete(bcm);
+
+       mutex_lock(&(bcm)->mutex);
+       bcm43xx_set_status(bcm, BCM43xx_STAT_UNINIT);
+       mutex_unlock(&(bcm)->mutex);
+
+       bcm43xx_cancel_work(bcm);
 
        mutex_lock(&(bcm)->mutex);
        bcm43xx_shutdown_all_wireless_cores(bcm);
        err = bcm43xx_disable_interrupts_sync(bcm);
        assert(!err);
        bcm43xx_free_board(bcm);
-       flush_scheduled_work();
+       bcm43xx_cancel_work(bcm);
 
        return 0;
 }
        struct bcm43xx_phyinfo *phy;
        int err = -ENODEV;
 
+       bcm43xx_cancel_work(bcm);
        mutex_lock(&(bcm)->mutex);
        if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) {
-               bcm43xx_periodic_tasks_delete(bcm);
                phy = bcm43xx_current_phy(bcm);
                err = bcm43xx_select_wireless_core(bcm, phy->type);
                if (!err)