aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFranky Lin <frankyl@broadcom.com>2012-11-05 19:22:24 -0500
committerJohn W. Linville <linville@tuxdriver.com>2012-11-14 14:55:56 -0500
commit38b0b0ddee3270106d740e8df42a5b52beed502b (patch)
tree09cc5589cf2ad3d618ea7f74c98f5a207e37349f
parent7cdf57d34c017e5c4c48069ae46e7cb87979435a (diff)
brcmfmac: protect consecutive SDIO access with sdio_claim_host
Semaphore sdsem is used to protect consecutive memory access through SDIO bus. Same functionality is provided by sdio_claim_host/ sdio_release_host interface as well. Replace sdsem with sdio_claim_host. Signed-off-by: Franky Lin <frankyl@broadcom.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c28
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c7
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c118
3 files changed, 82 insertions, 71 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
index 3b2c4c20e7f..1aec4342875 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
@@ -84,6 +84,8 @@ int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev)
84 return ret; 84 return ret;
85 sdiodev->irq_wake = true; 85 sdiodev->irq_wake = true;
86 86
87 sdio_claim_host(sdiodev->func[1]);
88
87 /* must configure SDIO_CCCR_IENx to enable irq */ 89 /* must configure SDIO_CCCR_IENx to enable irq */
88 data = brcmf_sdio_regrb(sdiodev, SDIO_CCCR_IENx, &ret); 90 data = brcmf_sdio_regrb(sdiodev, SDIO_CCCR_IENx, &ret);
89 data |= 1 << SDIO_FUNC_1 | 1 << SDIO_FUNC_2 | 1; 91 data |= 1 << SDIO_FUNC_1 | 1 << SDIO_FUNC_2 | 1;
@@ -95,6 +97,8 @@ int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev)
95 data |= SDIO_SEPINT_ACT_HI; 97 data |= SDIO_SEPINT_ACT_HI;
96 brcmf_sdio_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, data, &ret); 98 brcmf_sdio_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, data, &ret);
97 99
100 sdio_release_host(sdiodev->func[1]);
101
98 return 0; 102 return 0;
99} 103}
100 104
@@ -102,8 +106,10 @@ int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev)
102{ 106{
103 brcmf_dbg(TRACE, "Entering\n"); 107 brcmf_dbg(TRACE, "Entering\n");
104 108
109 sdio_claim_host(sdiodev->func[1]);
105 brcmf_sdio_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, 0, NULL); 110 brcmf_sdio_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, 0, NULL);
106 brcmf_sdio_regwb(sdiodev, SDIO_CCCR_IENx, 0, NULL); 111 brcmf_sdio_regwb(sdiodev, SDIO_CCCR_IENx, 0, NULL);
112 sdio_release_host(sdiodev->func[1]);
107 113
108 if (sdiodev->irq_wake) { 114 if (sdiodev->irq_wake) {
109 disable_irq_wake(sdiodev->irq); 115 disable_irq_wake(sdiodev->irq);
@@ -249,9 +255,7 @@ u8 brcmf_sdio_regrb(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret)
249 int retval; 255 int retval;
250 256
251 brcmf_dbg(INFO, "addr:0x%08x\n", addr); 257 brcmf_dbg(INFO, "addr:0x%08x\n", addr);
252 sdio_claim_host(sdiodev->func[1]);
253 retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, false); 258 retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, false);
254 sdio_release_host(sdiodev->func[1]);
255 brcmf_dbg(INFO, "data:0x%02x\n", data); 259 brcmf_dbg(INFO, "data:0x%02x\n", data);
256 260
257 if (ret) 261 if (ret)
@@ -266,9 +270,7 @@ u32 brcmf_sdio_regrl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret)
266 int retval; 270 int retval;
267 271
268 brcmf_dbg(INFO, "addr:0x%08x\n", addr); 272 brcmf_dbg(INFO, "addr:0x%08x\n", addr);
269 sdio_claim_host(sdiodev->func[1]);
270 retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, false); 273 retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, false);
271 sdio_release_host(sdiodev->func[1]);
272 brcmf_dbg(INFO, "data:0x%08x\n", data); 274 brcmf_dbg(INFO, "data:0x%08x\n", data);
273 275
274 if (ret) 276 if (ret)
@@ -283,9 +285,7 @@ void brcmf_sdio_regwb(struct brcmf_sdio_dev *sdiodev, u32 addr,
283 int retval; 285 int retval;
284 286
285 brcmf_dbg(INFO, "addr:0x%08x, data:0x%02x\n", addr, data); 287 brcmf_dbg(INFO, "addr:0x%08x, data:0x%02x\n", addr, data);
286 sdio_claim_host(sdiodev->func[1]);
287 retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, true); 288 retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, true);
288 sdio_release_host(sdiodev->func[1]);
289 289
290 if (ret) 290 if (ret)
291 *ret = retval; 291 *ret = retval;
@@ -297,9 +297,7 @@ void brcmf_sdio_regwl(struct brcmf_sdio_dev *sdiodev, u32 addr,
297 int retval; 297 int retval;
298 298
299 brcmf_dbg(INFO, "addr:0x%08x, data:0x%08x\n", addr, data); 299 brcmf_dbg(INFO, "addr:0x%08x, data:0x%08x\n", addr, data);
300 sdio_claim_host(sdiodev->func[1]);
301 retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, true); 300 retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, true);
302 sdio_release_host(sdiodev->func[1]);
303 301
304 if (ret) 302 if (ret)
305 *ret = retval; 303 *ret = retval;
@@ -364,8 +362,6 @@ brcmf_sdcard_recv_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
364 brcmf_dbg(INFO, "fun = %d, addr = 0x%x, size = %d\n", 362 brcmf_dbg(INFO, "fun = %d, addr = 0x%x, size = %d\n",
365 fn, addr, pkt->len); 363 fn, addr, pkt->len);
366 364
367 sdio_claim_host(sdiodev->func[1]);
368
369 width = (flags & SDIO_REQ_4BYTE) ? 4 : 2; 365 width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
370 err = brcmf_sdcard_recv_prepare(sdiodev, fn, flags, width, &addr); 366 err = brcmf_sdcard_recv_prepare(sdiodev, fn, flags, width, &addr);
371 if (err) 367 if (err)
@@ -376,8 +372,6 @@ brcmf_sdcard_recv_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
376 fn, addr, pkt); 372 fn, addr, pkt);
377 373
378done: 374done:
379 sdio_release_host(sdiodev->func[1]);
380
381 return err; 375 return err;
382} 376}
383 377
@@ -391,8 +385,6 @@ int brcmf_sdcard_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
391 brcmf_dbg(INFO, "fun = %d, addr = 0x%x, size = %d\n", 385 brcmf_dbg(INFO, "fun = %d, addr = 0x%x, size = %d\n",
392 fn, addr, pktq->qlen); 386 fn, addr, pktq->qlen);
393 387
394 sdio_claim_host(sdiodev->func[1]);
395
396 width = (flags & SDIO_REQ_4BYTE) ? 4 : 2; 388 width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
397 err = brcmf_sdcard_recv_prepare(sdiodev, fn, flags, width, &addr); 389 err = brcmf_sdcard_recv_prepare(sdiodev, fn, flags, width, &addr);
398 if (err) 390 if (err)
@@ -403,8 +395,6 @@ int brcmf_sdcard_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
403 pktq); 395 pktq);
404 396
405done: 397done:
406 sdio_release_host(sdiodev->func[1]);
407
408 return err; 398 return err;
409} 399}
410 400
@@ -446,8 +436,6 @@ brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
446 if (flags & SDIO_REQ_ASYNC) 436 if (flags & SDIO_REQ_ASYNC)
447 return -ENOTSUPP; 437 return -ENOTSUPP;
448 438
449 sdio_claim_host(sdiodev->func[1]);
450
451 if (bar0 != sdiodev->sbwad) { 439 if (bar0 != sdiodev->sbwad) {
452 err = brcmf_sdcard_set_sbaddr_window(sdiodev, bar0); 440 err = brcmf_sdcard_set_sbaddr_window(sdiodev, bar0);
453 if (err) 441 if (err)
@@ -467,8 +455,6 @@ brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
467 addr, pkt); 455 addr, pkt);
468 456
469done: 457done:
470 sdio_release_host(sdiodev->func[1]);
471
472 return err; 458 return err;
473} 459}
474 460
@@ -510,10 +496,8 @@ int brcmf_sdcard_abort(struct brcmf_sdio_dev *sdiodev, uint fn)
510 brcmf_dbg(TRACE, "Enter\n"); 496 brcmf_dbg(TRACE, "Enter\n");
511 497
512 /* issue abort cmd52 command through F0 */ 498 /* issue abort cmd52 command through F0 */
513 sdio_claim_host(sdiodev->func[1]);
514 brcmf_sdioh_request_byte(sdiodev, SDIOH_WRITE, SDIO_FUNC_0, 499 brcmf_sdioh_request_byte(sdiodev, SDIOH_WRITE, SDIO_FUNC_0,
515 SDIO_CCCR_ABORT, &t_func); 500 SDIO_CCCR_ABORT, &t_func);
516 sdio_release_host(sdiodev->func[1]);
517 501
518 brcmf_dbg(TRACE, "Exit\n"); 502 brcmf_dbg(TRACE, "Exit\n");
519 return 0; 503 return 0;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
index c3247d5b3c2..c62ec2a5b27 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
@@ -372,9 +372,7 @@ static int brcmf_sdioh_enablefuncs(struct brcmf_sdio_dev *sdiodev)
372 } 372 }
373 373
374 /* Enable Function 1 */ 374 /* Enable Function 1 */
375 sdio_claim_host(sdiodev->func[1]);
376 err_ret = sdio_enable_func(sdiodev->func[1]); 375 err_ret = sdio_enable_func(sdiodev->func[1]);
377 sdio_release_host(sdiodev->func[1]);
378 if (err_ret) 376 if (err_ret)
379 brcmf_dbg(ERROR, "Failed to enable F1 Err: 0x%08x\n", err_ret); 377 brcmf_dbg(ERROR, "Failed to enable F1 Err: 0x%08x\n", err_ret);
380 378
@@ -393,16 +391,14 @@ int brcmf_sdioh_attach(struct brcmf_sdio_dev *sdiodev)
393 sdiodev->num_funcs = 2; 391 sdiodev->num_funcs = 2;
394 392
395 sdio_claim_host(sdiodev->func[1]); 393 sdio_claim_host(sdiodev->func[1]);
394
396 err_ret = sdio_set_block_size(sdiodev->func[1], SDIO_FUNC1_BLOCKSIZE); 395 err_ret = sdio_set_block_size(sdiodev->func[1], SDIO_FUNC1_BLOCKSIZE);
397 sdio_release_host(sdiodev->func[1]);
398 if (err_ret) { 396 if (err_ret) {
399 brcmf_dbg(ERROR, "Failed to set F1 blocksize\n"); 397 brcmf_dbg(ERROR, "Failed to set F1 blocksize\n");
400 goto out; 398 goto out;
401 } 399 }
402 400
403 sdio_claim_host(sdiodev->func[2]);
404 err_ret = sdio_set_block_size(sdiodev->func[2], SDIO_FUNC2_BLOCKSIZE); 401 err_ret = sdio_set_block_size(sdiodev->func[2], SDIO_FUNC2_BLOCKSIZE);
405 sdio_release_host(sdiodev->func[2]);
406 if (err_ret) { 402 if (err_ret) {
407 brcmf_dbg(ERROR, "Failed to set F2 blocksize\n"); 403 brcmf_dbg(ERROR, "Failed to set F2 blocksize\n");
408 goto out; 404 goto out;
@@ -411,6 +407,7 @@ int brcmf_sdioh_attach(struct brcmf_sdio_dev *sdiodev)
411 brcmf_sdioh_enablefuncs(sdiodev); 407 brcmf_sdioh_enablefuncs(sdiodev);
412 408
413out: 409out:
410 sdio_release_host(sdiodev->func[1]);
414 brcmf_dbg(TRACE, "Done\n"); 411 brcmf_dbg(TRACE, "Done\n");
415 return err_ret; 412 return err_ret;
416} 413}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
index e3288527aea..7b8c653aaf1 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
@@ -584,8 +584,6 @@ struct brcmf_sdio {
584 struct list_head dpc_tsklst; 584 struct list_head dpc_tsklst;
585 spinlock_t dpc_tl_lock; 585 spinlock_t dpc_tl_lock;
586 586
587 struct semaphore sdsem;
588
589 const struct firmware *firmware; 587 const struct firmware *firmware;
590 u32 fw_ptr; 588 u32 fw_ptr;
591 589
@@ -1274,7 +1272,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
1274 * read directly into the chained packet, or allocate a large 1272 * read directly into the chained packet, or allocate a large
1275 * packet and and copy into the chain. 1273 * packet and and copy into the chain.
1276 */ 1274 */
1277 down(&bus->sdsem); 1275 sdio_claim_host(bus->sdiodev->func[1]);
1278 if (usechain) { 1276 if (usechain) {
1279 errcode = brcmf_sdcard_recv_chain(bus->sdiodev, 1277 errcode = brcmf_sdcard_recv_chain(bus->sdiodev,
1280 bus->sdiodev->sbwad, 1278 bus->sdiodev->sbwad,
@@ -1296,7 +1294,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
1296 dlen); 1294 dlen);
1297 errcode = -1; 1295 errcode = -1;
1298 } 1296 }
1299 up(&bus->sdsem); 1297 sdio_release_host(bus->sdiodev->func[1]);
1300 bus->sdcnt.f2rxdata++; 1298 bus->sdcnt.f2rxdata++;
1301 1299
1302 /* On failure, kill the superframe, allow a couple retries */ 1300 /* On failure, kill the superframe, allow a couple retries */
@@ -1305,6 +1303,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
1305 dlen, errcode); 1303 dlen, errcode);
1306 bus->sdiodev->bus_if->dstats.rx_errors++; 1304 bus->sdiodev->bus_if->dstats.rx_errors++;
1307 1305
1306 sdio_claim_host(bus->sdiodev->func[1]);
1308 if (bus->glomerr++ < 3) { 1307 if (bus->glomerr++ < 3) {
1309 brcmf_sdbrcm_rxfail(bus, true, true); 1308 brcmf_sdbrcm_rxfail(bus, true, true);
1310 } else { 1309 } else {
@@ -1313,6 +1312,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
1313 bus->sdcnt.rxglomfail++; 1312 bus->sdcnt.rxglomfail++;
1314 brcmf_sdbrcm_free_glom(bus); 1313 brcmf_sdbrcm_free_glom(bus);
1315 } 1314 }
1315 sdio_release_host(bus->sdiodev->func[1]);
1316 return 0; 1316 return 0;
1317 } 1317 }
1318 1318
@@ -1322,8 +1322,10 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
1322 1322
1323 rd_new.seq_num = rxseq; 1323 rd_new.seq_num = rxseq;
1324 rd_new.len = dlen; 1324 rd_new.len = dlen;
1325 sdio_claim_host(bus->sdiodev->func[1]);
1325 errcode = -!brcmf_sdio_hdparser(bus, pfirst->data, &rd_new, 1326 errcode = -!brcmf_sdio_hdparser(bus, pfirst->data, &rd_new,
1326 BRCMF_SDIO_FT_SUPER); 1327 BRCMF_SDIO_FT_SUPER);
1328 sdio_release_host(bus->sdiodev->func[1]);
1327 bus->cur_read.len = rd_new.len_nxtfrm << 4; 1329 bus->cur_read.len = rd_new.len_nxtfrm << 4;
1328 1330
1329 /* Remove superframe header, remember offset */ 1331 /* Remove superframe header, remember offset */
@@ -1339,9 +1341,11 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
1339 1341
1340 rd_new.len = pnext->len; 1342 rd_new.len = pnext->len;
1341 rd_new.seq_num = rxseq++; 1343 rd_new.seq_num = rxseq++;
1344 sdio_claim_host(bus->sdiodev->func[1]);
1342 errcode = -!brcmf_sdio_hdparser(bus, pnext->data, 1345 errcode = -!brcmf_sdio_hdparser(bus, pnext->data,
1343 &rd_new, 1346 &rd_new,
1344 BRCMF_SDIO_FT_SUB); 1347 BRCMF_SDIO_FT_SUB);
1348 sdio_release_host(bus->sdiodev->func[1]);
1345 brcmf_dbg_hex_dump(BRCMF_GLOM_ON(), 1349 brcmf_dbg_hex_dump(BRCMF_GLOM_ON(),
1346 pnext->data, 32, "subframe:\n"); 1350 pnext->data, 32, "subframe:\n");
1347 1351
@@ -1351,6 +1355,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
1351 if (errcode) { 1355 if (errcode) {
1352 /* Terminate frame on error, request 1356 /* Terminate frame on error, request
1353 a couple retries */ 1357 a couple retries */
1358 sdio_claim_host(bus->sdiodev->func[1]);
1354 if (bus->glomerr++ < 3) { 1359 if (bus->glomerr++ < 3) {
1355 /* Restore superframe header space */ 1360 /* Restore superframe header space */
1356 skb_push(pfirst, sfdoff); 1361 skb_push(pfirst, sfdoff);
@@ -1361,6 +1366,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
1361 bus->sdcnt.rxglomfail++; 1366 bus->sdcnt.rxglomfail++;
1362 brcmf_sdbrcm_free_glom(bus); 1367 brcmf_sdbrcm_free_glom(bus);
1363 } 1368 }
1369 sdio_release_host(bus->sdiodev->func[1]);
1364 bus->cur_read.len = 0; 1370 bus->cur_read.len = 0;
1365 return 0; 1371 return 0;
1366 } 1372 }
@@ -1585,7 +1591,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
1585 1591
1586 rd->len_left = rd->len; 1592 rd->len_left = rd->len;
1587 /* read header first for unknow frame length */ 1593 /* read header first for unknow frame length */
1588 down(&bus->sdsem); 1594 sdio_claim_host(bus->sdiodev->func[1]);
1589 if (!rd->len) { 1595 if (!rd->len) {
1590 sdret = brcmf_sdcard_recv_buf(bus->sdiodev, 1596 sdret = brcmf_sdcard_recv_buf(bus->sdiodev,
1591 bus->sdiodev->sbwad, 1597 bus->sdiodev->sbwad,
@@ -1598,7 +1604,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
1598 sdret); 1604 sdret);
1599 bus->sdcnt.rx_hdrfail++; 1605 bus->sdcnt.rx_hdrfail++;
1600 brcmf_sdbrcm_rxfail(bus, true, true); 1606 brcmf_sdbrcm_rxfail(bus, true, true);
1601 up(&bus->sdsem); 1607 sdio_release_host(bus->sdiodev->func[1]);
1602 continue; 1608 continue;
1603 } 1609 }
1604 1610
@@ -1608,7 +1614,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
1608 1614
1609 if (!brcmf_sdio_hdparser(bus, bus->rxhdr, rd, 1615 if (!brcmf_sdio_hdparser(bus, bus->rxhdr, rd,
1610 BRCMF_SDIO_FT_NORMAL)) { 1616 BRCMF_SDIO_FT_NORMAL)) {
1611 up(&bus->sdsem); 1617 sdio_release_host(bus->sdiodev->func[1]);
1612 if (!bus->rxpending) 1618 if (!bus->rxpending)
1613 break; 1619 break;
1614 else 1620 else
@@ -1624,7 +1630,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
1624 rd->len_nxtfrm = 0; 1630 rd->len_nxtfrm = 0;
1625 /* treat all packet as event if we don't know */ 1631 /* treat all packet as event if we don't know */
1626 rd->channel = SDPCM_EVENT_CHANNEL; 1632 rd->channel = SDPCM_EVENT_CHANNEL;
1627 up(&bus->sdsem); 1633 sdio_release_host(bus->sdiodev->func[1]);
1628 continue; 1634 continue;
1629 } 1635 }
1630 rd->len_left = rd->len > BRCMF_FIRSTREAD ? 1636 rd->len_left = rd->len > BRCMF_FIRSTREAD ?
@@ -1642,7 +1648,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
1642 bus->sdiodev->bus_if->dstats.rx_dropped++; 1648 bus->sdiodev->bus_if->dstats.rx_dropped++;
1643 brcmf_sdbrcm_rxfail(bus, false, 1649 brcmf_sdbrcm_rxfail(bus, false,
1644 RETRYCHAN(rd->channel)); 1650 RETRYCHAN(rd->channel));
1645 up(&bus->sdsem); 1651 sdio_release_host(bus->sdiodev->func[1]);
1646 continue; 1652 continue;
1647 } 1653 }
1648 skb_pull(pkt, head_read); 1654 skb_pull(pkt, head_read);
@@ -1651,15 +1657,17 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
1651 sdret = brcmf_sdcard_recv_pkt(bus->sdiodev, bus->sdiodev->sbwad, 1657 sdret = brcmf_sdcard_recv_pkt(bus->sdiodev, bus->sdiodev->sbwad,
1652 SDIO_FUNC_2, F2SYNC, pkt); 1658 SDIO_FUNC_2, F2SYNC, pkt);
1653 bus->sdcnt.f2rxdata++; 1659 bus->sdcnt.f2rxdata++;
1654 up(&bus->sdsem); 1660 sdio_release_host(bus->sdiodev->func[1]);
1655 1661
1656 if (sdret < 0) { 1662 if (sdret < 0) {
1657 brcmf_dbg(ERROR, "read %d bytes from channel %d failed: %d\n", 1663 brcmf_dbg(ERROR, "read %d bytes from channel %d failed: %d\n",
1658 rd->len, rd->channel, sdret); 1664 rd->len, rd->channel, sdret);
1659 brcmu_pkt_buf_free_skb(pkt); 1665 brcmu_pkt_buf_free_skb(pkt);
1660 bus->sdiodev->bus_if->dstats.rx_errors++; 1666 bus->sdiodev->bus_if->dstats.rx_errors++;
1667 sdio_claim_host(bus->sdiodev->func[1]);
1661 brcmf_sdbrcm_rxfail(bus, true, 1668 brcmf_sdbrcm_rxfail(bus, true,
1662 RETRYCHAN(rd->channel)); 1669 RETRYCHAN(rd->channel));
1670 sdio_release_host(bus->sdiodev->func[1]);
1663 continue; 1671 continue;
1664 } 1672 }
1665 1673
@@ -1670,6 +1678,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
1670 } else { 1678 } else {
1671 memcpy(bus->rxhdr, pkt->data, SDPCM_HDRLEN); 1679 memcpy(bus->rxhdr, pkt->data, SDPCM_HDRLEN);
1672 rd_new.seq_num = rd->seq_num; 1680 rd_new.seq_num = rd->seq_num;
1681 sdio_claim_host(bus->sdiodev->func[1]);
1673 if (!brcmf_sdio_hdparser(bus, bus->rxhdr, &rd_new, 1682 if (!brcmf_sdio_hdparser(bus, bus->rxhdr, &rd_new,
1674 BRCMF_SDIO_FT_NORMAL)) { 1683 BRCMF_SDIO_FT_NORMAL)) {
1675 rd->len = 0; 1684 rd->len = 0;
@@ -1682,9 +1691,11 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
1682 roundup(rd_new.len, 16) >> 4); 1691 roundup(rd_new.len, 16) >> 4);
1683 rd->len = 0; 1692 rd->len = 0;
1684 brcmf_sdbrcm_rxfail(bus, true, true); 1693 brcmf_sdbrcm_rxfail(bus, true, true);
1694 sdio_release_host(bus->sdiodev->func[1]);
1685 brcmu_pkt_buf_free_skb(pkt); 1695 brcmu_pkt_buf_free_skb(pkt);
1686 continue; 1696 continue;
1687 } 1697 }
1698 sdio_release_host(bus->sdiodev->func[1]);
1688 rd->len_nxtfrm = rd_new.len_nxtfrm; 1699 rd->len_nxtfrm = rd_new.len_nxtfrm;
1689 rd->channel = rd_new.channel; 1700 rd->channel = rd_new.channel;
1690 rd->dat_offset = rd_new.dat_offset; 1701 rd->dat_offset = rd_new.dat_offset;
@@ -1700,7 +1711,9 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
1700 rd_new.seq_num); 1711 rd_new.seq_num);
1701 /* Force retry w/normal header read */ 1712 /* Force retry w/normal header read */
1702 rd->len = 0; 1713 rd->len = 0;
1714 sdio_claim_host(bus->sdiodev->func[1]);
1703 brcmf_sdbrcm_rxfail(bus, false, true); 1715 brcmf_sdbrcm_rxfail(bus, false, true);
1716 sdio_release_host(bus->sdiodev->func[1]);
1704 brcmu_pkt_buf_free_skb(pkt); 1717 brcmu_pkt_buf_free_skb(pkt);
1705 continue; 1718 continue;
1706 } 1719 }
@@ -1723,7 +1736,9 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
1723 } else { 1736 } else {
1724 brcmf_dbg(ERROR, "%s: glom superframe w/o " 1737 brcmf_dbg(ERROR, "%s: glom superframe w/o "
1725 "descriptor!\n", __func__); 1738 "descriptor!\n", __func__);
1739 sdio_claim_host(bus->sdiodev->func[1]);
1726 brcmf_sdbrcm_rxfail(bus, false, false); 1740 brcmf_sdbrcm_rxfail(bus, false, false);
1741 sdio_release_host(bus->sdiodev->func[1]);
1727 } 1742 }
1728 /* prepare the descriptor for the next read */ 1743 /* prepare the descriptor for the next read */
1729 rd->len = rd->len_nxtfrm << 4; 1744 rd->len = rd->len_nxtfrm << 4;
@@ -1879,7 +1894,7 @@ static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt,
1879 if (len & (ALIGNMENT - 1)) 1894 if (len & (ALIGNMENT - 1))
1880 len = roundup(len, ALIGNMENT); 1895 len = roundup(len, ALIGNMENT);
1881 1896
1882 down(&bus->sdsem); 1897 sdio_claim_host(bus->sdiodev->func[1]);
1883 ret = brcmf_sdcard_send_pkt(bus->sdiodev, bus->sdiodev->sbwad, 1898 ret = brcmf_sdcard_send_pkt(bus->sdiodev, bus->sdiodev->sbwad,
1884 SDIO_FUNC_2, F2SYNC, pkt); 1899 SDIO_FUNC_2, F2SYNC, pkt);
1885 bus->sdcnt.f2txdata++; 1900 bus->sdcnt.f2txdata++;
@@ -1907,7 +1922,7 @@ static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt,
1907 } 1922 }
1908 1923
1909 } 1924 }
1910 up(&bus->sdsem); 1925 sdio_release_host(bus->sdiodev->func[1]);
1911 if (ret == 0) 1926 if (ret == 0)
1912 bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP; 1927 bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP;
1913 1928
@@ -1955,11 +1970,11 @@ static uint brcmf_sdbrcm_sendfromq(struct brcmf_sdio *bus, uint maxframes)
1955 /* In poll mode, need to check for other events */ 1970 /* In poll mode, need to check for other events */
1956 if (!bus->intr && cnt) { 1971 if (!bus->intr && cnt) {
1957 /* Check device status, signal pending interrupt */ 1972 /* Check device status, signal pending interrupt */
1958 down(&bus->sdsem); 1973 sdio_claim_host(bus->sdiodev->func[1]);
1959 ret = r_sdreg32(bus, &intstatus, 1974 ret = r_sdreg32(bus, &intstatus,
1960 offsetof(struct sdpcmd_regs, 1975 offsetof(struct sdpcmd_regs,
1961 intstatus)); 1976 intstatus));
1962 up(&bus->sdsem); 1977 sdio_release_host(bus->sdiodev->func[1]);
1963 bus->sdcnt.f2txdata++; 1978 bus->sdcnt.f2txdata++;
1964 if (ret != 0) 1979 if (ret != 0)
1965 break; 1980 break;
@@ -1996,7 +2011,7 @@ static void brcmf_sdbrcm_bus_stop(struct device *dev)
1996 bus->watchdog_tsk = NULL; 2011 bus->watchdog_tsk = NULL;
1997 } 2012 }
1998 2013
1999 down(&bus->sdsem); 2014 sdio_claim_host(bus->sdiodev->func[1]);
2000 2015
2001 /* Enable clock for device interrupts */ 2016 /* Enable clock for device interrupts */
2002 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); 2017 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
@@ -2030,7 +2045,7 @@ static void brcmf_sdbrcm_bus_stop(struct device *dev)
2030 2045
2031 /* Turn off the backplane clock (only) */ 2046 /* Turn off the backplane clock (only) */
2032 brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false); 2047 brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false);
2033 up(&bus->sdsem); 2048 sdio_release_host(bus->sdiodev->func[1]);
2034 2049
2035 /* Clear the data packet queues */ 2050 /* Clear the data packet queues */
2036 brcmu_pktq_flush(&bus->txq, true, NULL, NULL); 2051 brcmu_pktq_flush(&bus->txq, true, NULL, NULL);
@@ -2132,7 +2147,7 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
2132 2147
2133 brcmf_dbg(TRACE, "Enter\n"); 2148 brcmf_dbg(TRACE, "Enter\n");
2134 2149
2135 down(&bus->sdsem); 2150 sdio_claim_host(bus->sdiodev->func[1]);
2136 2151
2137 /* If waiting for HTAVAIL, check status */ 2152 /* If waiting for HTAVAIL, check status */
2138 if (bus->clkstate == CLK_PENDING) { 2153 if (bus->clkstate == CLK_PENDING) {
@@ -2186,9 +2201,7 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
2186 /* Pending interrupt indicates new device status */ 2201 /* Pending interrupt indicates new device status */
2187 if (atomic_read(&bus->ipend) > 0) { 2202 if (atomic_read(&bus->ipend) > 0) {
2188 atomic_set(&bus->ipend, 0); 2203 atomic_set(&bus->ipend, 0);
2189 sdio_claim_host(bus->sdiodev->func[1]);
2190 err = brcmf_sdio_intr_rstatus(bus); 2204 err = brcmf_sdio_intr_rstatus(bus);
2191 sdio_release_host(bus->sdiodev->func[1]);
2192 } 2205 }
2193 2206
2194 /* Start with leftover status bits */ 2207 /* Start with leftover status bits */
@@ -2217,7 +2230,7 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
2217 intstatus |= brcmf_sdbrcm_hostmail(bus); 2230 intstatus |= brcmf_sdbrcm_hostmail(bus);
2218 } 2231 }
2219 2232
2220 up(&bus->sdsem); 2233 sdio_release_host(bus->sdiodev->func[1]);
2221 2234
2222 /* Generally don't ask for these, can get CRC errors... */ 2235 /* Generally don't ask for these, can get CRC errors... */
2223 if (intstatus & I_WR_OOSYNC) { 2236 if (intstatus & I_WR_OOSYNC) {
@@ -2265,7 +2278,7 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
2265 (bus->clkstate == CLK_AVAIL)) { 2278 (bus->clkstate == CLK_AVAIL)) {
2266 int i; 2279 int i;
2267 2280
2268 down(&bus->sdsem); 2281 sdio_claim_host(bus->sdiodev->func[1]);
2269 err = brcmf_sdcard_send_buf(bus->sdiodev, bus->sdiodev->sbwad, 2282 err = brcmf_sdcard_send_buf(bus->sdiodev, bus->sdiodev->sbwad,
2270 SDIO_FUNC_2, F2SYNC, bus->ctrl_frame_buf, 2283 SDIO_FUNC_2, F2SYNC, bus->ctrl_frame_buf,
2271 (u32) bus->ctrl_frame_len); 2284 (u32) bus->ctrl_frame_len);
@@ -2299,7 +2312,7 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
2299 } else { 2312 } else {
2300 bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP; 2313 bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP;
2301 } 2314 }
2302 up(&bus->sdsem); 2315 sdio_release_host(bus->sdiodev->func[1]);
2303 bus->ctrl_frame_stat = false; 2316 bus->ctrl_frame_stat = false;
2304 brcmf_sdbrcm_wait_event_wakeup(bus); 2317 brcmf_sdbrcm_wait_event_wakeup(bus);
2305 } 2318 }
@@ -2329,7 +2342,9 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
2329 if ((bus->clkstate != CLK_PENDING) 2342 if ((bus->clkstate != CLK_PENDING)
2330 && bus->idletime == BRCMF_IDLE_IMMEDIATE) { 2343 && bus->idletime == BRCMF_IDLE_IMMEDIATE) {
2331 bus->activity = false; 2344 bus->activity = false;
2345 sdio_claim_host(bus->sdiodev->func[1]);
2332 brcmf_sdbrcm_clkctl(bus, CLK_NONE, false); 2346 brcmf_sdbrcm_clkctl(bus, CLK_NONE, false);
2347 sdio_release_host(bus->sdiodev->func[1]);
2333 } 2348 }
2334} 2349}
2335 2350
@@ -2622,9 +2637,9 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
2622 /* precondition: IS_ALIGNED((unsigned long)frame, 2) */ 2637 /* precondition: IS_ALIGNED((unsigned long)frame, 2) */
2623 2638
2624 /* Make sure backplane clock is on */ 2639 /* Make sure backplane clock is on */
2625 down(&bus->sdsem); 2640 sdio_claim_host(bus->sdiodev->func[1]);
2626 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); 2641 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
2627 up(&bus->sdsem); 2642 sdio_release_host(bus->sdiodev->func[1]);
2628 2643
2629 /* Hardware tag: 2 byte len followed by 2 byte ~len check (all LE) */ 2644 /* Hardware tag: 2 byte len followed by 2 byte ~len check (all LE) */
2630 *(__le16 *) frame = cpu_to_le16((u16) msglen); 2645 *(__le16 *) frame = cpu_to_le16((u16) msglen);
@@ -2666,9 +2681,9 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
2666 frame, min_t(u16, len, 16), "TxHdr:\n"); 2681 frame, min_t(u16, len, 16), "TxHdr:\n");
2667 2682
2668 do { 2683 do {
2669 down(&bus->sdsem); 2684 sdio_claim_host(bus->sdiodev->func[1]);
2670 ret = brcmf_tx_frame(bus, frame, len); 2685 ret = brcmf_tx_frame(bus, frame, len);
2671 up(&bus->sdsem); 2686 sdio_release_host(bus->sdiodev->func[1]);
2672 } while (ret < 0 && retries++ < TXRETRIES); 2687 } while (ret < 0 && retries++ < TXRETRIES);
2673 } 2688 }
2674 2689
@@ -2678,9 +2693,9 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
2678 spin_unlock_irqrestore(&bus->dpc_tl_lock, flags); 2693 spin_unlock_irqrestore(&bus->dpc_tl_lock, flags);
2679 2694
2680 bus->activity = false; 2695 bus->activity = false;
2681 down(&bus->sdsem); 2696 sdio_claim_host(bus->sdiodev->func[1]);
2682 brcmf_sdbrcm_clkctl(bus, CLK_NONE, true); 2697 brcmf_sdbrcm_clkctl(bus, CLK_NONE, true);
2683 up(&bus->sdsem); 2698 sdio_release_host(bus->sdiodev->func[1]);
2684 } else { 2699 } else {
2685 spin_unlock_irqrestore(&bus->dpc_tl_lock, flags); 2700 spin_unlock_irqrestore(&bus->dpc_tl_lock, flags);
2686 } 2701 }
@@ -2714,10 +2729,10 @@ static int brcmf_sdio_readshared(struct brcmf_sdio *bus,
2714 * Read last word in socram to determine 2729 * Read last word in socram to determine
2715 * address of sdpcm_shared structure 2730 * address of sdpcm_shared structure
2716 */ 2731 */
2717 down(&bus->sdsem); 2732 sdio_claim_host(bus->sdiodev->func[1]);
2718 rv = brcmf_sdbrcm_membytes(bus, false, shaddr, 2733 rv = brcmf_sdbrcm_membytes(bus, false, shaddr,
2719 (u8 *)&addr_le, 4); 2734 (u8 *)&addr_le, 4);
2720 up(&bus->sdsem); 2735 sdio_claim_host(bus->sdiodev->func[1]);
2721 if (rv < 0) 2736 if (rv < 0)
2722 return rv; 2737 return rv;
2723 2738
@@ -2736,8 +2751,10 @@ static int brcmf_sdio_readshared(struct brcmf_sdio *bus,
2736 } 2751 }
2737 2752
2738 /* Read hndrte_shared structure */ 2753 /* Read hndrte_shared structure */
2754 sdio_claim_host(bus->sdiodev->func[1]);
2739 rv = brcmf_sdbrcm_membytes(bus, false, addr, (u8 *)&sh_le, 2755 rv = brcmf_sdbrcm_membytes(bus, false, addr, (u8 *)&sh_le,
2740 sizeof(struct sdpcm_shared_le)); 2756 sizeof(struct sdpcm_shared_le));
2757 sdio_release_host(bus->sdiodev->func[1]);
2741 if (rv < 0) 2758 if (rv < 0)
2742 return rv; 2759 return rv;
2743 2760
@@ -2840,14 +2857,14 @@ static int brcmf_sdio_trap_info(struct brcmf_sdio *bus, struct sdpcm_shared *sh,
2840 if ((sh->flags & SDPCM_SHARED_TRAP) == 0) 2857 if ((sh->flags & SDPCM_SHARED_TRAP) == 0)
2841 return 0; 2858 return 0;
2842 2859
2843 down(&bus->sdsem); 2860 sdio_claim_host(bus->sdiodev->func[1]);
2844 error = brcmf_sdbrcm_membytes(bus, false, sh->trap_addr, (u8 *)&tr, 2861 error = brcmf_sdbrcm_membytes(bus, false, sh->trap_addr, (u8 *)&tr,
2845 sizeof(struct brcmf_trap_info)); 2862 sizeof(struct brcmf_trap_info));
2846 if (error < 0) 2863 if (error < 0)
2847 return error; 2864 return error;
2848 2865
2849 nbytes = brcmf_sdio_dump_console(bus, sh, data, count); 2866 nbytes = brcmf_sdio_dump_console(bus, sh, data, count);
2850 up(&bus->sdsem); 2867 sdio_release_host(bus->sdiodev->func[1]);
2851 if (nbytes < 0) 2868 if (nbytes < 0)
2852 return nbytes; 2869 return nbytes;
2853 2870
@@ -2893,7 +2910,7 @@ static int brcmf_sdio_assert_info(struct brcmf_sdio *bus,
2893 return 0; 2910 return 0;
2894 } 2911 }
2895 2912
2896 down(&bus->sdsem); 2913 sdio_claim_host(bus->sdiodev->func[1]);
2897 if (sh->assert_file_addr != 0) { 2914 if (sh->assert_file_addr != 0) {
2898 error = brcmf_sdbrcm_membytes(bus, false, sh->assert_file_addr, 2915 error = brcmf_sdbrcm_membytes(bus, false, sh->assert_file_addr,
2899 (u8 *)file, 80); 2916 (u8 *)file, 80);
@@ -2906,7 +2923,7 @@ static int brcmf_sdio_assert_info(struct brcmf_sdio *bus,
2906 if (error < 0) 2923 if (error < 0)
2907 return error; 2924 return error;
2908 } 2925 }
2909 up(&bus->sdsem); 2926 sdio_release_host(bus->sdiodev->func[1]);
2910 2927
2911 res = scnprintf(buf, sizeof(buf), 2928 res = scnprintf(buf, sizeof(buf),
2912 "dongle assert: %s:%d: assert(%s)\n", 2929 "dongle assert: %s:%d: assert(%s)\n",
@@ -3366,13 +3383,16 @@ brcmf_sdbrcm_download_firmware(struct brcmf_sdio *bus)
3366{ 3383{
3367 bool ret; 3384 bool ret;
3368 3385
3369 /* Download the firmware */ 3386 sdio_claim_host(bus->sdiodev->func[1]);
3387
3370 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); 3388 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
3371 3389
3372 ret = _brcmf_sdbrcm_download_firmware(bus) == 0; 3390 ret = _brcmf_sdbrcm_download_firmware(bus) == 0;
3373 3391
3374 brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false); 3392 brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false);
3375 3393
3394 sdio_release_host(bus->sdiodev->func[1]);
3395
3376 return ret; 3396 return ret;
3377} 3397}
3378 3398
@@ -3401,7 +3421,7 @@ static int brcmf_sdbrcm_bus_init(struct device *dev)
3401 bus->sdcnt.tickcnt = 0; 3421 bus->sdcnt.tickcnt = 0;
3402 brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS); 3422 brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS);
3403 3423
3404 down(&bus->sdsem); 3424 sdio_claim_host(bus->sdiodev->func[1]);
3405 3425
3406 /* Make sure backplane clock is on, needed to generate F2 interrupt */ 3426 /* Make sure backplane clock is on, needed to generate F2 interrupt */
3407 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); 3427 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
@@ -3470,7 +3490,7 @@ static int brcmf_sdbrcm_bus_init(struct device *dev)
3470 brcmf_sdbrcm_clkctl(bus, CLK_NONE, false); 3490 brcmf_sdbrcm_clkctl(bus, CLK_NONE, false);
3471 3491
3472exit: 3492exit:
3473 up(&bus->sdsem); 3493 sdio_release_host(bus->sdiodev->func[1]);
3474 3494
3475 return ret; 3495 return ret;
3476} 3496}
@@ -3533,9 +3553,11 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus)
3533 u8 devpend; 3553 u8 devpend;
3534 spin_unlock_irqrestore(&bus->dpc_tl_lock, 3554 spin_unlock_irqrestore(&bus->dpc_tl_lock,
3535 flags); 3555 flags);
3556 sdio_claim_host(bus->sdiodev->func[1]);
3536 devpend = brcmf_sdio_regrb(bus->sdiodev, 3557 devpend = brcmf_sdio_regrb(bus->sdiodev,
3537 SDIO_CCCR_INTx, 3558 SDIO_CCCR_INTx,
3538 NULL); 3559 NULL);
3560 sdio_release_host(bus->sdiodev->func[1]);
3539 intstatus = 3561 intstatus =
3540 devpend & (INTR_STATUS_FUNC1 | 3562 devpend & (INTR_STATUS_FUNC1 |
3541 INTR_STATUS_FUNC2); 3563 INTR_STATUS_FUNC2);
@@ -3565,13 +3587,13 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus)
3565 bus->console.count += BRCMF_WD_POLL_MS; 3587 bus->console.count += BRCMF_WD_POLL_MS;
3566 if (bus->console.count >= bus->console_interval) { 3588 if (bus->console.count >= bus->console_interval) {
3567 bus->console.count -= bus->console_interval; 3589 bus->console.count -= bus->console_interval;
3568 down(&bus->sdsem); 3590 sdio_claim_host(bus->sdiodev->func[1]);
3569 /* Make sure backplane clock is on */ 3591 /* Make sure backplane clock is on */
3570 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); 3592 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
3571 if (brcmf_sdbrcm_readconsole(bus) < 0) 3593 if (brcmf_sdbrcm_readconsole(bus) < 0)
3572 /* stop on error */ 3594 /* stop on error */
3573 bus->console_interval = 0; 3595 bus->console_interval = 0;
3574 up(&bus->sdsem); 3596 sdio_release_host(bus->sdiodev->func[1]);
3575 } 3597 }
3576 } 3598 }
3577#endif /* DEBUG */ 3599#endif /* DEBUG */
@@ -3584,9 +3606,9 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus)
3584 bus->activity = false; 3606 bus->activity = false;
3585 brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS); 3607 brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS);
3586 } else { 3608 } else {
3587 down(&bus->sdsem); 3609 sdio_claim_host(bus->sdiodev->func[1]);
3588 brcmf_sdbrcm_clkctl(bus, CLK_NONE, false); 3610 brcmf_sdbrcm_clkctl(bus, CLK_NONE, false);
3589 up(&bus->sdsem); 3611 sdio_release_host(bus->sdiodev->func[1]);
3590 } 3612 }
3591 } 3613 }
3592 } 3614 }
@@ -3685,6 +3707,8 @@ brcmf_sdbrcm_probe_attach(struct brcmf_sdio *bus, u32 regsva)
3685 3707
3686 bus->alp_only = true; 3708 bus->alp_only = true;
3687 3709
3710 sdio_claim_host(bus->sdiodev->func[1]);
3711
3688 pr_debug("F1 signature read @0x18000000=0x%4x\n", 3712 pr_debug("F1 signature read @0x18000000=0x%4x\n",
3689 brcmf_sdio_regrl(bus->sdiodev, SI_ENUM_BASE, NULL)); 3713 brcmf_sdio_regrl(bus->sdiodev, SI_ENUM_BASE, NULL));
3690 3714
@@ -3732,6 +3756,8 @@ brcmf_sdbrcm_probe_attach(struct brcmf_sdio *bus, u32 regsva)
3732 reg_val = brcmf_sdio_regrl(bus->sdiodev, reg_addr, NULL); 3756 reg_val = brcmf_sdio_regrl(bus->sdiodev, reg_addr, NULL);
3733 brcmf_sdio_regwl(bus->sdiodev, reg_addr, reg_val | CC_BPRESEN, NULL); 3757 brcmf_sdio_regwl(bus->sdiodev, reg_addr, reg_val | CC_BPRESEN, NULL);
3734 3758
3759 sdio_release_host(bus->sdiodev->func[1]);
3760
3735 brcmu_pktq_init(&bus->txq, (PRIOMASK + 1), TXQLEN); 3761 brcmu_pktq_init(&bus->txq, (PRIOMASK + 1), TXQLEN);
3736 3762
3737 /* Locate an appropriately-aligned portion of hdrbuf */ 3763 /* Locate an appropriately-aligned portion of hdrbuf */
@@ -3747,6 +3773,7 @@ brcmf_sdbrcm_probe_attach(struct brcmf_sdio *bus, u32 regsva)
3747 return true; 3773 return true;
3748 3774
3749fail: 3775fail:
3776 sdio_release_host(bus->sdiodev->func[1]);
3750 return false; 3777 return false;
3751} 3778}
3752 3779
@@ -3754,6 +3781,8 @@ static bool brcmf_sdbrcm_probe_init(struct brcmf_sdio *bus)
3754{ 3781{
3755 brcmf_dbg(TRACE, "Enter\n"); 3782 brcmf_dbg(TRACE, "Enter\n");
3756 3783
3784 sdio_claim_host(bus->sdiodev->func[1]);
3785
3757 /* Disable F2 to clear any intermediate frame state on the dongle */ 3786 /* Disable F2 to clear any intermediate frame state on the dongle */
3758 brcmf_sdio_regwb(bus->sdiodev, SDIO_CCCR_IOEx, 3787 brcmf_sdio_regwb(bus->sdiodev, SDIO_CCCR_IOEx,
3759 SDIO_FUNC_ENABLE_1, NULL); 3788 SDIO_FUNC_ENABLE_1, NULL);
@@ -3764,6 +3793,8 @@ static bool brcmf_sdbrcm_probe_init(struct brcmf_sdio *bus)
3764 /* Done with backplane-dependent accesses, can drop clock... */ 3793 /* Done with backplane-dependent accesses, can drop clock... */
3765 brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL); 3794 brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL);
3766 3795
3796 sdio_release_host(bus->sdiodev->func[1]);
3797
3767 /* ...and initialize clock/power states */ 3798 /* ...and initialize clock/power states */
3768 bus->clkstate = CLK_SDONLY; 3799 bus->clkstate = CLK_SDONLY;
3769 bus->idletime = BRCMF_IDLE_INTERVAL; 3800 bus->idletime = BRCMF_IDLE_INTERVAL;
@@ -3819,8 +3850,10 @@ static void brcmf_sdbrcm_release_dongle(struct brcmf_sdio *bus)
3819 brcmf_dbg(TRACE, "Enter\n"); 3850 brcmf_dbg(TRACE, "Enter\n");
3820 3851
3821 if (bus->ci) { 3852 if (bus->ci) {
3853 sdio_claim_host(bus->sdiodev->func[1]);
3822 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); 3854 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
3823 brcmf_sdbrcm_clkctl(bus, CLK_NONE, false); 3855 brcmf_sdbrcm_clkctl(bus, CLK_NONE, false);
3856 sdio_release_host(bus->sdiodev->func[1]);
3824 brcmf_sdio_chip_detach(&bus->ci); 3857 brcmf_sdio_chip_detach(&bus->ci);
3825 if (bus->vars && bus->varsz) 3858 if (bus->vars && bus->varsz)
3826 kfree(bus->vars); 3859 kfree(bus->vars);
@@ -3905,9 +3938,6 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev)
3905 bus->timer.data = (unsigned long)bus; 3938 bus->timer.data = (unsigned long)bus;
3906 bus->timer.function = brcmf_sdbrcm_watchdog; 3939 bus->timer.function = brcmf_sdbrcm_watchdog;
3907 3940
3908 /* Initialize thread based operation and lock */
3909 sema_init(&bus->sdsem, 1);
3910
3911 /* Initialize watchdog thread */ 3941 /* Initialize watchdog thread */
3912 init_completion(&bus->watchdog_wait); 3942 init_completion(&bus->watchdog_wait);
3913 bus->watchdog_tsk = kthread_run(brcmf_sdbrcm_watchdog_thread, 3943 bus->watchdog_tsk = kthread_run(brcmf_sdbrcm_watchdog_thread,