Commit 4ab2cf03 authored by Arend van Spriel's avatar Arend van Spriel Committed by Kalle Valo

brcmfmac: check and dump trap info during sdio probe

When the firmware crashes during the probe sequence we provide little
information on what really failed. This patch checks the sdpcm shared
location and show the trap information if a firmware trap has happened.
Reviewed-by: default avatarHante Meuleman <hante.meuleman@broadcom.com>
Reviewed-by: default avatarPieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
Reviewed-by: default avatarFranky Lin <franky.lin@broadcom.com>
Signed-off-by: default avatarArend van Spriel <arend.vanspriel@broadcom.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent 92d3b88b
...@@ -2999,6 +2999,7 @@ static int brcmf_sdio_trap_info(struct seq_file *seq, struct brcmf_sdio *bus, ...@@ -2999,6 +2999,7 @@ static int brcmf_sdio_trap_info(struct seq_file *seq, struct brcmf_sdio *bus,
if (error < 0) if (error < 0)
return error; return error;
if (seq)
seq_printf(seq, seq_printf(seq,
"dongle trap info: type 0x%x @ epc 0x%08x\n" "dongle trap info: type 0x%x @ epc 0x%08x\n"
" cpsr 0x%08x spsr 0x%08x sp 0x%08x\n" " cpsr 0x%08x spsr 0x%08x sp 0x%08x\n"
...@@ -3013,7 +3014,20 @@ static int brcmf_sdio_trap_info(struct seq_file *seq, struct brcmf_sdio *bus, ...@@ -3013,7 +3014,20 @@ static int brcmf_sdio_trap_info(struct seq_file *seq, struct brcmf_sdio *bus,
le32_to_cpu(tr.r2), le32_to_cpu(tr.r3), le32_to_cpu(tr.r2), le32_to_cpu(tr.r3),
le32_to_cpu(tr.r4), le32_to_cpu(tr.r5), le32_to_cpu(tr.r4), le32_to_cpu(tr.r5),
le32_to_cpu(tr.r6), le32_to_cpu(tr.r7)); le32_to_cpu(tr.r6), le32_to_cpu(tr.r7));
else
pr_debug("dongle trap info: type 0x%x @ epc 0x%08x\n"
" cpsr 0x%08x spsr 0x%08x sp 0x%08x\n"
" lr 0x%08x pc 0x%08x offset 0x%x\n"
" r0 0x%08x r1 0x%08x r2 0x%08x r3 0x%08x\n"
" r4 0x%08x r5 0x%08x r6 0x%08x r7 0x%08x\n",
le32_to_cpu(tr.type), le32_to_cpu(tr.epc),
le32_to_cpu(tr.cpsr), le32_to_cpu(tr.spsr),
le32_to_cpu(tr.r13), le32_to_cpu(tr.r14),
le32_to_cpu(tr.pc), sh->trap_addr,
le32_to_cpu(tr.r0), le32_to_cpu(tr.r1),
le32_to_cpu(tr.r2), le32_to_cpu(tr.r3),
le32_to_cpu(tr.r4), le32_to_cpu(tr.r5),
le32_to_cpu(tr.r6), le32_to_cpu(tr.r7));
return 0; return 0;
} }
...@@ -3067,8 +3081,10 @@ static int brcmf_sdio_checkdied(struct brcmf_sdio *bus) ...@@ -3067,8 +3081,10 @@ static int brcmf_sdio_checkdied(struct brcmf_sdio *bus)
else if (sh.flags & SDPCM_SHARED_ASSERT) else if (sh.flags & SDPCM_SHARED_ASSERT)
brcmf_err("assertion in dongle\n"); brcmf_err("assertion in dongle\n");
if (sh.flags & SDPCM_SHARED_TRAP) if (sh.flags & SDPCM_SHARED_TRAP) {
brcmf_err("firmware trap in dongle\n"); brcmf_err("firmware trap in dongle\n");
brcmf_sdio_trap_info(NULL, bus, &sh);
}
return 0; return 0;
} }
...@@ -4199,7 +4215,7 @@ static void brcmf_sdio_firmware_callback(struct device *dev, int err, ...@@ -4199,7 +4215,7 @@ static void brcmf_sdio_firmware_callback(struct device *dev, int err,
} else { } else {
/* Disable F2 again */ /* Disable F2 again */
sdio_disable_func(sdiod->func2); sdio_disable_func(sdiod->func2);
goto release; goto checkdied;
} }
if (brcmf_chip_sr_capable(bus->ci)) { if (brcmf_chip_sr_capable(bus->ci)) {
...@@ -4220,8 +4236,10 @@ static void brcmf_sdio_firmware_callback(struct device *dev, int err, ...@@ -4220,8 +4236,10 @@ static void brcmf_sdio_firmware_callback(struct device *dev, int err,
} }
/* If we didn't come up, turn off backplane clock */ /* If we didn't come up, turn off backplane clock */
if (err != 0) if (err != 0) {
brcmf_sdio_clkctl(bus, CLK_NONE, false); brcmf_sdio_clkctl(bus, CLK_NONE, false);
goto checkdied;
}
sdio_release_host(sdiod->func1); sdio_release_host(sdiod->func1);
...@@ -4235,12 +4253,15 @@ static void brcmf_sdio_firmware_callback(struct device *dev, int err, ...@@ -4235,12 +4253,15 @@ static void brcmf_sdio_firmware_callback(struct device *dev, int err,
err = brcmf_attach(sdiod->dev, sdiod->settings); err = brcmf_attach(sdiod->dev, sdiod->settings);
if (err != 0) { if (err != 0) {
brcmf_err("brcmf_attach failed\n"); brcmf_err("brcmf_attach failed\n");
goto fail; sdio_claim_host(sdiod->func1);
goto checkdied;
} }
/* ready */ /* ready */
return; return;
checkdied:
brcmf_sdio_checkdied(bus);
release: release:
sdio_release_host(sdiod->func1); sdio_release_host(sdiod->func1);
fail: fail:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment