Skip to content

Commit 92caded

Browse files
storulfKalle Valo
authored andcommitted
brcmfmac: Avoid keeping power to SDIO card unless WOWL is used
Keeping the power to the SDIO card during system wide suspend, consumes energy. Especially on battery driven embedded systems, this can be a problem. Therefore, let's change the behaviour into allowing the SDIO card to be powered off, unless WOWL is supported and enabled. Note that, the downside from this change, is that during system resume the SDIO card needs to be re-initialized and the FW must be re-programmed. Even if this may take some time to complete, it should we worth it, rather than draining the battery. Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> Tested-by: Christophe Roullier <christophe.roullier@foss.st.com> Reviewed-by: Yann Gautier <yann.gautier@foss.st.com> Signed-off-by: Kalle Valo <kvalo@kernel.org> Link: https://lore.kernel.org/r/20220323083950.414783-1-ulf.hansson@linaro.org
1 parent 3e12968 commit 92caded

File tree

1 file changed

+22
-17
lines changed
  • drivers/net/wireless/broadcom/brcm80211/brcmfmac

1 file changed

+22
-17
lines changed

drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1119,9 +1119,21 @@ void brcmf_sdio_wowl_config(struct device *dev, bool enabled)
11191119
{
11201120
struct brcmf_bus *bus_if = dev_get_drvdata(dev);
11211121
struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
1122+
mmc_pm_flag_t pm_caps = sdio_get_host_pm_caps(sdiodev->func1);
11221123

1123-
brcmf_dbg(SDIO, "Configuring WOWL, enabled=%d\n", enabled);
1124-
sdiodev->wowl_enabled = enabled;
1124+
/* Power must be preserved to be able to support WOWL. */
1125+
if (!(pm_caps & MMC_PM_KEEP_POWER))
1126+
goto notsup;
1127+
1128+
if (sdiodev->settings->bus.sdio.oob_irq_supported ||
1129+
pm_caps & MMC_PM_WAKE_SDIO_IRQ) {
1130+
sdiodev->wowl_enabled = enabled;
1131+
brcmf_dbg(SDIO, "Configuring WOWL, enabled=%d\n", enabled);
1132+
return;
1133+
}
1134+
1135+
notsup:
1136+
brcmf_dbg(SDIO, "WOWL not supported\n");
11251137
}
11261138

11271139
#ifdef CONFIG_PM_SLEEP
@@ -1130,7 +1142,7 @@ static int brcmf_ops_sdio_suspend(struct device *dev)
11301142
struct sdio_func *func;
11311143
struct brcmf_bus *bus_if;
11321144
struct brcmf_sdio_dev *sdiodev;
1133-
mmc_pm_flag_t pm_caps, sdio_flags;
1145+
mmc_pm_flag_t sdio_flags;
11341146
int ret = 0;
11351147

11361148
func = container_of(dev, struct sdio_func, dev);
@@ -1142,20 +1154,15 @@ static int brcmf_ops_sdio_suspend(struct device *dev)
11421154
bus_if = dev_get_drvdata(dev);
11431155
sdiodev = bus_if->bus_priv.sdio;
11441156

1145-
pm_caps = sdio_get_host_pm_caps(func);
1146-
1147-
if (pm_caps & MMC_PM_KEEP_POWER) {
1148-
/* preserve card power during suspend */
1157+
if (sdiodev->wowl_enabled) {
11491158
brcmf_sdiod_freezer_on(sdiodev);
11501159
brcmf_sdio_wd_timer(sdiodev->bus, 0);
11511160

11521161
sdio_flags = MMC_PM_KEEP_POWER;
1153-
if (sdiodev->wowl_enabled) {
1154-
if (sdiodev->settings->bus.sdio.oob_irq_supported)
1155-
enable_irq_wake(sdiodev->settings->bus.sdio.oob_irq_nr);
1156-
else
1157-
sdio_flags |= MMC_PM_WAKE_SDIO_IRQ;
1158-
}
1162+
if (sdiodev->settings->bus.sdio.oob_irq_supported)
1163+
enable_irq_wake(sdiodev->settings->bus.sdio.oob_irq_nr);
1164+
else
1165+
sdio_flags |= MMC_PM_WAKE_SDIO_IRQ;
11591166

11601167
if (sdio_set_host_pm_flags(sdiodev->func1, sdio_flags))
11611168
brcmf_err("Failed to set pm_flags %x\n", sdio_flags);
@@ -1176,21 +1183,19 @@ static int brcmf_ops_sdio_resume(struct device *dev)
11761183
struct brcmf_bus *bus_if = dev_get_drvdata(dev);
11771184
struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
11781185
struct sdio_func *func = container_of(dev, struct sdio_func, dev);
1179-
mmc_pm_flag_t pm_caps = sdio_get_host_pm_caps(func);
11801186
int ret = 0;
11811187

11821188
brcmf_dbg(SDIO, "Enter: F%d\n", func->num);
11831189
if (func->num != 2)
11841190
return 0;
11851191

1186-
if (!(pm_caps & MMC_PM_KEEP_POWER)) {
1192+
if (!sdiodev->wowl_enabled) {
11871193
/* bus was powered off and device removed, probe again */
11881194
ret = brcmf_sdiod_probe(sdiodev);
11891195
if (ret)
11901196
brcmf_err("Failed to probe device on resume\n");
11911197
} else {
1192-
if (sdiodev->wowl_enabled &&
1193-
sdiodev->settings->bus.sdio.oob_irq_supported)
1198+
if (sdiodev->settings->bus.sdio.oob_irq_supported)
11941199
disable_irq_wake(sdiodev->settings->bus.sdio.oob_irq_nr);
11951200

11961201
brcmf_sdiod_freezer_off(sdiodev);

0 commit comments

Comments
 (0)