From patchwork Wed Sep 25 13:44:57 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adrian Ratiu X-Patchwork-Id: 11160709 X-Patchwork-Delegate: kvalo@adurom.com Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E6264924 for ; Wed, 25 Sep 2019 13:45:07 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id CEE8421D7E for ; Wed, 25 Sep 2019 13:45:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2406776AbfIYNo5 (ORCPT ); Wed, 25 Sep 2019 09:44:57 -0400 Received: from bhuna.collabora.co.uk ([46.235.227.227]:57998 "EHLO bhuna.collabora.co.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2406646AbfIYNo5 (ORCPT ); Wed, 25 Sep 2019 09:44:57 -0400 Received: from [127.0.0.1] (localhost [127.0.0.1]) (Authenticated sender: aratiu) with ESMTPSA id 34818280400 From: Adrian Ratiu To: brcm80211-dev-list.pdl@broadcom.com Cc: linux-wireless@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Martyn Welch Subject: [PATCH 1/2] brcmfmac: don't WARN when there are no requests Date: Wed, 25 Sep 2019 16:44:57 +0300 Message-Id: <20190925134458.1413790-1-adrian.ratiu@collabora.com> X-Mailer: git-send-email 2.23.0 MIME-Version: 1.0 Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org 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 Signed-off-by: Adrian Ratiu --- 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) From patchwork Wed Sep 25 13:44:58 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adrian Ratiu X-Patchwork-Id: 11160707 X-Patchwork-Delegate: kvalo@adurom.com Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 47A3C14DB for ; Wed, 25 Sep 2019 13:45:03 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 2F3CC21D7F for ; Wed, 25 Sep 2019 13:45:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2406832AbfIYNo6 (ORCPT ); Wed, 25 Sep 2019 09:44:58 -0400 Received: from bhuna.collabora.co.uk ([46.235.227.227]:58004 "EHLO bhuna.collabora.co.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2406650AbfIYNo5 (ORCPT ); Wed, 25 Sep 2019 09:44:57 -0400 Received: from [127.0.0.1] (localhost [127.0.0.1]) (Authenticated sender: aratiu) with ESMTPSA id 8EFA628BCCF From: Adrian Ratiu To: brcm80211-dev-list.pdl@broadcom.com Cc: linux-wireless@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Gustavo Padovan Subject: [PATCH 2/2] brcmfmac: fix suspend/resume when power is cut off Date: Wed, 25 Sep 2019 16:44:58 +0300 Message-Id: <20190925134458.1413790-2-adrian.ratiu@collabora.com> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20190925134458.1413790-1-adrian.ratiu@collabora.com> References: <20190925134458.1413790-1-adrian.ratiu@collabora.com> MIME-Version: 1.0 Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org 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 Signed-off-by: Adrian Ratiu --- .../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 987731b..dac4685 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c @@ -1136,7 +1136,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; struct brcmf_cfg80211_info *config; int retry = BRCMF_PM_WAIT_MAXRETRY; @@ -1159,19 +1160,33 @@ static int brcmf_ops_sdio_suspend(struct device *dev) sdiodev = bus_if->bus_priv.sdio; - 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; + 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); + + } 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) @@ -1179,13 +1194,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 = {