diff options
| -rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 20 |
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 | ||
