aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/brcm80211/brcmfmac
diff options
context:
space:
mode:
authorHante Meuleman <meuleman@broadcom.com>2015-03-06 12:40:39 -0500
committerKalle Valo <kvalo@codeaurora.org>2015-03-13 09:16:32 -0400
commitb441ba8dc34136dc418d85299757514c3a08913d (patch)
tree8368347547ed455143a75cb5556b9483ad564dfa /drivers/net/wireless/brcm80211/brcmfmac
parentde6878c8354d1524940055fe1b802c799f4fc318 (diff)
brcmfmac: Simplify watchdog sleep.
The watchdog thread is used to put the SDIO bus to sleep when the system is idling. This patch simplifies the way it is determined when sleep can be entered. Reviewed-by: Arend Van Spriel <arend@broadcom.com> Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com> Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com> Reviewed-by: Daniel (Deognyoun) Kim <dekim@broadcom.com> Signed-off-by: Hante Meuleman <meuleman@broadcom.com> Signed-off-by: Arend van Spriel <arend@broadcom.com> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Diffstat (limited to 'drivers/net/wireless/brcm80211/brcmfmac')
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/sdio.c60
1 files changed, 21 insertions, 39 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
index c54ba4f8b489..161acd046451 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
@@ -485,10 +485,9 @@ struct brcmf_sdio {
485#endif /* DEBUG */ 485#endif /* DEBUG */
486 486
487 uint clkstate; /* State of sd and backplane clock(s) */ 487 uint clkstate; /* State of sd and backplane clock(s) */
488 bool activity; /* Activity flag for clock down */
489 s32 idletime; /* Control for activity timeout */ 488 s32 idletime; /* Control for activity timeout */
490 s32 idlecount; /* Activity timeout counter */ 489 s32 idlecount; /* Activity timeout counter */
491 s32 idleclock; /* How to set bus driver when idle */ 490 s32 idleclock; /* How to set bus driver when idle */
492 bool rxflow_mode; /* Rx flow control mode */ 491 bool rxflow_mode; /* Rx flow control mode */
493 bool rxflow; /* Is rx flow control on */ 492 bool rxflow; /* Is rx flow control on */
494 bool alp_only; /* Don't use HT clock (ALP only) */ 493 bool alp_only; /* Don't use HT clock (ALP only) */
@@ -511,6 +510,7 @@ struct brcmf_sdio {
511 struct workqueue_struct *brcmf_wq; 510 struct workqueue_struct *brcmf_wq;
512 struct work_struct datawork; 511 struct work_struct datawork;
513 atomic_t dpc_tskcnt; 512 atomic_t dpc_tskcnt;
513 atomic_t dpc_running;
514 514
515 bool txoff; /* Transmit flow-controlled */ 515 bool txoff; /* Transmit flow-controlled */
516 struct brcmf_sdio_count sdcnt; 516 struct brcmf_sdio_count sdcnt;
@@ -959,13 +959,8 @@ static int brcmf_sdio_clkctl(struct brcmf_sdio *bus, uint target, bool pendok)
959 brcmf_dbg(SDIO, "Enter\n"); 959 brcmf_dbg(SDIO, "Enter\n");
960 960
961 /* Early exit if we're already there */ 961 /* Early exit if we're already there */
962 if (bus->clkstate == target) { 962 if (bus->clkstate == target)
963 if (target == CLK_AVAIL) {
964 brcmf_sdio_wd_timer(bus, BRCMF_WD_POLL_MS);
965 bus->activity = true;
966 }
967 return 0; 963 return 0;
968 }
969 964
970 switch (target) { 965 switch (target) {
971 case CLK_AVAIL: 966 case CLK_AVAIL:
@@ -975,7 +970,6 @@ static int brcmf_sdio_clkctl(struct brcmf_sdio *bus, uint target, bool pendok)
975 /* Now request HT Avail on the backplane */ 970 /* Now request HT Avail on the backplane */
976 brcmf_sdio_htclk(bus, true, pendok); 971 brcmf_sdio_htclk(bus, true, pendok);
977 brcmf_sdio_wd_timer(bus, BRCMF_WD_POLL_MS); 972 brcmf_sdio_wd_timer(bus, BRCMF_WD_POLL_MS);
978 bus->activity = true;
979 break; 973 break;
980 974
981 case CLK_SDONLY: 975 case CLK_SDONLY:
@@ -1024,17 +1018,6 @@ brcmf_sdio_bus_sleep(struct brcmf_sdio *bus, bool sleep, bool pendok)
1024 1018
1025 /* Going to sleep */ 1019 /* Going to sleep */
1026 if (sleep) { 1020 if (sleep) {
1027 /* Don't sleep if something is pending */
1028 if (atomic_read(&bus->intstatus) ||
1029 atomic_read(&bus->ipend) > 0 ||
1030 bus->ctrl_frame_stat ||
1031 (!atomic_read(&bus->fcstate) &&
1032 brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol) &&
1033 data_ok(bus))) {
1034 err = -EBUSY;
1035 goto done;
1036 }
1037
1038 clkcsr = brcmf_sdiod_regrb(bus->sdiodev, 1021 clkcsr = brcmf_sdiod_regrb(bus->sdiodev,
1039 SBSDIO_FUNC1_CHIPCLKCSR, 1022 SBSDIO_FUNC1_CHIPCLKCSR,
1040 &err); 1023 &err);
@@ -1045,11 +1028,7 @@ brcmf_sdio_bus_sleep(struct brcmf_sdio *bus, bool sleep, bool pendok)
1045 SBSDIO_ALP_AVAIL_REQ, &err); 1028 SBSDIO_ALP_AVAIL_REQ, &err);
1046 } 1029 }
1047 err = brcmf_sdio_kso_control(bus, false); 1030 err = brcmf_sdio_kso_control(bus, false);
1048 /* disable watchdog */
1049 if (!err)
1050 brcmf_sdio_wd_timer(bus, 0);
1051 } else { 1031 } else {
1052 bus->idlecount = 0;
1053 err = brcmf_sdio_kso_control(bus, true); 1032 err = brcmf_sdio_kso_control(bus, true);
1054 } 1033 }
1055 if (err) { 1034 if (err) {
@@ -3566,7 +3545,7 @@ void brcmf_sdio_isr(struct brcmf_sdio *bus)
3566 queue_work(bus->brcmf_wq, &bus->datawork); 3545 queue_work(bus->brcmf_wq, &bus->datawork);
3567} 3546}
3568 3547
3569static bool brcmf_sdio_bus_watchdog(struct brcmf_sdio *bus) 3548static void brcmf_sdio_bus_watchdog(struct brcmf_sdio *bus)
3570{ 3549{
3571 brcmf_dbg(TIMER, "Enter\n"); 3550 brcmf_dbg(TIMER, "Enter\n");
3572 3551
@@ -3627,22 +3606,21 @@ static bool brcmf_sdio_bus_watchdog(struct brcmf_sdio *bus)
3627#endif /* DEBUG */ 3606#endif /* DEBUG */
3628 3607
3629 /* On idle timeout clear activity flag and/or turn off clock */ 3608 /* On idle timeout clear activity flag and/or turn off clock */
3630 if ((bus->idletime > 0) && (bus->clkstate == CLK_AVAIL)) { 3609 if ((atomic_read(&bus->dpc_tskcnt) == 0) &&
3631 if (++bus->idlecount >= bus->idletime) { 3610 (atomic_read(&bus->dpc_running) == 0) &&
3611 (bus->idletime > 0) && (bus->clkstate == CLK_AVAIL)) {
3612 bus->idlecount++;
3613 if (bus->idlecount > bus->idletime) {
3614 brcmf_dbg(SDIO, "idle\n");
3615 sdio_claim_host(bus->sdiodev->func[1]);
3616 brcmf_sdio_wd_timer(bus, 0);
3632 bus->idlecount = 0; 3617 bus->idlecount = 0;
3633 if (bus->activity) { 3618 brcmf_sdio_bus_sleep(bus, true, false);
3634 bus->activity = false; 3619 sdio_release_host(bus->sdiodev->func[1]);
3635 brcmf_sdio_wd_timer(bus, BRCMF_WD_POLL_MS);
3636 } else {
3637 brcmf_dbg(SDIO, "idle\n");
3638 sdio_claim_host(bus->sdiodev->func[1]);
3639 brcmf_sdio_bus_sleep(bus, true, false);
3640 sdio_release_host(bus->sdiodev->func[1]);
3641 }
3642 } 3620 }
3621 } else {
3622 bus->idlecount = 0;
3643 } 3623 }
3644
3645 return (atomic_read(&bus->ipend) > 0);
3646} 3624}
3647 3625
3648static void brcmf_sdio_dataworker(struct work_struct *work) 3626static void brcmf_sdio_dataworker(struct work_struct *work)
@@ -3651,8 +3629,11 @@ static void brcmf_sdio_dataworker(struct work_struct *work)
3651 datawork); 3629 datawork);
3652 3630
3653 while (atomic_read(&bus->dpc_tskcnt)) { 3631 while (atomic_read(&bus->dpc_tskcnt)) {
3632 atomic_set(&bus->dpc_running, 1);
3654 atomic_set(&bus->dpc_tskcnt, 0); 3633 atomic_set(&bus->dpc_tskcnt, 0);
3655 brcmf_sdio_dpc(bus); 3634 brcmf_sdio_dpc(bus);
3635 bus->idlecount = 0;
3636 atomic_set(&bus->dpc_running, 0);
3656 } 3637 }
3657 if (brcmf_sdiod_freezing(bus->sdiodev)) { 3638 if (brcmf_sdiod_freezing(bus->sdiodev)) {
3658 brcmf_sdiod_change_state(bus->sdiodev, BRCMF_SDIOD_DOWN); 3639 brcmf_sdiod_change_state(bus->sdiodev, BRCMF_SDIOD_DOWN);
@@ -4154,6 +4135,7 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
4154 } 4135 }
4155 /* Initialize DPC thread */ 4136 /* Initialize DPC thread */
4156 atomic_set(&bus->dpc_tskcnt, 0); 4137 atomic_set(&bus->dpc_tskcnt, 0);
4138 atomic_set(&bus->dpc_running, 0);
4157 4139
4158 /* Assign bus interface call back */ 4140 /* Assign bus interface call back */
4159 bus->sdiodev->bus_if->dev = bus->sdiodev->dev; 4141 bus->sdiodev->bus_if->dev = bus->sdiodev->dev;