Commit c98db0be authored by Hante Meuleman's avatar Hante Meuleman Committed by John W. Linville

brcmfmac: Use atomic functions for intstatus update.

The intstatus in sdio code can be updated from different
threads. To protect intstatus access, atomic functions are
used. The loop was replaced using atomic_set_mask().
Reviewed-by: default avatarArend Van Spriel <arend@broadcom.com>
Reviewed-by: default avatarFranky (Zhenhui) Lin <frankyl@broadcom.com>
Reviewed-by: default avatarPieter-Paul Giesberts <pieterpg@broadcom.com>
Reviewed-by: default avatarDaniel (Deognyoun) Kim <dekim@broadcom.com>
Signed-off-by: default avatarHante Meuleman <meuleman@broadcom.com>
Signed-off-by: default avatarArend van Spriel <arend@broadcom.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 2259ba38
...@@ -2449,7 +2449,7 @@ static int brcmf_sdio_intr_rstatus(struct brcmf_sdio *bus) ...@@ -2449,7 +2449,7 @@ static int brcmf_sdio_intr_rstatus(struct brcmf_sdio *bus)
struct brcmf_core *buscore; struct brcmf_core *buscore;
u32 addr; u32 addr;
unsigned long val; unsigned long val;
int n, ret; int ret;
buscore = brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV); buscore = brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV);
addr = buscore->base + offsetof(struct sdpcmd_regs, intstatus); addr = buscore->base + offsetof(struct sdpcmd_regs, intstatus);
...@@ -2457,7 +2457,7 @@ static int brcmf_sdio_intr_rstatus(struct brcmf_sdio *bus) ...@@ -2457,7 +2457,7 @@ static int brcmf_sdio_intr_rstatus(struct brcmf_sdio *bus)
val = brcmf_sdiod_regrl(bus->sdiodev, addr, &ret); val = brcmf_sdiod_regrl(bus->sdiodev, addr, &ret);
bus->sdcnt.f1regdata++; bus->sdcnt.f1regdata++;
if (ret != 0) if (ret != 0)
val = 0; return ret;
val &= bus->hostintmask; val &= bus->hostintmask;
atomic_set(&bus->fcstate, !!(val & I_HMB_FC_STATE)); atomic_set(&bus->fcstate, !!(val & I_HMB_FC_STATE));
...@@ -2466,13 +2466,7 @@ static int brcmf_sdio_intr_rstatus(struct brcmf_sdio *bus) ...@@ -2466,13 +2466,7 @@ static int brcmf_sdio_intr_rstatus(struct brcmf_sdio *bus)
if (val) { if (val) {
brcmf_sdiod_regwl(bus->sdiodev, addr, val, &ret); brcmf_sdiod_regwl(bus->sdiodev, addr, val, &ret);
bus->sdcnt.f1regdata++; bus->sdcnt.f1regdata++;
} atomic_set_mask(val, &bus->intstatus);
if (ret) {
atomic_set(&bus->intstatus, 0);
} else if (val) {
for_each_set_bit(n, &val, 32)
set_bit(n, (unsigned long *)&bus->intstatus.counter);
} }
return ret; return ret;
...@@ -2484,7 +2478,7 @@ static void brcmf_sdio_dpc(struct brcmf_sdio *bus) ...@@ -2484,7 +2478,7 @@ static void brcmf_sdio_dpc(struct brcmf_sdio *bus)
unsigned long intstatus; unsigned long intstatus;
uint txlimit = bus->txbound; /* Tx frames to send before resched */ uint txlimit = bus->txbound; /* Tx frames to send before resched */
uint framecnt; /* Temporary counter of tx/rx frames */ uint framecnt; /* Temporary counter of tx/rx frames */
int err = 0, n; int err = 0;
brcmf_dbg(TRACE, "Enter\n"); brcmf_dbg(TRACE, "Enter\n");
...@@ -2588,10 +2582,8 @@ static void brcmf_sdio_dpc(struct brcmf_sdio *bus) ...@@ -2588,10 +2582,8 @@ static void brcmf_sdio_dpc(struct brcmf_sdio *bus)
} }
/* Keep still-pending events for next scheduling */ /* Keep still-pending events for next scheduling */
if (intstatus) { if (intstatus)
for_each_set_bit(n, &intstatus, 32) atomic_set_mask(intstatus, &bus->intstatus);
set_bit(n, (unsigned long *)&bus->intstatus.counter);
}
brcmf_sdio_clrintr(bus); brcmf_sdio_clrintr(bus);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment