]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
brcmfmac: Keep OOB wake-interrupt disabled when it shouldn't be enabled
authorDmitry Osipenko <digetx@gmail.com>
Sun, 15 Dec 2019 18:42:24 +0000 (21:42 +0300)
committerKalle Valo <kvalo@codeaurora.org>
Wed, 18 Dec 2019 19:09:02 +0000 (21:09 +0200)
NVIDIA Tegra SoCs do not like when OOB wake is enabled and WiFi interface
is in DOWN state during suspend. This results in a CPU hang on programming
OOB wake-up state of the GPIO controller during of system's suspend.

The solution is trivial: don't enable wake for the OOB interrupt when it
should be disabled.

This fixes hang on Tegra20 (Acer A500) and Tegra30 (Nexus 7) devices which
are using BCM4329 and BCM4330 WiFi chips respectively.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h

index f4c53ab46058bae47ac7c939411a98c1e757719f..b684a5b6d90449e38490519def42c0e9dcd7b71c 100644 (file)
@@ -120,7 +120,7 @@ int brcmf_sdiod_intr_register(struct brcmf_sdio_dev *sdiodev)
                        brcmf_err("enable_irq_wake failed %d\n", ret);
                        return ret;
                }
-               sdiodev->irq_wake = true;
+               disable_irq_wake(pdata->oob_irq_nr);
 
                sdio_claim_host(sdiodev->func1);
 
@@ -179,10 +179,6 @@ void brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev *sdiodev)
                sdio_release_host(sdiodev->func1);
 
                sdiodev->oob_irq_requested = false;
-               if (sdiodev->irq_wake) {
-                       disable_irq_wake(pdata->oob_irq_nr);
-                       sdiodev->irq_wake = false;
-               }
                free_irq(pdata->oob_irq_nr, &sdiodev->func1->dev);
                sdiodev->irq_en = false;
                sdiodev->oob_irq_requested = false;
@@ -1173,6 +1169,10 @@ static int brcmf_ops_sdio_resume(struct device *dev)
                if (ret)
                        brcmf_err("Failed to probe device on resume\n");
        } else {
+               if (sdiodev->wowl_enabled &&
+                   sdiodev->settings->bus.sdio.oob_irq_supported)
+                       disable_irq_wake(sdiodev->settings->bus.sdio.oob_irq_nr);
+
                brcmf_sdiod_freezer_off(sdiodev);
        }
 
index 0bd47c119dae0a674ff249474044e8ba6d33c150..163fd664780a03c43efac5883294484958816589 100644 (file)
@@ -178,7 +178,6 @@ struct brcmf_sdio_dev {
        bool sd_irq_requested;
        bool irq_en;                    /* irq enable flags */
        spinlock_t irq_en_lock;
-       bool irq_wake;                  /* irq wake enable flags */
        bool sg_support;
        uint max_request_size;
        ushort max_segment_count;