]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
brcmfmac: pcie: Fix crashes due to early IRQs
authorHector Martin <marcan@marcan.st>
Mon, 31 Jan 2022 16:07:10 +0000 (01:07 +0900)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 8 Apr 2022 12:39:58 +0000 (14:39 +0200)
commit b50255c83b914defd61a57fbc81d452334b63f4c upstream.

The driver was enabling IRQs before the message processing was
initialized. This could cause IRQs to come in too early and crash the
driver. Instead, move the IRQ enable and hostready to a bus preinit
function, at which point everything is properly initialized.

Fixes: 9e37f045d5e7 ("brcmfmac: Adding PCIe bus layer support.")
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Reviewed-by: Arend van Spriel <arend.vanspriel@broadcom.com>
Cc: stable@vger.kernel.org
Signed-off-by: Hector Martin <marcan@marcan.st>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20220131160713.245637-7-marcan@marcan.st
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c

index 40a905efda2f42fa48d98930f786d12ed48fcffc..61febc9bfa14ab344329e0255c1480079e2a691b 100644 (file)
@@ -1306,6 +1306,18 @@ static void brcmf_pcie_down(struct device *dev)
 {
 }
 
+static int brcmf_pcie_preinit(struct device *dev)
+{
+       struct brcmf_bus *bus_if = dev_get_drvdata(dev);
+       struct brcmf_pciedev *buspub = bus_if->bus_priv.pcie;
+
+       brcmf_dbg(PCIE, "Enter\n");
+
+       brcmf_pcie_intr_enable(buspub->devinfo);
+       brcmf_pcie_hostready(buspub->devinfo);
+
+       return 0;
+}
 
 static int brcmf_pcie_tx(struct device *dev, struct sk_buff *skb)
 {
@@ -1414,6 +1426,7 @@ static int brcmf_pcie_reset(struct device *dev)
 }
 
 static const struct brcmf_bus_ops brcmf_pcie_bus_ops = {
+       .preinit = brcmf_pcie_preinit,
        .txdata = brcmf_pcie_tx,
        .stop = brcmf_pcie_down,
        .txctl = brcmf_pcie_tx_ctlpkt,
@@ -1786,9 +1799,6 @@ static void brcmf_pcie_setup(struct device *dev, int ret,
 
        init_waitqueue_head(&devinfo->mbdata_resp_wait);
 
-       brcmf_pcie_intr_enable(devinfo);
-       brcmf_pcie_hostready(devinfo);
-
        ret = brcmf_attach(&devinfo->pdev->dev);
        if (ret)
                goto fail;