brcmfmac: use sdio functions to enable/disable F2
Instead of catching CCCR_IOEx register in F0 write access to determine whether F2 state needs to change do it with direct call to sdio_[enable/disable]_func(). 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>
This commit is contained in:
parent
463c30b3f9
commit
71370eb87b
|
@ -53,6 +53,9 @@
|
|||
|
||||
#define SDIO_FUNC1_BLOCKSIZE 64
|
||||
#define SDIO_FUNC2_BLOCKSIZE 512
|
||||
/* Maximum milliseconds to wait for F2 to come up */
|
||||
#define SDIO_WAIT_F2RDY 3000
|
||||
|
||||
|
||||
static irqreturn_t brcmf_sdio_oob_irqhandler(int irq, void *dev_id)
|
||||
{
|
||||
|
@ -205,27 +208,8 @@ static inline int brcmf_sdioh_f0_write_byte(struct brcmf_sdio_dev *sdiodev,
|
|||
* Handle F2 enable/disable and Abort command
|
||||
* as a special case.
|
||||
*/
|
||||
if (regaddr == SDIO_CCCR_IOEx) {
|
||||
sdfunc = sdiodev->func[2];
|
||||
if (sdfunc) {
|
||||
if (*byte & SDIO_FUNC_ENABLE_2) {
|
||||
/* Enable Function 2 */
|
||||
err_ret = sdio_enable_func(sdfunc);
|
||||
if (err_ret)
|
||||
brcmf_err("enable F2 failed:%d\n",
|
||||
err_ret);
|
||||
} else {
|
||||
/* Disable Function 2 */
|
||||
err_ret = sdio_disable_func(sdfunc);
|
||||
if (err_ret)
|
||||
brcmf_err("Disable F2 failed:%d\n",
|
||||
err_ret);
|
||||
}
|
||||
} else {
|
||||
err_ret = -ENOENT;
|
||||
}
|
||||
} else if ((regaddr == SDIO_CCCR_ABORT) ||
|
||||
(regaddr == SDIO_CCCR_IENx)) {
|
||||
if ((regaddr == SDIO_CCCR_ABORT) ||
|
||||
(regaddr == SDIO_CCCR_IENx)) {
|
||||
sdfunc = kmemdup(sdiodev->func[0], sizeof(struct sdio_func),
|
||||
GFP_KERNEL);
|
||||
if (!sdfunc)
|
||||
|
@ -945,6 +929,9 @@ static int brcmf_sdioh_attach(struct brcmf_sdio_dev *sdiodev)
|
|||
goto out;
|
||||
}
|
||||
|
||||
/* increase F2 timeout */
|
||||
sdiodev->func[2]->enable_timeout = SDIO_WAIT_F2RDY;
|
||||
|
||||
/* Enable Function 1 */
|
||||
err_ret = sdio_enable_func(sdiodev->func[1]);
|
||||
if (err_ret) {
|
||||
|
|
|
@ -260,9 +260,6 @@ struct rte_console {
|
|||
#define MAX_HDR_READ (1 << 6)
|
||||
#define MAX_RX_DATASZ 2048
|
||||
|
||||
/* Maximum milliseconds to wait for F2 to come up */
|
||||
#define BRCMF_WAIT_F2RDY 3000
|
||||
|
||||
/* Bump up limit on waiting for HT to account for first startup;
|
||||
* if the image is doing a CRC calculation before programming the PMU
|
||||
* for HT availability, it could take a couple hundred ms more, so
|
||||
|
@ -2265,8 +2262,7 @@ static void brcmf_sdbrcm_bus_stop(struct device *dev)
|
|||
|
||||
/* Turn off the bus (F2), free any pending packets */
|
||||
brcmf_dbg(INTR, "disable SDIO interrupts\n");
|
||||
brcmf_sdio_regwb(bus->sdiodev, SDIO_CCCR_IOEx, SDIO_FUNC_ENABLE_1,
|
||||
NULL);
|
||||
sdio_disable_func(bus->sdiodev->func[SDIO_FUNC_2]);
|
||||
|
||||
/* Clear any pending interrupts now that F2 is disabled */
|
||||
w_sdreg32(bus, local_hostintmask,
|
||||
|
@ -3570,8 +3566,6 @@ static int brcmf_sdbrcm_bus_init(struct device *dev)
|
|||
struct brcmf_bus *bus_if = dev_get_drvdata(dev);
|
||||
struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
|
||||
struct brcmf_sdio *bus = sdiodev->bus;
|
||||
unsigned long timeout;
|
||||
u8 ready, enable;
|
||||
int err, ret = 0;
|
||||
u8 saveclk;
|
||||
|
||||
|
@ -3612,26 +3606,13 @@ static int brcmf_sdbrcm_bus_init(struct device *dev)
|
|||
/* Enable function 2 (frame transfers) */
|
||||
w_sdreg32(bus, SDPCM_PROT_VERSION << SMB_DATA_VERSION_SHIFT,
|
||||
offsetof(struct sdpcmd_regs, tosbmailboxdata));
|
||||
enable = (SDIO_FUNC_ENABLE_1 | SDIO_FUNC_ENABLE_2);
|
||||
err = sdio_enable_func(bus->sdiodev->func[SDIO_FUNC_2]);
|
||||
|
||||
brcmf_sdio_regwb(bus->sdiodev, SDIO_CCCR_IOEx, enable, NULL);
|
||||
|
||||
timeout = jiffies + msecs_to_jiffies(BRCMF_WAIT_F2RDY);
|
||||
ready = 0;
|
||||
while (enable != ready) {
|
||||
ready = brcmf_sdio_regrb(bus->sdiodev,
|
||||
SDIO_CCCR_IORx, NULL);
|
||||
if (time_after(jiffies, timeout))
|
||||
break;
|
||||
else if (time_after(jiffies, timeout - BRCMF_WAIT_F2RDY + 50))
|
||||
/* prevent busy waiting if it takes too long */
|
||||
msleep_interruptible(20);
|
||||
}
|
||||
|
||||
brcmf_dbg(INFO, "enable 0x%02x, ready 0x%02x\n", enable, ready);
|
||||
brcmf_dbg(INFO, "enable F2: err=%d\n", err);
|
||||
|
||||
/* If F2 successfully enabled, set core and enable interrupts */
|
||||
if (ready == enable) {
|
||||
if (!err) {
|
||||
/* Set up the interrupt mask and enable interrupts */
|
||||
bus->hostintmask = HOSTINTMASK;
|
||||
w_sdreg32(bus, bus->hostintmask,
|
||||
|
@ -3640,8 +3621,7 @@ static int brcmf_sdbrcm_bus_init(struct device *dev)
|
|||
brcmf_sdio_regwb(bus->sdiodev, SBSDIO_WATERMARK, 8, &err);
|
||||
} else {
|
||||
/* Disable F2 again */
|
||||
enable = SDIO_FUNC_ENABLE_1;
|
||||
brcmf_sdio_regwb(bus->sdiodev, SDIO_CCCR_IOEx, enable, NULL);
|
||||
sdio_disable_func(bus->sdiodev->func[SDIO_FUNC_2]);
|
||||
ret = -ENODEV;
|
||||
}
|
||||
|
||||
|
@ -3942,8 +3922,7 @@ static bool brcmf_sdbrcm_probe_init(struct brcmf_sdio *bus)
|
|||
sdio_claim_host(bus->sdiodev->func[1]);
|
||||
|
||||
/* Disable F2 to clear any intermediate frame state on the dongle */
|
||||
brcmf_sdio_regwb(bus->sdiodev, SDIO_CCCR_IOEx,
|
||||
SDIO_FUNC_ENABLE_1, NULL);
|
||||
sdio_disable_func(bus->sdiodev->func[SDIO_FUNC_2]);
|
||||
|
||||
bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
|
||||
bus->rxflow = false;
|
||||
|
|
Loading…
Reference in New Issue