mirror of
				git://git.openwrt.org/openwrt/openwrt.git
				synced 2025-11-03 22:44:27 -05:00 
			
		
		
		
	
		
			
				
	
	
		
			67 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			67 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
From a32de68edab7b73ded850bcf76cdf6858e92a7e5 Mon Sep 17 00:00:00 2001
 | 
						|
From: Dmitry Osipenko <digetx@gmail.com>
 | 
						|
Date: Sun, 15 Dec 2019 21:42:24 +0300
 | 
						|
Subject: [PATCH] brcmfmac: Keep OOB wake-interrupt disabled when it shouldn't
 | 
						|
 be enabled
 | 
						|
 | 
						|
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>
 | 
						|
---
 | 
						|
 .../net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c  | 10 +++++-----
 | 
						|
 .../net/wireless/broadcom/brcm80211/brcmfmac/sdio.h    |  1 -
 | 
						|
 2 files changed, 5 insertions(+), 6 deletions(-)
 | 
						|
 | 
						|
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
 | 
						|
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
 | 
						|
@@ -120,7 +120,7 @@ int brcmf_sdiod_intr_register(struct brc
 | 
						|
 			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
 | 
						|
 		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
 | 
						|
 		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);
 | 
						|
 	}
 | 
						|
 
 | 
						|
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
 | 
						|
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
 | 
						|
@@ -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;
 |