diff options
Diffstat (limited to 'drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c')
| -rw-r--r-- | drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 71 |
1 files changed, 47 insertions, 24 deletions
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c index 0cd5b8d970d7..4d104ab80fd8 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | |||
| @@ -2999,21 +2999,35 @@ static int brcmf_sdio_trap_info(struct seq_file *seq, struct brcmf_sdio *bus, | |||
| 2999 | if (error < 0) | 2999 | if (error < 0) |
| 3000 | return error; | 3000 | return error; |
| 3001 | 3001 | ||
| 3002 | seq_printf(seq, | 3002 | if (seq) |
| 3003 | "dongle trap info: type 0x%x @ epc 0x%08x\n" | 3003 | seq_printf(seq, |
| 3004 | " cpsr 0x%08x spsr 0x%08x sp 0x%08x\n" | 3004 | "dongle trap info: type 0x%x @ epc 0x%08x\n" |
| 3005 | " lr 0x%08x pc 0x%08x offset 0x%x\n" | 3005 | " cpsr 0x%08x spsr 0x%08x sp 0x%08x\n" |
| 3006 | " r0 0x%08x r1 0x%08x r2 0x%08x r3 0x%08x\n" | 3006 | " lr 0x%08x pc 0x%08x offset 0x%x\n" |
| 3007 | " r4 0x%08x r5 0x%08x r6 0x%08x r7 0x%08x\n", | 3007 | " r0 0x%08x r1 0x%08x r2 0x%08x r3 0x%08x\n" |
| 3008 | le32_to_cpu(tr.type), le32_to_cpu(tr.epc), | 3008 | " r4 0x%08x r5 0x%08x r6 0x%08x r7 0x%08x\n", |
| 3009 | le32_to_cpu(tr.cpsr), le32_to_cpu(tr.spsr), | 3009 | le32_to_cpu(tr.type), le32_to_cpu(tr.epc), |
| 3010 | le32_to_cpu(tr.r13), le32_to_cpu(tr.r14), | 3010 | le32_to_cpu(tr.cpsr), le32_to_cpu(tr.spsr), |
| 3011 | le32_to_cpu(tr.pc), sh->trap_addr, | 3011 | le32_to_cpu(tr.r13), le32_to_cpu(tr.r14), |
| 3012 | le32_to_cpu(tr.r0), le32_to_cpu(tr.r1), | 3012 | le32_to_cpu(tr.pc), sh->trap_addr, |
| 3013 | le32_to_cpu(tr.r2), le32_to_cpu(tr.r3), | 3013 | le32_to_cpu(tr.r0), le32_to_cpu(tr.r1), |
| 3014 | le32_to_cpu(tr.r4), le32_to_cpu(tr.r5), | 3014 | le32_to_cpu(tr.r2), le32_to_cpu(tr.r3), |
| 3015 | le32_to_cpu(tr.r6), le32_to_cpu(tr.r7)); | 3015 | le32_to_cpu(tr.r4), le32_to_cpu(tr.r5), |
| 3016 | 3016 | le32_to_cpu(tr.r6), le32_to_cpu(tr.r7)); | |
| 3017 | else | ||
| 3018 | pr_debug("dongle trap info: type 0x%x @ epc 0x%08x\n" | ||
| 3019 | " cpsr 0x%08x spsr 0x%08x sp 0x%08x\n" | ||
| 3020 | " lr 0x%08x pc 0x%08x offset 0x%x\n" | ||
| 3021 | " r0 0x%08x r1 0x%08x r2 0x%08x r3 0x%08x\n" | ||
| 3022 | " r4 0x%08x r5 0x%08x r6 0x%08x r7 0x%08x\n", | ||
| 3023 | le32_to_cpu(tr.type), le32_to_cpu(tr.epc), | ||
| 3024 | le32_to_cpu(tr.cpsr), le32_to_cpu(tr.spsr), | ||
| 3025 | le32_to_cpu(tr.r13), le32_to_cpu(tr.r14), | ||
| 3026 | le32_to_cpu(tr.pc), sh->trap_addr, | ||
| 3027 | le32_to_cpu(tr.r0), le32_to_cpu(tr.r1), | ||
| 3028 | le32_to_cpu(tr.r2), le32_to_cpu(tr.r3), | ||
| 3029 | le32_to_cpu(tr.r4), le32_to_cpu(tr.r5), | ||
| 3030 | le32_to_cpu(tr.r6), le32_to_cpu(tr.r7)); | ||
| 3017 | return 0; | 3031 | return 0; |
| 3018 | } | 3032 | } |
| 3019 | 3033 | ||
| @@ -3067,8 +3081,10 @@ static int brcmf_sdio_checkdied(struct brcmf_sdio *bus) | |||
| 3067 | else if (sh.flags & SDPCM_SHARED_ASSERT) | 3081 | else if (sh.flags & SDPCM_SHARED_ASSERT) |
| 3068 | brcmf_err("assertion in dongle\n"); | 3082 | brcmf_err("assertion in dongle\n"); |
| 3069 | 3083 | ||
| 3070 | if (sh.flags & SDPCM_SHARED_TRAP) | 3084 | if (sh.flags & SDPCM_SHARED_TRAP) { |
| 3071 | brcmf_err("firmware trap in dongle\n"); | 3085 | brcmf_err("firmware trap in dongle\n"); |
| 3086 | brcmf_sdio_trap_info(NULL, bus, &sh); | ||
| 3087 | } | ||
| 3072 | 3088 | ||
| 3073 | return 0; | 3089 | return 0; |
| 3074 | } | 3090 | } |
| @@ -3143,9 +3159,12 @@ static int brcmf_debugfs_sdio_count_read(struct seq_file *seq, void *data) | |||
| 3143 | return 0; | 3159 | return 0; |
| 3144 | } | 3160 | } |
| 3145 | 3161 | ||
| 3146 | static void brcmf_sdio_debugfs_create(struct brcmf_sdio *bus) | 3162 | static void brcmf_sdio_debugfs_create(struct device *dev) |
| 3147 | { | 3163 | { |
| 3148 | struct brcmf_pub *drvr = bus->sdiodev->bus_if->drvr; | 3164 | struct brcmf_bus *bus_if = dev_get_drvdata(dev); |
| 3165 | struct brcmf_pub *drvr = bus_if->drvr; | ||
| 3166 | struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; | ||
| 3167 | struct brcmf_sdio *bus = sdiodev->bus; | ||
| 3149 | struct dentry *dentry = brcmf_debugfs_get_devdir(drvr); | 3168 | struct dentry *dentry = brcmf_debugfs_get_devdir(drvr); |
| 3150 | 3169 | ||
| 3151 | if (IS_ERR_OR_NULL(dentry)) | 3170 | if (IS_ERR_OR_NULL(dentry)) |
| @@ -3165,7 +3184,7 @@ static int brcmf_sdio_checkdied(struct brcmf_sdio *bus) | |||
| 3165 | return 0; | 3184 | return 0; |
| 3166 | } | 3185 | } |
| 3167 | 3186 | ||
| 3168 | static void brcmf_sdio_debugfs_create(struct brcmf_sdio *bus) | 3187 | static void brcmf_sdio_debugfs_create(struct device *dev) |
| 3169 | { | 3188 | { |
| 3170 | } | 3189 | } |
| 3171 | #endif /* DEBUG */ | 3190 | #endif /* DEBUG */ |
| @@ -3477,8 +3496,6 @@ static int brcmf_sdio_bus_preinit(struct device *dev) | |||
| 3477 | if (bus->rxbuf) | 3496 | if (bus->rxbuf) |
| 3478 | bus->rxblen = value; | 3497 | bus->rxblen = value; |
| 3479 | 3498 | ||
| 3480 | brcmf_sdio_debugfs_create(bus); | ||
| 3481 | |||
| 3482 | /* the commands below use the terms tx and rx from | 3499 | /* the commands below use the terms tx and rx from |
| 3483 | * a device perspective, ie. bus:txglom affects the | 3500 | * a device perspective, ie. bus:txglom affects the |
| 3484 | * bus transfers from device to host. | 3501 | * bus transfers from device to host. |
| @@ -4088,6 +4105,7 @@ static const struct brcmf_bus_ops brcmf_sdio_bus_ops = { | |||
| 4088 | .get_ramsize = brcmf_sdio_bus_get_ramsize, | 4105 | .get_ramsize = brcmf_sdio_bus_get_ramsize, |
| 4089 | .get_memdump = brcmf_sdio_bus_get_memdump, | 4106 | .get_memdump = brcmf_sdio_bus_get_memdump, |
| 4090 | .get_fwname = brcmf_sdio_get_fwname, | 4107 | .get_fwname = brcmf_sdio_get_fwname, |
| 4108 | .debugfs_create = brcmf_sdio_debugfs_create | ||
| 4091 | }; | 4109 | }; |
| 4092 | 4110 | ||
| 4093 | #define BRCMF_SDIO_FW_CODE 0 | 4111 | #define BRCMF_SDIO_FW_CODE 0 |
| @@ -4197,7 +4215,7 @@ static void brcmf_sdio_firmware_callback(struct device *dev, int err, | |||
| 4197 | } else { | 4215 | } else { |
| 4198 | /* Disable F2 again */ | 4216 | /* Disable F2 again */ |
| 4199 | sdio_disable_func(sdiod->func2); | 4217 | sdio_disable_func(sdiod->func2); |
| 4200 | goto release; | 4218 | goto checkdied; |
| 4201 | } | 4219 | } |
| 4202 | 4220 | ||
| 4203 | if (brcmf_chip_sr_capable(bus->ci)) { | 4221 | if (brcmf_chip_sr_capable(bus->ci)) { |
| @@ -4218,8 +4236,10 @@ static void brcmf_sdio_firmware_callback(struct device *dev, int err, | |||
| 4218 | } | 4236 | } |
| 4219 | 4237 | ||
| 4220 | /* If we didn't come up, turn off backplane clock */ | 4238 | /* If we didn't come up, turn off backplane clock */ |
| 4221 | if (err != 0) | 4239 | if (err != 0) { |
| 4222 | brcmf_sdio_clkctl(bus, CLK_NONE, false); | 4240 | brcmf_sdio_clkctl(bus, CLK_NONE, false); |
| 4241 | goto checkdied; | ||
| 4242 | } | ||
| 4223 | 4243 | ||
| 4224 | sdio_release_host(sdiod->func1); | 4244 | sdio_release_host(sdiod->func1); |
| 4225 | 4245 | ||
| @@ -4233,12 +4253,15 @@ static void brcmf_sdio_firmware_callback(struct device *dev, int err, | |||
| 4233 | err = brcmf_attach(sdiod->dev, sdiod->settings); | 4253 | err = brcmf_attach(sdiod->dev, sdiod->settings); |
| 4234 | if (err != 0) { | 4254 | if (err != 0) { |
| 4235 | brcmf_err("brcmf_attach failed\n"); | 4255 | brcmf_err("brcmf_attach failed\n"); |
| 4236 | goto fail; | 4256 | sdio_claim_host(sdiod->func1); |
| 4257 | goto checkdied; | ||
| 4237 | } | 4258 | } |
| 4238 | 4259 | ||
| 4239 | /* ready */ | 4260 | /* ready */ |
| 4240 | return; | 4261 | return; |
| 4241 | 4262 | ||
| 4263 | checkdied: | ||
| 4264 | brcmf_sdio_checkdied(bus); | ||
| 4242 | release: | 4265 | release: |
| 4243 | sdio_release_host(sdiod->func1); | 4266 | sdio_release_host(sdiod->func1); |
| 4244 | fail: | 4267 | fail: |
