linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/2] brcmfmac: don't WARN when there are no requests
@ 2019-09-25 13:44 Adrian Ratiu
  2019-09-25 13:44 ` [PATCH 2/2] brcmfmac: fix suspend/resume when power is cut off Adrian Ratiu
  2019-10-01  9:14 ` [PATCH 1/2] brcmfmac: don't WARN when there are no requests Kalle Valo
  0 siblings, 2 replies; 3+ messages in thread
From: Adrian Ratiu @ 2019-09-25 13:44 UTC (permalink / raw)
  To: brcm80211-dev-list.pdl; +Cc: linux-wireless, netdev, linux-kernel, Martyn Welch

When n_reqs == 0 there is nothing to do so it doesn't make sense to
search for requests and issue a warning because none is found.

Signed-off-by: Martyn Welch <martyn.welch@collabora.com>
Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora.com>
---
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c
index 14e530601ef3..fabfbb0b40b0 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c
@@ -57,6 +57,10 @@ static int brcmf_pno_remove_request(struct brcmf_pno_info *pi, u64 reqid)
 
 	mutex_lock(&pi->req_lock);
 
+	/* Nothing to do if we have no requests */
+	if (pi->n_reqs == 0)
+		goto done;
+
 	/* find request */
 	for (i = 0; i < pi->n_reqs; i++) {
 		if (pi->reqs[i]->reqid == reqid)
-- 
2.23.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH 2/2] brcmfmac: fix suspend/resume when power is cut off
  2019-09-25 13:44 [PATCH 1/2] brcmfmac: don't WARN when there are no requests Adrian Ratiu
@ 2019-09-25 13:44 ` Adrian Ratiu
  2019-10-01  9:14 ` [PATCH 1/2] brcmfmac: don't WARN when there are no requests Kalle Valo
  1 sibling, 0 replies; 3+ messages in thread
From: Adrian Ratiu @ 2019-09-25 13:44 UTC (permalink / raw)
  To: brcm80211-dev-list.pdl
  Cc: linux-wireless, netdev, linux-kernel, Gustavo Padovan

brcmfmac assumed the wifi device always remains powered on and thus
hardcoded the MMC_PM_KEEP_POWER flag expecting the wifi device to
remain on even during suspend/resume cycles.

This is not always the case, some appliances cut power to everything
connected via SDIO for efficiency reasons and this leads to wifi not
being usable after coming out of suspend because the device was not
correctly reinitialized.

So we check for the keep_power capability and if it's not present then
we remove the device and probe it again during resume to mirror what's
happening in hardware and ensure correct reinitialization in the case
when MMC_PM_KEEP_POWER is not supported.

Suggested-by: Gustavo Padovan <gustavo.padovan@collabora.com>
Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora.com>
---
 .../broadcom/brcm80211/brcmfmac/bcmsdh.c      | 53 ++++++++++++++-----
 1 file changed, 39 insertions(+), 14 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index fc12598b2dd3..96fd8e2bf773 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -1108,7 +1108,8 @@ static int brcmf_ops_sdio_suspend(struct device *dev)
 	struct sdio_func *func;
 	struct brcmf_bus *bus_if;
 	struct brcmf_sdio_dev *sdiodev;
-	mmc_pm_flag_t sdio_flags;
+	mmc_pm_flag_t pm_caps, sdio_flags;
+	int ret = 0;
 
 	func = container_of(dev, struct sdio_func, dev);
 	brcmf_dbg(SDIO, "Enter: F%d\n", func->num);
@@ -1119,19 +1120,33 @@ static int brcmf_ops_sdio_suspend(struct device *dev)
 	bus_if = dev_get_drvdata(dev);
 	sdiodev = bus_if->bus_priv.sdio;
 
-	brcmf_sdiod_freezer_on(sdiodev);
-	brcmf_sdio_wd_timer(sdiodev->bus, 0);
+	pm_caps = sdio_get_host_pm_caps(func);
+
+	if (pm_caps & MMC_PM_KEEP_POWER) {
+		/* preserve card power during suspend */
+		brcmf_sdiod_freezer_on(sdiodev);
+		brcmf_sdio_wd_timer(sdiodev->bus, 0);
+
+		sdio_flags = MMC_PM_KEEP_POWER;
+		if (sdiodev->wowl_enabled) {
+			if (sdiodev->settings->bus.sdio.oob_irq_supported)
+				enable_irq_wake(sdiodev->settings->bus.sdio.oob_irq_nr);
+			else
+				sdio_flags |= MMC_PM_WAKE_SDIO_IRQ;
+		}
+
+		if (sdio_set_host_pm_flags(sdiodev->func1, sdio_flags))
+			brcmf_err("Failed to set pm_flags %x\n", sdio_flags);
 
-	sdio_flags = MMC_PM_KEEP_POWER;
-	if (sdiodev->wowl_enabled) {
-		if (sdiodev->settings->bus.sdio.oob_irq_supported)
-			enable_irq_wake(sdiodev->settings->bus.sdio.oob_irq_nr);
-		else
-			sdio_flags |= MMC_PM_WAKE_SDIO_IRQ;
+	} else {
+		/* power will be cut so remove device, probe again in resume */
+		brcmf_sdiod_intr_unregister(sdiodev);
+		ret = brcmf_sdiod_remove(sdiodev);
+		if (ret)
+			brcmf_err("Failed to remove device on suspend\n");
 	}
-	if (sdio_set_host_pm_flags(sdiodev->func1, sdio_flags))
-		brcmf_err("Failed to set pm_flags %x\n", sdio_flags);
-	return 0;
+
+	return ret;
 }
 
 static int brcmf_ops_sdio_resume(struct device *dev)
@@ -1139,13 +1154,23 @@ static int brcmf_ops_sdio_resume(struct device *dev)
 	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
 	struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
 	struct sdio_func *func = container_of(dev, struct sdio_func, dev);
+	mmc_pm_flag_t pm_caps = sdio_get_host_pm_caps(func);
+	int ret = 0;
 
 	brcmf_dbg(SDIO, "Enter: F%d\n", func->num);
 	if (func->num != 2)
 		return 0;
 
-	brcmf_sdiod_freezer_off(sdiodev);
-	return 0;
+	if (!(pm_caps & MMC_PM_KEEP_POWER)) {
+		/* bus was powered off and device removed, probe again */
+		ret = brcmf_sdiod_probe(sdiodev);
+		if (ret)
+			brcmf_err("Failed to probe device on resume\n");
+	} else {
+		brcmf_sdiod_freezer_off(sdiodev);
+	}
+
+	return ret;
 }
 
 static const struct dev_pm_ops brcmf_sdio_pm_ops = {
-- 
2.23.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH 1/2] brcmfmac: don't WARN when there are no requests
  2019-09-25 13:44 [PATCH 1/2] brcmfmac: don't WARN when there are no requests Adrian Ratiu
  2019-09-25 13:44 ` [PATCH 2/2] brcmfmac: fix suspend/resume when power is cut off Adrian Ratiu
@ 2019-10-01  9:14 ` Kalle Valo
  1 sibling, 0 replies; 3+ messages in thread
From: Kalle Valo @ 2019-10-01  9:14 UTC (permalink / raw)
  To: Adrian Ratiu
  Cc: brcm80211-dev-list.pdl, linux-wireless, netdev, linux-kernel,
	Martyn Welch

Adrian Ratiu <adrian.ratiu@collabora.com> wrote:

> When n_reqs == 0 there is nothing to do so it doesn't make sense to
> search for requests and issue a warning because none is found.
> 
> Signed-off-by: Martyn Welch <martyn.welch@collabora.com>
> Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora.com>

2 patches applied to wireless-drivers-next.git, thanks.

1524cbf36215 brcmfmac: don't WARN when there are no requests
e0ae4bac22ef brcmfmac: fix suspend/resume when power is cut off

-- 
https://patchwork.kernel.org/patch/11160709/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2019-10-01  9:14 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-09-25 13:44 [PATCH 1/2] brcmfmac: don't WARN when there are no requests Adrian Ratiu
2019-09-25 13:44 ` [PATCH 2/2] brcmfmac: fix suspend/resume when power is cut off Adrian Ratiu
2019-10-01  9:14 ` [PATCH 1/2] brcmfmac: don't WARN when there are no requests Kalle Valo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).