[PATCH] brcmfmac: sdio: Fix OOB interrupt initialization on brcm43362
From: Jean-Philippe Brucker <hidden>
Date: 2019-12-26 09:23:44
Also in:
linux-wireless
Subsystem:
broadcom brcm80211 ieee802.11 wireless drivers, the rest · Maintainers:
Arend van Spriel, Linus Torvalds
Commit 262f2b53f679 ("brcmfmac: call brcmf_attach() just before calling
brcmf_bus_started()") changed the initialization order of the brcmfmac
SDIO driver. Unfortunately since brcmf_sdiod_intr_register() is now
called before the sdiodev->bus_if initialization, it reads the wrong
chip ID and fails to initialize the GPIO on brcm43362. Thus the chip
cannot send interrupts and fails to probe:
[ 12.517023] brcmfmac: brcmf_sdio_bus_rxctl: resumed on timeout
[ 12.531214] ieee80211 phy0: brcmf_bus_started: failed: -110
[ 12.536976] ieee80211 phy0: brcmf_attach: dongle is not responding: err=-110
[ 12.566467] brcmfmac: brcmf_sdio_firmware_callback: brcmf_attach failed
Initialize the bus interface earlier to ensure that
brcmf_sdiod_intr_register() properly sets up the OOB interrupt.
BugLink: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=908438
Fixes: 262f2b53f679 ("brcmfmac: call brcmf_attach() just before calling brcmf_bus_started()")
Signed-off-by: Jean-Philippe Brucker <redacted>
---
A workaround [1] disabling the OOB interrupt is being discussed. It
works for me, but this patch fixes the wifi problem on my cubietruck.
[1] https://lore.kernel.org/linux-arm-kernel/20180930150927.12076-1-hdegoede@redhat.com/ (local)
---
.../net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index 264ad63232f8..058069a03693 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c@@ -4220,38 +4220,38 @@ static void brcmf_sdio_firmware_callback(struct device *dev, int err, brcmf_sdio_sr_init(bus); } else { /* Restore previous clock setting */ brcmf_sdiod_writeb(sdiod, SBSDIO_FUNC1_CHIPCLKCSR, saveclk, &err); } if (err == 0) { + /* Assign bus interface call back */ + sdiod->bus_if->dev = sdiod->dev; + sdiod->bus_if->ops = &brcmf_sdio_bus_ops; + sdiod->bus_if->chip = bus->ci->chip; + sdiod->bus_if->chiprev = bus->ci->chiprev; + /* Allow full data communication using DPC from now on. */ brcmf_sdiod_change_state(bus->sdiodev, BRCMF_SDIOD_DATA); err = brcmf_sdiod_intr_register(sdiod); if (err != 0) brcmf_err("intr register failed:%d\n", err); } /* If we didn't come up, turn off backplane clock */ if (err != 0) { brcmf_sdio_clkctl(bus, CLK_NONE, false); goto checkdied; } sdio_release_host(sdiod->func1); - /* Assign bus interface call back */ - sdiod->bus_if->dev = sdiod->dev; - sdiod->bus_if->ops = &brcmf_sdio_bus_ops; - sdiod->bus_if->chip = bus->ci->chip; - sdiod->bus_if->chiprev = bus->ci->chiprev; - err = brcmf_alloc(sdiod->dev, sdiod->settings); if (err) { brcmf_err("brcmf_alloc failed\n"); goto claim; } /* Attach to the common layer, reserve hdr space */ err = brcmf_attach(sdiod->dev);
--
2.24.0