aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c8
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c149
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h6
3 files changed, 106 insertions, 57 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
index 4f936c6b682d..19057896d92e 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
@@ -2263,8 +2263,6 @@ static void brcmf_sdio_bus_stop(struct device *dev)
2263 w_sdreg32(bus, local_hostintmask, 2263 w_sdreg32(bus, local_hostintmask,
2264 offsetof(struct sdpcmd_regs, intstatus)); 2264 offsetof(struct sdpcmd_regs, intstatus));
2265 2265
2266 /* Turn off the backplane clock (only) */
2267 brcmf_sdio_clkctl(bus, CLK_SDONLY, false);
2268 sdio_release_host(bus->sdiodev->func[1]); 2266 sdio_release_host(bus->sdiodev->func[1]);
2269 2267
2270 /* Clear the data packet queues */ 2268 /* Clear the data packet queues */
@@ -4085,6 +4083,12 @@ void brcmf_sdio_remove(struct brcmf_sdio *bus)
4085 if (bus->ci) { 4083 if (bus->ci) {
4086 sdio_claim_host(bus->sdiodev->func[1]); 4084 sdio_claim_host(bus->sdiodev->func[1]);
4087 brcmf_sdio_clkctl(bus, CLK_AVAIL, false); 4085 brcmf_sdio_clkctl(bus, CLK_AVAIL, false);
4086 /* Leave the device in state where it is 'quiet'. This
4087 * is done by putting it in download_state which
4088 * essentially resets all necessary cores
4089 */
4090 msleep(20);
4091 brcmf_sdio_download_state(bus, true);
4088 brcmf_sdio_clkctl(bus, CLK_NONE, false); 4092 brcmf_sdio_clkctl(bus, CLK_NONE, false);
4089 sdio_release_host(bus->sdiodev->func[1]); 4093 sdio_release_host(bus->sdiodev->func[1]);
4090 brcmf_sdio_chip_detach(&bus->ci); 4094 brcmf_sdio_chip_detach(&bus->ci);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c
index a74a3d1c3e00..434297648e34 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c
@@ -51,6 +51,9 @@
51#define BCM43143_CORE_ARM_BASE 0x18003000 51#define BCM43143_CORE_ARM_BASE 0x18003000
52#define BCM43143_RAMSIZE 0x70000 52#define BCM43143_RAMSIZE 0x70000
53 53
54/* All D11 cores, ID 0x812 */
55#define BCM43xx_CORE_D11_BASE 0x18001000
56
54#define SBCOREREV(sbidh) \ 57#define SBCOREREV(sbidh) \
55 ((((sbidh) & SSB_IDHIGH_RCHI) >> SSB_IDHIGH_RCHI_SHIFT) | \ 58 ((((sbidh) & SSB_IDHIGH_RCHI) >> SSB_IDHIGH_RCHI_SHIFT) | \
56 ((sbidh) & SSB_IDHIGH_RCLO)) 59 ((sbidh) & SSB_IDHIGH_RCLO))
@@ -66,6 +69,10 @@
66/* ARM CR4 core specific control flag bits */ 69/* ARM CR4 core specific control flag bits */
67#define ARMCR4_BCMA_IOCTL_CPUHALT 0x0020 70#define ARMCR4_BCMA_IOCTL_CPUHALT 0x0020
68 71
72/* D11 core specific control flag bits */
73#define D11_BCMA_IOCTL_PHYCLOCKEN 0x0004
74#define D11_BCMA_IOCTL_PHYRESET 0x0008
75
69#define SDIOD_DRVSTR_KEY(chip, pmu) (((chip) << 16) | (pmu)) 76#define SDIOD_DRVSTR_KEY(chip, pmu) (((chip) << 16) | (pmu))
70/* SDIO Pad drive strength to select value mappings */ 77/* SDIO Pad drive strength to select value mappings */
71struct sdiod_drive_str { 78struct sdiod_drive_str {
@@ -193,7 +200,8 @@ brcmf_sdio_ai_iscoreup(struct brcmf_sdio_dev *sdiodev,
193 200
194static void 201static void
195brcmf_sdio_sb_coredisable(struct brcmf_sdio_dev *sdiodev, 202brcmf_sdio_sb_coredisable(struct brcmf_sdio_dev *sdiodev,
196 struct chip_info *ci, u16 coreid, u32 core_bits) 203 struct chip_info *ci, u16 coreid, u32 pre_resetbits,
204 u32 in_resetbits)
197{ 205{
198 u32 regdata, base; 206 u32 regdata, base;
199 u8 idx; 207 u8 idx;
@@ -279,52 +287,48 @@ brcmf_sdio_sb_coredisable(struct brcmf_sdio_dev *sdiodev,
279 287
280static void 288static void
281brcmf_sdio_ai_coredisable(struct brcmf_sdio_dev *sdiodev, 289brcmf_sdio_ai_coredisable(struct brcmf_sdio_dev *sdiodev,
282 struct chip_info *ci, u16 coreid, u32 core_bits) 290 struct chip_info *ci, u16 coreid, u32 pre_resetbits,
291 u32 in_resetbits)
283{ 292{
284 u8 idx; 293 u8 idx;
285 u32 regdata; 294 u32 regdata;
295 u32 wrapbase;
286 296
287 idx = brcmf_sdio_chip_getinfidx(ci, coreid); 297 idx = brcmf_sdio_chip_getinfidx(ci, coreid);
288 if (idx == BRCMF_MAX_CORENUM) 298 if (idx == BRCMF_MAX_CORENUM)
289 return; 299 return;
290 300
301 wrapbase = ci->c_inf[idx].wrapbase;
302
291 /* if core is already in reset, just return */ 303 /* if core is already in reset, just return */
292 regdata = brcmf_sdiod_regrl(sdiodev, 304 regdata = brcmf_sdiod_regrl(sdiodev, wrapbase + BCMA_RESET_CTL, NULL);
293 ci->c_inf[idx].wrapbase+BCMA_RESET_CTL,
294 NULL);
295 if ((regdata & BCMA_RESET_CTL_RESET) != 0) 305 if ((regdata & BCMA_RESET_CTL_RESET) != 0)
296 return; 306 return;
297 307
298 /* ensure no pending backplane operation 308 /* configure reset */
299 * 300uc should be sufficient for backplane ops to be finish 309 brcmf_sdiod_regwl(sdiodev, wrapbase + BCMA_IOCTL, pre_resetbits |
300 * extra 10ms is taken into account for firmware load stage 310 BCMA_IOCTL_FGC | BCMA_IOCTL_CLK, NULL);
301 * after 10300us carry on disabling the core anyway 311 regdata = brcmf_sdiod_regrl(sdiodev, wrapbase + BCMA_IOCTL, NULL);
302 */
303 SPINWAIT(brcmf_sdiod_regrl(sdiodev,
304 ci->c_inf[idx].wrapbase+BCMA_RESET_ST,
305 NULL), 10300);
306 regdata = brcmf_sdiod_regrl(sdiodev,
307 ci->c_inf[idx].wrapbase+BCMA_RESET_ST,
308 NULL);
309 if (regdata)
310 brcmf_err("disabling core 0x%x with reset status %x\n",
311 coreid, regdata);
312 312
313 brcmf_sdiod_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_RESET_CTL, 313 /* put in reset */
314 brcmf_sdiod_regwl(sdiodev, wrapbase + BCMA_RESET_CTL,
314 BCMA_RESET_CTL_RESET, NULL); 315 BCMA_RESET_CTL_RESET, NULL);
315 udelay(1);
316
317 brcmf_sdiod_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL,
318 core_bits, NULL);
319 regdata = brcmf_sdiod_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL,
320 NULL);
321 usleep_range(10, 20); 316 usleep_range(10, 20);
322 317
318 /* wait till reset is 1 */
319 SPINWAIT(brcmf_sdiod_regrl(sdiodev, wrapbase + BCMA_RESET_CTL, NULL) !=
320 BCMA_RESET_CTL_RESET, 300);
321
322 /* post reset configure */
323 brcmf_sdiod_regwl(sdiodev, wrapbase + BCMA_IOCTL, pre_resetbits |
324 BCMA_IOCTL_FGC | BCMA_IOCTL_CLK, NULL);
325 regdata = brcmf_sdiod_regrl(sdiodev, wrapbase + BCMA_IOCTL, NULL);
323} 326}
324 327
325static void 328static void
326brcmf_sdio_sb_resetcore(struct brcmf_sdio_dev *sdiodev, 329brcmf_sdio_sb_resetcore(struct brcmf_sdio_dev *sdiodev,
327 struct chip_info *ci, u16 coreid, u32 core_bits) 330 struct chip_info *ci, u16 coreid, u32 pre_resetbits,
331 u32 in_resetbits, u32 post_resetbits)
328{ 332{
329 u32 regdata; 333 u32 regdata;
330 u8 idx; 334 u8 idx;
@@ -337,7 +341,8 @@ brcmf_sdio_sb_resetcore(struct brcmf_sdio_dev *sdiodev,
337 * Must do the disable sequence first to work for 341 * Must do the disable sequence first to work for
338 * arbitrary current core state. 342 * arbitrary current core state.
339 */ 343 */
340 brcmf_sdio_sb_coredisable(sdiodev, ci, coreid, 0); 344 brcmf_sdio_sb_coredisable(sdiodev, ci, coreid, pre_resetbits,
345 in_resetbits);
341 346
342 /* 347 /*
343 * Now do the initialization sequence. 348 * Now do the initialization sequence.
@@ -390,35 +395,32 @@ brcmf_sdio_sb_resetcore(struct brcmf_sdio_dev *sdiodev,
390 395
391static void 396static void
392brcmf_sdio_ai_resetcore(struct brcmf_sdio_dev *sdiodev, 397brcmf_sdio_ai_resetcore(struct brcmf_sdio_dev *sdiodev,
393 struct chip_info *ci, u16 coreid, u32 core_bits) 398 struct chip_info *ci, u16 coreid, u32 pre_resetbits,
399 u32 in_resetbits, u32 post_resetbits)
394{ 400{
395 u8 idx; 401 u8 idx;
396 u32 regdata; 402 u32 regdata;
403 u32 wrapbase;
397 404
398 idx = brcmf_sdio_chip_getinfidx(ci, coreid); 405 idx = brcmf_sdio_chip_getinfidx(ci, coreid);
399 if (idx == BRCMF_MAX_CORENUM) 406 if (idx == BRCMF_MAX_CORENUM)
400 return; 407 return;
401 408
409 wrapbase = ci->c_inf[idx].wrapbase;
410
402 /* must disable first to work for arbitrary current core state */ 411 /* must disable first to work for arbitrary current core state */
403 brcmf_sdio_ai_coredisable(sdiodev, ci, coreid, core_bits); 412 brcmf_sdio_ai_coredisable(sdiodev, ci, coreid, pre_resetbits,
413 in_resetbits);
404 414
405 /* now do initialization sequence */ 415 while (brcmf_sdiod_regrl(sdiodev, wrapbase + BCMA_RESET_CTL, NULL) &
406 brcmf_sdiod_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, 416 BCMA_RESET_CTL_RESET) {
407 core_bits | BCMA_IOCTL_FGC | BCMA_IOCTL_CLK, NULL); 417 brcmf_sdiod_regwl(sdiodev, wrapbase + BCMA_RESET_CTL, 0, NULL);
408 regdata = brcmf_sdiod_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, 418 usleep_range(40, 60);
409 NULL); 419 }
410 brcmf_sdiod_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_RESET_CTL,
411 0, NULL);
412 regdata = brcmf_sdiod_regrl(sdiodev,
413 ci->c_inf[idx].wrapbase+BCMA_RESET_CTL,
414 NULL);
415 udelay(1);
416 420
417 brcmf_sdiod_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, 421 brcmf_sdiod_regwl(sdiodev, wrapbase + BCMA_IOCTL, post_resetbits |
418 core_bits | BCMA_IOCTL_CLK, NULL); 422 BCMA_IOCTL_CLK, NULL);
419 regdata = brcmf_sdiod_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, 423 regdata = brcmf_sdiod_regrl(sdiodev, wrapbase + BCMA_IOCTL, NULL);
420 NULL);
421 udelay(1);
422} 424}
423 425
424#ifdef DEBUG 426#ifdef DEBUG
@@ -498,6 +500,9 @@ static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev,
498 ci->c_inf[3].base = BCM43143_CORE_ARM_BASE; 500 ci->c_inf[3].base = BCM43143_CORE_ARM_BASE;
499 ci->c_inf[3].wrapbase = ci->c_inf[3].base + 0x00100000; 501 ci->c_inf[3].wrapbase = ci->c_inf[3].base + 0x00100000;
500 ci->c_inf[3].cib = 0x07000000; 502 ci->c_inf[3].cib = 0x07000000;
503 ci->c_inf[4].id = BCMA_CORE_80211;
504 ci->c_inf[4].base = BCM43xx_CORE_D11_BASE;
505 ci->c_inf[4].wrapbase = ci->c_inf[4].base + 0x00100000;
501 ci->ramsize = BCM43143_RAMSIZE; 506 ci->ramsize = BCM43143_RAMSIZE;
502 break; 507 break;
503 case BCM43241_CHIP_ID: 508 case BCM43241_CHIP_ID:
@@ -515,6 +520,9 @@ static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev,
515 ci->c_inf[3].base = 0x18003000; 520 ci->c_inf[3].base = 0x18003000;
516 ci->c_inf[3].wrapbase = 0x18103000; 521 ci->c_inf[3].wrapbase = 0x18103000;
517 ci->c_inf[3].cib = 0x07004211; 522 ci->c_inf[3].cib = 0x07004211;
523 ci->c_inf[4].id = BCMA_CORE_80211;
524 ci->c_inf[4].base = BCM43xx_CORE_D11_BASE;
525 ci->c_inf[4].wrapbase = ci->c_inf[4].base + 0x00100000;
518 ci->ramsize = 0x90000; 526 ci->ramsize = 0x90000;
519 break; 527 break;
520 case BCM4329_CHIP_ID: 528 case BCM4329_CHIP_ID:
@@ -524,6 +532,8 @@ static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev,
524 ci->c_inf[2].base = BCM4329_CORE_SOCRAM_BASE; 532 ci->c_inf[2].base = BCM4329_CORE_SOCRAM_BASE;
525 ci->c_inf[3].id = BCMA_CORE_ARM_CM3; 533 ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
526 ci->c_inf[3].base = BCM4329_CORE_ARM_BASE; 534 ci->c_inf[3].base = BCM4329_CORE_ARM_BASE;
535 ci->c_inf[4].id = BCMA_CORE_80211;
536 ci->c_inf[4].base = BCM43xx_CORE_D11_BASE;
527 ci->ramsize = BCM4329_RAMSIZE; 537 ci->ramsize = BCM4329_RAMSIZE;
528 break; 538 break;
529 case BCM4330_CHIP_ID: 539 case BCM4330_CHIP_ID:
@@ -541,6 +551,9 @@ static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev,
541 ci->c_inf[3].base = 0x18003000; 551 ci->c_inf[3].base = 0x18003000;
542 ci->c_inf[3].wrapbase = 0x18103000; 552 ci->c_inf[3].wrapbase = 0x18103000;
543 ci->c_inf[3].cib = 0x03004211; 553 ci->c_inf[3].cib = 0x03004211;
554 ci->c_inf[4].id = BCMA_CORE_80211;
555 ci->c_inf[4].base = BCM43xx_CORE_D11_BASE;
556 ci->c_inf[4].wrapbase = ci->c_inf[4].base + 0x00100000;
544 ci->ramsize = 0x48000; 557 ci->ramsize = 0x48000;
545 break; 558 break;
546 case BCM4334_CHIP_ID: 559 case BCM4334_CHIP_ID:
@@ -558,6 +571,9 @@ static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev,
558 ci->c_inf[3].base = 0x18003000; 571 ci->c_inf[3].base = 0x18003000;
559 ci->c_inf[3].wrapbase = 0x18103000; 572 ci->c_inf[3].wrapbase = 0x18103000;
560 ci->c_inf[3].cib = 0x07004211; 573 ci->c_inf[3].cib = 0x07004211;
574 ci->c_inf[4].id = BCMA_CORE_80211;
575 ci->c_inf[4].base = BCM43xx_CORE_D11_BASE;
576 ci->c_inf[4].wrapbase = ci->c_inf[4].base + 0x00100000;
561 ci->ramsize = 0x80000; 577 ci->ramsize = 0x80000;
562 break; 578 break;
563 case BCM4335_CHIP_ID: 579 case BCM4335_CHIP_ID:
@@ -571,6 +587,9 @@ static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev,
571 ci->c_inf[2].base = 0x18002000; 587 ci->c_inf[2].base = 0x18002000;
572 ci->c_inf[2].wrapbase = 0x18102000; 588 ci->c_inf[2].wrapbase = 0x18102000;
573 ci->c_inf[2].cib = 0x01084411; 589 ci->c_inf[2].cib = 0x01084411;
590 ci->c_inf[3].id = BCMA_CORE_80211;
591 ci->c_inf[3].base = BCM43xx_CORE_D11_BASE;
592 ci->c_inf[3].wrapbase = ci->c_inf[3].base + 0x00100000;
574 ci->ramsize = 0xc0000; 593 ci->ramsize = 0xc0000;
575 ci->rambase = 0x180000; 594 ci->rambase = 0x180000;
576 break; 595 break;
@@ -585,6 +604,9 @@ static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev,
585 ci->c_inf[2].base = 0x18002000; 604 ci->c_inf[2].base = 0x18002000;
586 ci->c_inf[2].wrapbase = 0x18102000; 605 ci->c_inf[2].wrapbase = 0x18102000;
587 ci->c_inf[2].cib = 0x04084411; 606 ci->c_inf[2].cib = 0x04084411;
607 ci->c_inf[3].id = BCMA_CORE_80211;
608 ci->c_inf[3].base = BCM43xx_CORE_D11_BASE;
609 ci->c_inf[3].wrapbase = ci->c_inf[3].base + 0x00100000;
588 ci->ramsize = 0xc0000; 610 ci->ramsize = 0xc0000;
589 ci->rambase = 0x180000; 611 ci->rambase = 0x180000;
590 break; 612 break;
@@ -603,6 +625,9 @@ static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev,
603 ci->c_inf[3].base = 0x18003000; 625 ci->c_inf[3].base = 0x18003000;
604 ci->c_inf[3].wrapbase = 0x18103000; 626 ci->c_inf[3].wrapbase = 0x18103000;
605 ci->c_inf[3].cib = 0x03004211; 627 ci->c_inf[3].cib = 0x03004211;
628 ci->c_inf[4].id = BCMA_CORE_80211;
629 ci->c_inf[4].base = BCM43xx_CORE_D11_BASE;
630 ci->c_inf[4].wrapbase = ci->c_inf[4].base + 0x00100000;
606 ci->ramsize = 0x3C000; 631 ci->ramsize = 0x3C000;
607 break; 632 break;
608 default: 633 default:
@@ -713,7 +738,7 @@ brcmf_sdio_chip_buscoresetup(struct brcmf_sdio_dev *sdiodev,
713 * Make sure any on-chip ARM is off (in case strapping is wrong), 738 * Make sure any on-chip ARM is off (in case strapping is wrong),
714 * or downloaded code was already running. 739 * or downloaded code was already running.
715 */ 740 */
716 ci->coredisable(sdiodev, ci, BCMA_CORE_ARM_CM3, 0); 741 ci->coredisable(sdiodev, ci, BCMA_CORE_ARM_CM3, 0, 0);
717} 742}
718 743
719int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev, 744int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev,
@@ -846,8 +871,11 @@ static void
846brcmf_sdio_chip_cm3_enterdl(struct brcmf_sdio_dev *sdiodev, 871brcmf_sdio_chip_cm3_enterdl(struct brcmf_sdio_dev *sdiodev,
847 struct chip_info *ci) 872 struct chip_info *ci)
848{ 873{
849 ci->coredisable(sdiodev, ci, BCMA_CORE_ARM_CM3, 0); 874 ci->coredisable(sdiodev, ci, BCMA_CORE_ARM_CM3, 0, 0);
850 ci->resetcore(sdiodev, ci, BCMA_CORE_INTERNAL_MEM, 0); 875 ci->resetcore(sdiodev, ci, BCMA_CORE_80211,
876 D11_BCMA_IOCTL_PHYRESET | D11_BCMA_IOCTL_PHYCLOCKEN,
877 D11_BCMA_IOCTL_PHYCLOCKEN, D11_BCMA_IOCTL_PHYCLOCKEN);
878 ci->resetcore(sdiodev, ci, BCMA_CORE_INTERNAL_MEM, 0, 0, 0);
851} 879}
852 880
853static bool 881static bool
@@ -867,7 +895,7 @@ brcmf_sdio_chip_cm3_exitdl(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci)
867 reg_addr += offsetof(struct sdpcmd_regs, intstatus); 895 reg_addr += offsetof(struct sdpcmd_regs, intstatus);
868 brcmf_sdiod_regwl(sdiodev, reg_addr, 0xFFFFFFFF, NULL); 896 brcmf_sdiod_regwl(sdiodev, reg_addr, 0xFFFFFFFF, NULL);
869 897
870 ci->resetcore(sdiodev, ci, BCMA_CORE_ARM_CM3, 0); 898 ci->resetcore(sdiodev, ci, BCMA_CORE_ARM_CM3, 0, 0, 0);
871 899
872 return true; 900 return true;
873} 901}
@@ -876,8 +904,22 @@ static inline void
876brcmf_sdio_chip_cr4_enterdl(struct brcmf_sdio_dev *sdiodev, 904brcmf_sdio_chip_cr4_enterdl(struct brcmf_sdio_dev *sdiodev,
877 struct chip_info *ci) 905 struct chip_info *ci)
878{ 906{
879 ci->resetcore(sdiodev, ci, BCMA_CORE_ARM_CR4, 907 u8 idx;
880 ARMCR4_BCMA_IOCTL_CPUHALT); 908 u32 regdata;
909 u32 wrapbase;
910 idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_ARM_CR4);
911
912 if (idx == BRCMF_MAX_CORENUM)
913 return;
914
915 wrapbase = ci->c_inf[idx].wrapbase;
916 regdata = brcmf_sdiod_regrl(sdiodev, wrapbase + BCMA_IOCTL, NULL);
917 regdata &= ARMCR4_BCMA_IOCTL_CPUHALT;
918 ci->resetcore(sdiodev, ci, BCMA_CORE_ARM_CR4, regdata,
919 ARMCR4_BCMA_IOCTL_CPUHALT, ARMCR4_BCMA_IOCTL_CPUHALT);
920 ci->resetcore(sdiodev, ci, BCMA_CORE_80211,
921 D11_BCMA_IOCTL_PHYRESET | D11_BCMA_IOCTL_PHYCLOCKEN,
922 D11_BCMA_IOCTL_PHYCLOCKEN, D11_BCMA_IOCTL_PHYCLOCKEN);
881} 923}
882 924
883static bool 925static bool
@@ -897,7 +939,8 @@ brcmf_sdio_chip_cr4_exitdl(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci)
897 sizeof(ci->rst_vec)); 939 sizeof(ci->rst_vec));
898 940
899 /* restore ARM */ 941 /* restore ARM */
900 ci->resetcore(sdiodev, ci, BCMA_CORE_ARM_CR4, 0); 942 ci->resetcore(sdiodev, ci, BCMA_CORE_ARM_CR4, ARMCR4_BCMA_IOCTL_CPUHALT,
943 0, 0);
901 944
902 return true; 945 return true;
903} 946}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h
index c7d0dbc1ab59..91c61cb9de87 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h
@@ -81,9 +81,11 @@ struct chip_info {
81 u32 (*corerev)(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci, 81 u32 (*corerev)(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci,
82 u16 coreid); 82 u16 coreid);
83 void (*coredisable)(struct brcmf_sdio_dev *sdiodev, 83 void (*coredisable)(struct brcmf_sdio_dev *sdiodev,
84 struct chip_info *ci, u16 coreid, u32 core_bits); 84 struct chip_info *ci, u16 coreid, u32 pre_resetbits,
85 u32 in_resetbits);
85 void (*resetcore)(struct brcmf_sdio_dev *sdiodev, 86 void (*resetcore)(struct brcmf_sdio_dev *sdiodev,
86 struct chip_info *ci, u16 coreid, u32 core_bits); 87 struct chip_info *ci, u16 coreid, u32 pre_resetbits,
88 u32 in_resetbits, u32 post_resetbits);
87}; 89};
88 90
89struct sbconfig { 91struct sbconfig {