aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c20
1 files changed, 14 insertions, 6 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
index 5c2706e50775..70bab5e089eb 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
@@ -2444,7 +2444,7 @@ static int brcmf_sdio_intr_rstatus(struct brcmf_sdio *bus)
2444 struct brcmf_core *buscore; 2444 struct brcmf_core *buscore;
2445 u32 addr; 2445 u32 addr;
2446 unsigned long val; 2446 unsigned long val;
2447 int ret; 2447 int n, ret;
2448 2448
2449 buscore = brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV); 2449 buscore = brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV);
2450 addr = buscore->base + offsetof(struct sdpcmd_regs, intstatus); 2450 addr = buscore->base + offsetof(struct sdpcmd_regs, intstatus);
@@ -2452,7 +2452,7 @@ static int brcmf_sdio_intr_rstatus(struct brcmf_sdio *bus)
2452 val = brcmf_sdiod_regrl(bus->sdiodev, addr, &ret); 2452 val = brcmf_sdiod_regrl(bus->sdiodev, addr, &ret);
2453 bus->sdcnt.f1regdata++; 2453 bus->sdcnt.f1regdata++;
2454 if (ret != 0) 2454 if (ret != 0)
2455 return ret; 2455 val = 0;
2456 2456
2457 val &= bus->hostintmask; 2457 val &= bus->hostintmask;
2458 atomic_set(&bus->fcstate, !!(val & I_HMB_FC_STATE)); 2458 atomic_set(&bus->fcstate, !!(val & I_HMB_FC_STATE));
@@ -2461,7 +2461,13 @@ static int brcmf_sdio_intr_rstatus(struct brcmf_sdio *bus)
2461 if (val) { 2461 if (val) {
2462 brcmf_sdiod_regwl(bus->sdiodev, addr, val, &ret); 2462 brcmf_sdiod_regwl(bus->sdiodev, addr, val, &ret);
2463 bus->sdcnt.f1regdata++; 2463 bus->sdcnt.f1regdata++;
2464 atomic_set_mask(val, &bus->intstatus); 2464 }
2465
2466 if (ret) {
2467 atomic_set(&bus->intstatus, 0);
2468 } else if (val) {
2469 for_each_set_bit(n, &val, 32)
2470 set_bit(n, (unsigned long *)&bus->intstatus.counter);
2465 } 2471 }
2466 2472
2467 return ret; 2473 return ret;
@@ -2473,7 +2479,7 @@ static void brcmf_sdio_dpc(struct brcmf_sdio *bus)
2473 unsigned long intstatus; 2479 unsigned long intstatus;
2474 uint txlimit = bus->txbound; /* Tx frames to send before resched */ 2480 uint txlimit = bus->txbound; /* Tx frames to send before resched */
2475 uint framecnt; /* Temporary counter of tx/rx frames */ 2481 uint framecnt; /* Temporary counter of tx/rx frames */
2476 int err = 0; 2482 int err = 0, n;
2477 2483
2478 brcmf_dbg(TRACE, "Enter\n"); 2484 brcmf_dbg(TRACE, "Enter\n");
2479 2485
@@ -2577,8 +2583,10 @@ static void brcmf_sdio_dpc(struct brcmf_sdio *bus)
2577 } 2583 }
2578 2584
2579 /* Keep still-pending events for next scheduling */ 2585 /* Keep still-pending events for next scheduling */
2580 if (intstatus) 2586 if (intstatus) {
2581 atomic_set_mask(intstatus, &bus->intstatus); 2587 for_each_set_bit(n, &intstatus, 32)
2588 set_bit(n, (unsigned long *)&bus->intstatus.counter);
2589 }
2582 2590
2583 brcmf_sdio_clrintr(bus); 2591 brcmf_sdio_clrintr(bus);
2584 2592