summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
diff options
context:
space:
mode:
authorArend van Spriel <arend@broadcom.com>2013-12-12 11:59:06 +0100
committerJohn W. Linville <linville@tuxdriver.com>2013-12-18 15:23:00 -0500
commit36c4e7e4aa0605cd175ee4b953eaced7a00157f4 (patch)
treed7193da72e7d036d1a5df332e87c5df0a8ec6146 /drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
parent9fbe2a6dc71d85e166eea43842a55af3d62a4d7b (diff)
brcmfmac: clarify struct brcmf_sdio_dev::func[0] reference
The struct brcmf_sdio_dev contains array of sdio functions that are used in the driver. However, during probe func[0] entry was assigned to the function 1 reference. This was corrected upon doing the actual I/O access. This patch makes it more clear by creating the func[0] entry properly and use it as is during I/O access. Reviewed-by: Franky Lin <frankyl@broadcom.com> Reviewed-by: Hante Meuleman <meuleman@broadcom.com> Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com> Signed-off-by: Arend van Spriel <arend@broadcom.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c')
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c36
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)
return 0;
}
-static inline int brcmf_sdiod_f0_write_byte(struct brcmf_sdio_dev *sdiodev,
- uint regaddr, u8 *byte)
+static inline int brcmf_sdiod_f0_writeb(struct sdio_func *func,
+ uint regaddr, u8 byte)
{
- struct sdio_func *sdfunc = sdiodev->func[0];
int err_ret;
/*
* Can only directly write to some F0 registers.
- * Handle F2 enable/disable and Abort command
+ * Handle CCCR_IENx and CCCR_ABORT command
* as a special case.
*/
if ((regaddr == SDIO_CCCR_ABORT) ||
- (regaddr == SDIO_CCCR_IENx)) {
- sdfunc = kmemdup(sdiodev->func[0], sizeof(struct sdio_func),
- GFP_KERNEL);
- if (!sdfunc)
- return -ENOMEM;
- sdfunc->num = 0;
- sdio_writeb(sdfunc, *byte, regaddr, &err_ret);
- kfree(sdfunc);
- } else if (regaddr < 0xF0) {
- brcmf_err("F0 Wr:0x%02x: write disallowed\n", regaddr);
- err_ret = -EPERM;
- } else {
- sdio_f0_writeb(sdfunc, *byte, regaddr, &err_ret);
- }
+ (regaddr == SDIO_CCCR_IENx))
+ sdio_writeb(func, byte, regaddr, &err_ret);
+ else
+ sdio_f0_writeb(func, byte, regaddr, &err_ret);
return err_ret;
}
@@ -240,7 +229,8 @@ static int brcmf_sdiod_request_byte(struct brcmf_sdio_dev *sdiodev, uint rw,
if (rw && func == 0) {
/* handle F0 separately */
- err_ret = brcmf_sdiod_f0_write_byte(sdiodev, regaddr, byte);
+ err_ret = brcmf_sdiod_f0_writeb(sdiodev->func[func],
+ regaddr, *byte);
} else {
if (rw) /* CMD52 Write */
sdio_writeb(sdiodev->func[func], *byte, regaddr,
@@ -1030,7 +1020,11 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func,
return -ENOMEM;
}
- sdiodev->func[0] = func->card->sdio_func[0];
+ /* store refs to functions used. mmc_card does
+ * not hold the F0 function pointer.
+ */
+ sdiodev->func[0] = kmemdup(func, sizeof(*func), GFP_KERNEL);
+ sdiodev->func[0]->num = 0;
sdiodev->func[1] = func->card->sdio_func[0];
sdiodev->func[2] = func;
@@ -1060,6 +1054,7 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func,
fail:
dev_set_drvdata(&func->dev, NULL);
dev_set_drvdata(&sdiodev->func[1]->dev, NULL);
+ kfree(sdiodev->func[0]);
kfree(sdiodev);
kfree(bus_if);
return err;
@@ -1087,6 +1082,7 @@ static void brcmf_ops_sdio_remove(struct sdio_func *func)
dev_set_drvdata(&sdiodev->func[2]->dev, NULL);
kfree(bus_if);
+ kfree(sdiodev->func[0]);
kfree(sdiodev);
}