diff options
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | 36 |
1 files changed, 16 insertions, 20 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c index 7550f9f1211f..2b5cde67e728 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | |||
@@ -197,32 +197,21 @@ int brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev *sdiodev) | |||
197 | return 0; | 197 | return 0; |
198 | } | 198 | } |
199 | 199 | ||
200 | static inline int brcmf_sdiod_f0_write_byte(struct brcmf_sdio_dev *sdiodev, | 200 | static inline int brcmf_sdiod_f0_writeb(struct sdio_func *func, |
201 | uint regaddr, u8 *byte) | 201 | uint regaddr, u8 byte) |
202 | { | 202 | { |
203 | struct sdio_func *sdfunc = sdiodev->func[0]; | ||
204 | int err_ret; | 203 | int err_ret; |
205 | 204 | ||
206 | /* | 205 | /* |
207 | * Can only directly write to some F0 registers. | 206 | * Can only directly write to some F0 registers. |
208 | * Handle F2 enable/disable and Abort command | 207 | * Handle CCCR_IENx and CCCR_ABORT command |
209 | * as a special case. | 208 | * as a special case. |
210 | */ | 209 | */ |
211 | if ((regaddr == SDIO_CCCR_ABORT) || | 210 | if ((regaddr == SDIO_CCCR_ABORT) || |
212 | (regaddr == SDIO_CCCR_IENx)) { | 211 | (regaddr == SDIO_CCCR_IENx)) |
213 | sdfunc = kmemdup(sdiodev->func[0], sizeof(struct sdio_func), | 212 | sdio_writeb(func, byte, regaddr, &err_ret); |
214 | GFP_KERNEL); | 213 | else |
215 | if (!sdfunc) | 214 | sdio_f0_writeb(func, byte, regaddr, &err_ret); |
216 | return -ENOMEM; | ||
217 | sdfunc->num = 0; | ||
218 | sdio_writeb(sdfunc, *byte, regaddr, &err_ret); | ||
219 | kfree(sdfunc); | ||
220 | } else if (regaddr < 0xF0) { | ||
221 | brcmf_err("F0 Wr:0x%02x: write disallowed\n", regaddr); | ||
222 | err_ret = -EPERM; | ||
223 | } else { | ||
224 | sdio_f0_writeb(sdfunc, *byte, regaddr, &err_ret); | ||
225 | } | ||
226 | 215 | ||
227 | return err_ret; | 216 | return err_ret; |
228 | } | 217 | } |
@@ -240,7 +229,8 @@ static int brcmf_sdiod_request_byte(struct brcmf_sdio_dev *sdiodev, uint rw, | |||
240 | 229 | ||
241 | if (rw && func == 0) { | 230 | if (rw && func == 0) { |
242 | /* handle F0 separately */ | 231 | /* handle F0 separately */ |
243 | err_ret = brcmf_sdiod_f0_write_byte(sdiodev, regaddr, byte); | 232 | err_ret = brcmf_sdiod_f0_writeb(sdiodev->func[func], |
233 | regaddr, *byte); | ||
244 | } else { | 234 | } else { |
245 | if (rw) /* CMD52 Write */ | 235 | if (rw) /* CMD52 Write */ |
246 | sdio_writeb(sdiodev->func[func], *byte, regaddr, | 236 | sdio_writeb(sdiodev->func[func], *byte, regaddr, |
@@ -1030,7 +1020,11 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func, | |||
1030 | return -ENOMEM; | 1020 | return -ENOMEM; |
1031 | } | 1021 | } |
1032 | 1022 | ||
1033 | sdiodev->func[0] = func->card->sdio_func[0]; | 1023 | /* store refs to functions used. mmc_card does |
1024 | * not hold the F0 function pointer. | ||
1025 | */ | ||
1026 | sdiodev->func[0] = kmemdup(func, sizeof(*func), GFP_KERNEL); | ||
1027 | sdiodev->func[0]->num = 0; | ||
1034 | sdiodev->func[1] = func->card->sdio_func[0]; | 1028 | sdiodev->func[1] = func->card->sdio_func[0]; |
1035 | sdiodev->func[2] = func; | 1029 | sdiodev->func[2] = func; |
1036 | 1030 | ||
@@ -1060,6 +1054,7 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func, | |||
1060 | fail: | 1054 | fail: |
1061 | dev_set_drvdata(&func->dev, NULL); | 1055 | dev_set_drvdata(&func->dev, NULL); |
1062 | dev_set_drvdata(&sdiodev->func[1]->dev, NULL); | 1056 | dev_set_drvdata(&sdiodev->func[1]->dev, NULL); |
1057 | kfree(sdiodev->func[0]); | ||
1063 | kfree(sdiodev); | 1058 | kfree(sdiodev); |
1064 | kfree(bus_if); | 1059 | kfree(bus_if); |
1065 | return err; | 1060 | return err; |
@@ -1087,6 +1082,7 @@ static void brcmf_ops_sdio_remove(struct sdio_func *func) | |||
1087 | dev_set_drvdata(&sdiodev->func[2]->dev, NULL); | 1082 | dev_set_drvdata(&sdiodev->func[2]->dev, NULL); |
1088 | 1083 | ||
1089 | kfree(bus_if); | 1084 | kfree(bus_if); |
1085 | kfree(sdiodev->func[0]); | ||
1090 | kfree(sdiodev); | 1086 | kfree(sdiodev); |
1091 | } | 1087 | } |
1092 | 1088 | ||