wifi: brcmfmac: keep power during suspend if board requires it
[ Upstream commit 8c3170628a9ce24a59647bd24f897e666af919b8 ]
After commit 92cadedd9d
("brcmfmac: Avoid keeping power to SDIO card
unless WOWL is used"), the wifi adapter by default is turned off on
suspend and then re-probed on resume.
This conflicts with some embedded boards that require to remain powered.
They will fail on resume with:
brcmfmac: brcmf_sdio_bus_rxctl: resumed on timeout
ieee80211 phy1: brcmf_bus_started: failed: -110
ieee80211 phy1: brcmf_attach: dongle is not responding: err=-110
brcmfmac: brcmf_sdio_firmware_callback: brcmf_attach failed
This commit checks for the Device Tree property 'cap-power-off-cards'.
If this property is not set, it means that we do not have the capability
to power off and should therefore remain powered.
Signed-off-by: Matthias Proske <email@matthias-proske.de>
Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
Link: https://patch.msgid.link/20250212185941.146958-2-email@matthias-proske.de
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
ff0c8508eb
commit
499d26188a
@ -1151,6 +1151,7 @@ static int brcmf_ops_sdio_suspend(struct device *dev)
|
||||
struct brcmf_bus *bus_if;
|
||||
struct brcmf_sdio_dev *sdiodev;
|
||||
mmc_pm_flag_t sdio_flags;
|
||||
bool cap_power_off;
|
||||
int ret = 0;
|
||||
|
||||
func = container_of(dev, struct sdio_func, dev);
|
||||
@ -1158,19 +1159,23 @@ static int brcmf_ops_sdio_suspend(struct device *dev)
|
||||
if (func->num != 1)
|
||||
return 0;
|
||||
|
||||
cap_power_off = !!(func->card->host->caps & MMC_CAP_POWER_OFF_CARD);
|
||||
|
||||
bus_if = dev_get_drvdata(dev);
|
||||
sdiodev = bus_if->bus_priv.sdio;
|
||||
|
||||
if (sdiodev->wowl_enabled) {
|
||||
if (sdiodev->wowl_enabled || !cap_power_off) {
|
||||
brcmf_sdiod_freezer_on(sdiodev);
|
||||
brcmf_sdio_wd_timer(sdiodev->bus, 0);
|
||||
|
||||
sdio_flags = MMC_PM_KEEP_POWER;
|
||||
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 (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);
|
||||
@ -1192,18 +1197,19 @@ static int brcmf_ops_sdio_resume(struct device *dev)
|
||||
struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
|
||||
struct sdio_func *func = container_of(dev, struct sdio_func, dev);
|
||||
int ret = 0;
|
||||
bool cap_power_off = !!(func->card->host->caps & MMC_CAP_POWER_OFF_CARD);
|
||||
|
||||
brcmf_dbg(SDIO, "Enter: F%d\n", func->num);
|
||||
if (func->num != 2)
|
||||
return 0;
|
||||
|
||||
if (!sdiodev->wowl_enabled) {
|
||||
if (!sdiodev->wowl_enabled && cap_power_off) {
|
||||
/* 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 {
|
||||
if (sdiodev->settings->bus.sdio.oob_irq_supported)
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user