Commit 7cdf57d3 authored by Franky Lin's avatar Franky Lin Committed by John W. Linville

brcmfmac: decrease the range of SDIO access lock

Semaphore sdsem which protects consecutive SDIO bus access is used
to lock down unnecessary wide range. Decrease the locking range
provides the capability of parallel processing.
Signed-off-by: default avatarFranky Lin <frankyl@broadcom.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent dd43a01c
...@@ -1274,6 +1274,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) ...@@ -1274,6 +1274,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
* read directly into the chained packet, or allocate a large * read directly into the chained packet, or allocate a large
* packet and and copy into the chain. * packet and and copy into the chain.
*/ */
down(&bus->sdsem);
if (usechain) { if (usechain) {
errcode = brcmf_sdcard_recv_chain(bus->sdiodev, errcode = brcmf_sdcard_recv_chain(bus->sdiodev,
bus->sdiodev->sbwad, bus->sdiodev->sbwad,
...@@ -1295,6 +1296,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) ...@@ -1295,6 +1296,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
dlen); dlen);
errcode = -1; errcode = -1;
} }
up(&bus->sdsem);
bus->sdcnt.f2rxdata++; bus->sdcnt.f2rxdata++;
/* On failure, kill the superframe, allow a couple retries */ /* On failure, kill the superframe, allow a couple retries */
...@@ -1399,11 +1401,8 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) ...@@ -1399,11 +1401,8 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
pfirst->prev); pfirst->prev);
} }
/* sent any remaining packets up */ /* sent any remaining packets up */
if (bus->glom.qlen) { if (bus->glom.qlen)
up(&bus->sdsem);
brcmf_rx_frame(bus->sdiodev->dev, ifidx, &bus->glom); brcmf_rx_frame(bus->sdiodev->dev, ifidx, &bus->glom);
down(&bus->sdsem);
}
bus->sdcnt.rxglomframes++; bus->sdcnt.rxglomframes++;
bus->sdcnt.rxglompkts += bus->glom.qlen; bus->sdcnt.rxglompkts += bus->glom.qlen;
...@@ -1586,6 +1585,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) ...@@ -1586,6 +1585,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
rd->len_left = rd->len; rd->len_left = rd->len;
/* read header first for unknow frame length */ /* read header first for unknow frame length */
down(&bus->sdsem);
if (!rd->len) { if (!rd->len) {
sdret = brcmf_sdcard_recv_buf(bus->sdiodev, sdret = brcmf_sdcard_recv_buf(bus->sdiodev,
bus->sdiodev->sbwad, bus->sdiodev->sbwad,
...@@ -1598,6 +1598,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) ...@@ -1598,6 +1598,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
sdret); sdret);
bus->sdcnt.rx_hdrfail++; bus->sdcnt.rx_hdrfail++;
brcmf_sdbrcm_rxfail(bus, true, true); brcmf_sdbrcm_rxfail(bus, true, true);
up(&bus->sdsem);
continue; continue;
} }
...@@ -1607,6 +1608,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) ...@@ -1607,6 +1608,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
if (!brcmf_sdio_hdparser(bus, bus->rxhdr, rd, if (!brcmf_sdio_hdparser(bus, bus->rxhdr, rd,
BRCMF_SDIO_FT_NORMAL)) { BRCMF_SDIO_FT_NORMAL)) {
up(&bus->sdsem);
if (!bus->rxpending) if (!bus->rxpending)
break; break;
else else
...@@ -1622,6 +1624,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) ...@@ -1622,6 +1624,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
rd->len_nxtfrm = 0; rd->len_nxtfrm = 0;
/* treat all packet as event if we don't know */ /* treat all packet as event if we don't know */
rd->channel = SDPCM_EVENT_CHANNEL; rd->channel = SDPCM_EVENT_CHANNEL;
up(&bus->sdsem);
continue; continue;
} }
rd->len_left = rd->len > BRCMF_FIRSTREAD ? rd->len_left = rd->len > BRCMF_FIRSTREAD ?
...@@ -1639,6 +1642,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) ...@@ -1639,6 +1642,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
bus->sdiodev->bus_if->dstats.rx_dropped++; bus->sdiodev->bus_if->dstats.rx_dropped++;
brcmf_sdbrcm_rxfail(bus, false, brcmf_sdbrcm_rxfail(bus, false,
RETRYCHAN(rd->channel)); RETRYCHAN(rd->channel));
up(&bus->sdsem);
continue; continue;
} }
skb_pull(pkt, head_read); skb_pull(pkt, head_read);
...@@ -1647,6 +1651,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) ...@@ -1647,6 +1651,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
sdret = brcmf_sdcard_recv_pkt(bus->sdiodev, bus->sdiodev->sbwad, sdret = brcmf_sdcard_recv_pkt(bus->sdiodev, bus->sdiodev->sbwad,
SDIO_FUNC_2, F2SYNC, pkt); SDIO_FUNC_2, F2SYNC, pkt);
bus->sdcnt.f2rxdata++; bus->sdcnt.f2rxdata++;
up(&bus->sdsem);
if (sdret < 0) { if (sdret < 0) {
brcmf_dbg(ERROR, "read %d bytes from channel %d failed: %d\n", brcmf_dbg(ERROR, "read %d bytes from channel %d failed: %d\n",
...@@ -1749,10 +1754,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) ...@@ -1749,10 +1754,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
continue; continue;
} }
/* Unlock during rx call */
up(&bus->sdsem);
brcmf_rx_packet(bus->sdiodev->dev, ifidx, pkt); brcmf_rx_packet(bus->sdiodev->dev, ifidx, pkt);
down(&bus->sdsem);
} }
rxcount = maxframes - rxleft; rxcount = maxframes - rxleft;
...@@ -1772,9 +1774,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) ...@@ -1772,9 +1774,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
static void static void
brcmf_sdbrcm_wait_for_event(struct brcmf_sdio *bus, bool *lockvar) brcmf_sdbrcm_wait_for_event(struct brcmf_sdio *bus, bool *lockvar)
{ {
up(&bus->sdsem);
wait_event_interruptible_timeout(bus->ctrl_wait, !*lockvar, HZ * 2); wait_event_interruptible_timeout(bus->ctrl_wait, !*lockvar, HZ * 2);
down(&bus->sdsem);
return; return;
} }
...@@ -1879,6 +1879,7 @@ static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt, ...@@ -1879,6 +1879,7 @@ static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt,
if (len & (ALIGNMENT - 1)) if (len & (ALIGNMENT - 1))
len = roundup(len, ALIGNMENT); len = roundup(len, ALIGNMENT);
down(&bus->sdsem);
ret = brcmf_sdcard_send_pkt(bus->sdiodev, bus->sdiodev->sbwad, ret = brcmf_sdcard_send_pkt(bus->sdiodev, bus->sdiodev->sbwad,
SDIO_FUNC_2, F2SYNC, pkt); SDIO_FUNC_2, F2SYNC, pkt);
bus->sdcnt.f2txdata++; bus->sdcnt.f2txdata++;
...@@ -1906,15 +1907,14 @@ static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt, ...@@ -1906,15 +1907,14 @@ static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt,
} }
} }
up(&bus->sdsem);
if (ret == 0) if (ret == 0)
bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP; bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP;
done: done:
/* restore pkt buffer pointer before calling tx complete routine */ /* restore pkt buffer pointer before calling tx complete routine */
skb_pull(pkt, SDPCM_HDRLEN + pad); skb_pull(pkt, SDPCM_HDRLEN + pad);
up(&bus->sdsem);
brcmf_txcomplete(bus->sdiodev->dev, pkt, ret != 0); brcmf_txcomplete(bus->sdiodev->dev, pkt, ret != 0);
down(&bus->sdsem);
if (free_pkt) if (free_pkt)
brcmu_pkt_buf_free_skb(pkt); brcmu_pkt_buf_free_skb(pkt);
...@@ -1955,9 +1955,11 @@ static uint brcmf_sdbrcm_sendfromq(struct brcmf_sdio *bus, uint maxframes) ...@@ -1955,9 +1955,11 @@ static uint brcmf_sdbrcm_sendfromq(struct brcmf_sdio *bus, uint maxframes)
/* In poll mode, need to check for other events */ /* In poll mode, need to check for other events */
if (!bus->intr && cnt) { if (!bus->intr && cnt) {
/* Check device status, signal pending interrupt */ /* Check device status, signal pending interrupt */
down(&bus->sdsem);
ret = r_sdreg32(bus, &intstatus, ret = r_sdreg32(bus, &intstatus,
offsetof(struct sdpcmd_regs, offsetof(struct sdpcmd_regs,
intstatus)); intstatus));
up(&bus->sdsem);
bus->sdcnt.f2txdata++; bus->sdcnt.f2txdata++;
if (ret != 0) if (ret != 0)
break; break;
...@@ -2028,6 +2030,7 @@ static void brcmf_sdbrcm_bus_stop(struct device *dev) ...@@ -2028,6 +2030,7 @@ static void brcmf_sdbrcm_bus_stop(struct device *dev)
/* Turn off the backplane clock (only) */ /* Turn off the backplane clock (only) */
brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false); brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false);
up(&bus->sdsem);
/* Clear the data packet queues */ /* Clear the data packet queues */
brcmu_pktq_flush(&bus->txq, true, NULL, NULL); brcmu_pktq_flush(&bus->txq, true, NULL, NULL);
...@@ -2046,8 +2049,6 @@ static void brcmf_sdbrcm_bus_stop(struct device *dev) ...@@ -2046,8 +2049,6 @@ static void brcmf_sdbrcm_bus_stop(struct device *dev)
/* Reset some F2 state stuff */ /* Reset some F2 state stuff */
bus->rxskip = false; bus->rxskip = false;
bus->tx_seq = bus->rx_seq = 0; bus->tx_seq = bus->rx_seq = 0;
up(&bus->sdsem);
} }
#ifdef CONFIG_BRCMFMAC_SDIO_OOB #ifdef CONFIG_BRCMFMAC_SDIO_OOB
...@@ -2216,6 +2217,8 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) ...@@ -2216,6 +2217,8 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
intstatus |= brcmf_sdbrcm_hostmail(bus); intstatus |= brcmf_sdbrcm_hostmail(bus);
} }
up(&bus->sdsem);
/* Generally don't ask for these, can get CRC errors... */ /* Generally don't ask for these, can get CRC errors... */
if (intstatus & I_WR_OOSYNC) { if (intstatus & I_WR_OOSYNC) {
brcmf_dbg(ERROR, "Dongle reports WR_OOSYNC\n"); brcmf_dbg(ERROR, "Dongle reports WR_OOSYNC\n");
...@@ -2262,6 +2265,7 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) ...@@ -2262,6 +2265,7 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
(bus->clkstate == CLK_AVAIL)) { (bus->clkstate == CLK_AVAIL)) {
int i; int i;
down(&bus->sdsem);
err = brcmf_sdcard_send_buf(bus->sdiodev, bus->sdiodev->sbwad, err = brcmf_sdcard_send_buf(bus->sdiodev, bus->sdiodev->sbwad,
SDIO_FUNC_2, F2SYNC, bus->ctrl_frame_buf, SDIO_FUNC_2, F2SYNC, bus->ctrl_frame_buf,
(u32) bus->ctrl_frame_len); (u32) bus->ctrl_frame_len);
...@@ -2295,6 +2299,7 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) ...@@ -2295,6 +2299,7 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
} else { } else {
bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP; bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP;
} }
up(&bus->sdsem);
bus->ctrl_frame_stat = false; bus->ctrl_frame_stat = false;
brcmf_sdbrcm_wait_event_wakeup(bus); brcmf_sdbrcm_wait_event_wakeup(bus);
} }
...@@ -2326,8 +2331,6 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) ...@@ -2326,8 +2331,6 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
bus->activity = false; bus->activity = false;
brcmf_sdbrcm_clkctl(bus, CLK_NONE, false); brcmf_sdbrcm_clkctl(bus, CLK_NONE, false);
} }
up(&bus->sdsem);
} }
static int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt) static int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt)
...@@ -2618,11 +2621,10 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen) ...@@ -2618,11 +2621,10 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
/* precondition: IS_ALIGNED((unsigned long)frame, 2) */ /* precondition: IS_ALIGNED((unsigned long)frame, 2) */
/* Need to lock here to protect txseq and SDIO tx calls */
down(&bus->sdsem);
/* Make sure backplane clock is on */ /* Make sure backplane clock is on */
down(&bus->sdsem);
brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
up(&bus->sdsem);
/* Hardware tag: 2 byte len followed by 2 byte ~len check (all LE) */ /* Hardware tag: 2 byte len followed by 2 byte ~len check (all LE) */
*(__le16 *) frame = cpu_to_le16((u16) msglen); *(__le16 *) frame = cpu_to_le16((u16) msglen);
...@@ -2664,7 +2666,9 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen) ...@@ -2664,7 +2666,9 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
frame, min_t(u16, len, 16), "TxHdr:\n"); frame, min_t(u16, len, 16), "TxHdr:\n");
do { do {
down(&bus->sdsem);
ret = brcmf_tx_frame(bus, frame, len); ret = brcmf_tx_frame(bus, frame, len);
up(&bus->sdsem);
} while (ret < 0 && retries++ < TXRETRIES); } while (ret < 0 && retries++ < TXRETRIES);
} }
...@@ -2674,13 +2678,13 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen) ...@@ -2674,13 +2678,13 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
spin_unlock_irqrestore(&bus->dpc_tl_lock, flags); spin_unlock_irqrestore(&bus->dpc_tl_lock, flags);
bus->activity = false; bus->activity = false;
down(&bus->sdsem);
brcmf_sdbrcm_clkctl(bus, CLK_NONE, true); brcmf_sdbrcm_clkctl(bus, CLK_NONE, true);
up(&bus->sdsem);
} else { } else {
spin_unlock_irqrestore(&bus->dpc_tl_lock, flags); spin_unlock_irqrestore(&bus->dpc_tl_lock, flags);
} }
up(&bus->sdsem);
if (ret) if (ret)
bus->sdcnt.tx_ctlerrs++; bus->sdcnt.tx_ctlerrs++;
else else
...@@ -2710,8 +2714,10 @@ static int brcmf_sdio_readshared(struct brcmf_sdio *bus, ...@@ -2710,8 +2714,10 @@ static int brcmf_sdio_readshared(struct brcmf_sdio *bus,
* Read last word in socram to determine * Read last word in socram to determine
* address of sdpcm_shared structure * address of sdpcm_shared structure
*/ */
down(&bus->sdsem);
rv = brcmf_sdbrcm_membytes(bus, false, shaddr, rv = brcmf_sdbrcm_membytes(bus, false, shaddr,
(u8 *)&addr_le, 4); (u8 *)&addr_le, 4);
up(&bus->sdsem);
if (rv < 0) if (rv < 0)
return rv; return rv;
...@@ -2834,12 +2840,14 @@ static int brcmf_sdio_trap_info(struct brcmf_sdio *bus, struct sdpcm_shared *sh, ...@@ -2834,12 +2840,14 @@ static int brcmf_sdio_trap_info(struct brcmf_sdio *bus, struct sdpcm_shared *sh,
if ((sh->flags & SDPCM_SHARED_TRAP) == 0) if ((sh->flags & SDPCM_SHARED_TRAP) == 0)
return 0; return 0;
down(&bus->sdsem);
error = brcmf_sdbrcm_membytes(bus, false, sh->trap_addr, (u8 *)&tr, error = brcmf_sdbrcm_membytes(bus, false, sh->trap_addr, (u8 *)&tr,
sizeof(struct brcmf_trap_info)); sizeof(struct brcmf_trap_info));
if (error < 0) if (error < 0)
return error; return error;
nbytes = brcmf_sdio_dump_console(bus, sh, data, count); nbytes = brcmf_sdio_dump_console(bus, sh, data, count);
up(&bus->sdsem);
if (nbytes < 0) if (nbytes < 0)
return nbytes; return nbytes;
...@@ -2885,6 +2893,7 @@ static int brcmf_sdio_assert_info(struct brcmf_sdio *bus, ...@@ -2885,6 +2893,7 @@ static int brcmf_sdio_assert_info(struct brcmf_sdio *bus,
return 0; return 0;
} }
down(&bus->sdsem);
if (sh->assert_file_addr != 0) { if (sh->assert_file_addr != 0) {
error = brcmf_sdbrcm_membytes(bus, false, sh->assert_file_addr, error = brcmf_sdbrcm_membytes(bus, false, sh->assert_file_addr,
(u8 *)file, 80); (u8 *)file, 80);
...@@ -2897,6 +2906,7 @@ static int brcmf_sdio_assert_info(struct brcmf_sdio *bus, ...@@ -2897,6 +2906,7 @@ static int brcmf_sdio_assert_info(struct brcmf_sdio *bus,
if (error < 0) if (error < 0)
return error; return error;
} }
up(&bus->sdsem);
res = scnprintf(buf, sizeof(buf), res = scnprintf(buf, sizeof(buf),
"dongle assert: %s:%d: assert(%s)\n", "dongle assert: %s:%d: assert(%s)\n",
...@@ -2909,9 +2919,7 @@ static int brcmf_sdbrcm_checkdied(struct brcmf_sdio *bus) ...@@ -2909,9 +2919,7 @@ static int brcmf_sdbrcm_checkdied(struct brcmf_sdio *bus)
int error; int error;
struct sdpcm_shared sh; struct sdpcm_shared sh;
down(&bus->sdsem);
error = brcmf_sdio_readshared(bus, &sh); error = brcmf_sdio_readshared(bus, &sh);
up(&bus->sdsem);
if (error < 0) if (error < 0)
return error; return error;
...@@ -2938,7 +2946,6 @@ static int brcmf_sdbrcm_died_dump(struct brcmf_sdio *bus, char __user *data, ...@@ -2938,7 +2946,6 @@ static int brcmf_sdbrcm_died_dump(struct brcmf_sdio *bus, char __user *data,
if (pos != 0) if (pos != 0)
return 0; return 0;
down(&bus->sdsem);
error = brcmf_sdio_readshared(bus, &sh); error = brcmf_sdio_readshared(bus, &sh);
if (error < 0) if (error < 0)
goto done; goto done;
...@@ -2955,7 +2962,6 @@ static int brcmf_sdbrcm_died_dump(struct brcmf_sdio *bus, char __user *data, ...@@ -2955,7 +2962,6 @@ static int brcmf_sdbrcm_died_dump(struct brcmf_sdio *bus, char __user *data,
error += nbytes; error += nbytes;
*ppos += error; *ppos += error;
done: done:
up(&bus->sdsem);
return error; return error;
} }
...@@ -3511,8 +3517,6 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus) ...@@ -3511,8 +3517,6 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus)
brcmf_dbg(TIMER, "Enter\n"); brcmf_dbg(TIMER, "Enter\n");
down(&bus->sdsem);
/* Poll period: check device if appropriate. */ /* Poll period: check device if appropriate. */
if (bus->poll && (++bus->polltick >= bus->pollrate)) { if (bus->poll && (++bus->polltick >= bus->pollrate)) {
u32 intstatus = 0; u32 intstatus = 0;
...@@ -3561,11 +3565,13 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus) ...@@ -3561,11 +3565,13 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus)
bus->console.count += BRCMF_WD_POLL_MS; bus->console.count += BRCMF_WD_POLL_MS;
if (bus->console.count >= bus->console_interval) { if (bus->console.count >= bus->console_interval) {
bus->console.count -= bus->console_interval; bus->console.count -= bus->console_interval;
down(&bus->sdsem);
/* Make sure backplane clock is on */ /* Make sure backplane clock is on */
brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
if (brcmf_sdbrcm_readconsole(bus) < 0) if (brcmf_sdbrcm_readconsole(bus) < 0)
/* stop on error */ /* stop on error */
bus->console_interval = 0; bus->console_interval = 0;
up(&bus->sdsem);
} }
} }
#endif /* DEBUG */ #endif /* DEBUG */
...@@ -3578,13 +3584,13 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus) ...@@ -3578,13 +3584,13 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus)
bus->activity = false; bus->activity = false;
brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS); brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS);
} else { } else {
down(&bus->sdsem);
brcmf_sdbrcm_clkctl(bus, CLK_NONE, false); brcmf_sdbrcm_clkctl(bus, CLK_NONE, false);
up(&bus->sdsem);
} }
} }
} }
up(&bus->sdsem);
return (atomic_read(&bus->ipend) > 0); return (atomic_read(&bus->ipend) > 0);
} }
......
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