diff options
author | Franky Lin <frankyl@broadcom.com> | 2012-11-05 19:22:24 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2012-11-14 14:55:56 -0500 |
commit | 38b0b0ddee3270106d740e8df42a5b52beed502b (patch) | |
tree | 09cc5589cf2ad3d618ea7f74c98f5a207e37349f | |
parent | 7cdf57d34c017e5c4c48069ae46e7cb87979435a (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.c | 28 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c | 7 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 118 |
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 | ||
378 | done: | 374 | done: |
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 | ||
405 | done: | 397 | done: |
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 | ||
469 | done: | 457 | done: |
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 | ||
413 | out: | 409 | out: |
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 | ||
3472 | exit: | 3492 | exit: |
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 | ||
3749 | fail: | 3775 | fail: |
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, |