Commit 71370eb8 authored by Arend van Spriel's avatar Arend van Spriel Committed by John W. Linville
Browse files

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: default avatarFranky Lin <frankyl@broadcom.com>
Reviewed-by: default avatarHante Meuleman <meuleman@broadcom.com>
Reviewed-by: default avatarPieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: default avatarArend van Spriel <arend@broadcom.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 463c30b3
Loading
Loading
Loading
Loading
+8 −21
Original line number Diff line number Diff line
@@ -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,26 +208,7 @@ 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) ||
	if ((regaddr == SDIO_CCCR_ABORT) ||
	    (regaddr == SDIO_CCCR_IENx)) {
		sdfunc = kmemdup(sdiodev->func[0], sizeof(struct sdio_func),
				 GFP_KERNEL);
@@ -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) {
+6 −27
Original line number Diff line number Diff line
@@ -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);

	brcmf_sdio_regwb(bus->sdiodev, SDIO_CCCR_IOEx, enable, NULL);
	err = sdio_enable_func(bus->sdiodev->func[SDIO_FUNC_2]);

	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;