wl1251: cancel elp_work early
authorGrazvydas Ignotas <notasas@gmail.com>
Wed, 27 Oct 2010 13:17:49 +0000 (16:17 +0300)
committerGrazvydas Ignotas <notasas@gmail.com>
Sat, 5 Mar 2011 21:18:01 +0000 (23:18 +0200)
While working on PS I've noticed elp_work is kicking rather often, and
sometimes the chip is put to sleep before 5ms delay expires. This
seems to happen because by the time wl1251_ps_elp_wakeup is called
elp_work might still be pending, and if the processing takes longer
(for example interrupts may take some time to process), elp_work might
get started and hit the mutex. After main thread finishes work it
calls wl1251_ps_elp_sleep, which can no longer cancel old work (as
it's already started) and schedules yet another work needlessly. The
elp_work then gets the mutex and puts the chip to sleep too early.

Fix this by cancelling work in wl1251_ps_elp_wakeup instead.

Signed-off-by: Grazvydas Ignotas <notasas@gmail.com>
drivers/net/wireless/wl12xx/wl1251_ps.c

index ff71cf3..f5b90a1 100644 (file)
@@ -60,7 +60,6 @@ void wl1251_ps_elp_sleep(struct wl1251 *wl)
        unsigned long delay;
 
        if (wl->psm) {
        unsigned long delay;
 
        if (wl->psm) {
-               cancel_delayed_work(&wl->elp_work);
                delay = msecs_to_jiffies(ELP_ENTRY_DELAY);
                ieee80211_queue_delayed_work(wl->hw, &wl->elp_work, delay);
        }
                delay = msecs_to_jiffies(ELP_ENTRY_DELAY);
                ieee80211_queue_delayed_work(wl->hw, &wl->elp_work, delay);
        }
@@ -71,6 +70,9 @@ int wl1251_ps_elp_wakeup(struct wl1251 *wl)
        unsigned long timeout, start;
        u32 elp_reg;
 
        unsigned long timeout, start;
        u32 elp_reg;
 
+       if (delayed_work_pending(&wl->elp_work))
+               cancel_delayed_work(&wl->elp_work);
+
        if (!wl->elp)
                return 0;
 
        if (!wl->elp)
                return 0;