#endif                         /* DEBUG */
 
        uint clkstate;          /* State of sd and backplane clock(s) */
-       bool activity;          /* Activity flag for clock down */
        s32 idletime;           /* Control for activity timeout */
-       s32 idlecount;  /* Activity timeout counter */
-       s32 idleclock;  /* How to set bus driver when idle */
+       s32 idlecount;          /* Activity timeout counter */
+       s32 idleclock;          /* How to set bus driver when idle */
        bool rxflow_mode;       /* Rx flow control mode */
        bool rxflow;            /* Is rx flow control on */
        bool alp_only;          /* Don't use HT clock (ALP only) */
        struct workqueue_struct *brcmf_wq;
        struct work_struct datawork;
        atomic_t dpc_tskcnt;
+       atomic_t dpc_running;
 
        bool txoff;             /* Transmit flow-controlled */
        struct brcmf_sdio_count sdcnt;
        brcmf_dbg(SDIO, "Enter\n");
 
        /* Early exit if we're already there */
-       if (bus->clkstate == target) {
-               if (target == CLK_AVAIL) {
-                       brcmf_sdio_wd_timer(bus, BRCMF_WD_POLL_MS);
-                       bus->activity = true;
-               }
+       if (bus->clkstate == target)
                return 0;
-       }
 
        switch (target) {
        case CLK_AVAIL:
                /* Now request HT Avail on the backplane */
                brcmf_sdio_htclk(bus, true, pendok);
                brcmf_sdio_wd_timer(bus, BRCMF_WD_POLL_MS);
-               bus->activity = true;
                break;
 
        case CLK_SDONLY:
 
                /* Going to sleep */
                if (sleep) {
-                       /* Don't sleep if something is pending */
-                       if (atomic_read(&bus->intstatus) ||
-                           atomic_read(&bus->ipend) > 0 ||
-                           bus->ctrl_frame_stat ||
-                           (!atomic_read(&bus->fcstate) &&
-                           brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol) &&
-                           data_ok(bus))) {
-                                err = -EBUSY;
-                                goto done;
-                       }
-
                        clkcsr = brcmf_sdiod_regrb(bus->sdiodev,
                                                   SBSDIO_FUNC1_CHIPCLKCSR,
                                                   &err);
                                                  SBSDIO_ALP_AVAIL_REQ, &err);
                        }
                        err = brcmf_sdio_kso_control(bus, false);
-                       /* disable watchdog */
-                       if (!err)
-                               brcmf_sdio_wd_timer(bus, 0);
                } else {
-                       bus->idlecount = 0;
                        err = brcmf_sdio_kso_control(bus, true);
                }
                if (err) {
        queue_work(bus->brcmf_wq, &bus->datawork);
 }
 
-static bool brcmf_sdio_bus_watchdog(struct brcmf_sdio *bus)
+static void brcmf_sdio_bus_watchdog(struct brcmf_sdio *bus)
 {
        brcmf_dbg(TIMER, "Enter\n");
 
 #endif                         /* DEBUG */
 
        /* On idle timeout clear activity flag and/or turn off clock */
-       if ((bus->idletime > 0) && (bus->clkstate == CLK_AVAIL)) {
-               if (++bus->idlecount >= bus->idletime) {
+       if ((atomic_read(&bus->dpc_tskcnt) == 0) &&
+           (atomic_read(&bus->dpc_running) == 0) &&
+           (bus->idletime > 0) && (bus->clkstate == CLK_AVAIL)) {
+               bus->idlecount++;
+               if (bus->idlecount > bus->idletime) {
+                       brcmf_dbg(SDIO, "idle\n");
+                       sdio_claim_host(bus->sdiodev->func[1]);
+                       brcmf_sdio_wd_timer(bus, 0);
                        bus->idlecount = 0;
-                       if (bus->activity) {
-                               bus->activity = false;
-                               brcmf_sdio_wd_timer(bus, BRCMF_WD_POLL_MS);
-                       } else {
-                               brcmf_dbg(SDIO, "idle\n");
-                               sdio_claim_host(bus->sdiodev->func[1]);
-                               brcmf_sdio_bus_sleep(bus, true, false);
-                               sdio_release_host(bus->sdiodev->func[1]);
-                       }
+                       brcmf_sdio_bus_sleep(bus, true, false);
+                       sdio_release_host(bus->sdiodev->func[1]);
                }
+       } else {
+               bus->idlecount = 0;
        }
-
-       return (atomic_read(&bus->ipend) > 0);
 }
 
 static void brcmf_sdio_dataworker(struct work_struct *work)
                                              datawork);
 
        while (atomic_read(&bus->dpc_tskcnt)) {
+               atomic_set(&bus->dpc_running, 1);
                atomic_set(&bus->dpc_tskcnt, 0);
                brcmf_sdio_dpc(bus);
+               bus->idlecount = 0;
+               atomic_set(&bus->dpc_running, 0);
        }
        if (brcmf_sdiod_freezing(bus->sdiodev)) {
                brcmf_sdiod_change_state(bus->sdiodev, BRCMF_SDIOD_DOWN);
        }
        /* Initialize DPC thread */
        atomic_set(&bus->dpc_tskcnt, 0);
+       atomic_set(&bus->dpc_running, 0);
 
        /* Assign bus interface call back */
        bus->sdiodev->bus_if->dev = bus->sdiodev->dev;