diff options
Diffstat (limited to 'package/kernel/mac80211/patches/360-brcmfmac-fix-sdio-suspend-and-resume.patch')
-rw-r--r-- | package/kernel/mac80211/patches/360-brcmfmac-fix-sdio-suspend-and-resume.patch | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/package/kernel/mac80211/patches/360-brcmfmac-fix-sdio-suspend-and-resume.patch b/package/kernel/mac80211/patches/360-brcmfmac-fix-sdio-suspend-and-resume.patch new file mode 100644 index 0000000000..ac5584ec3c --- /dev/null +++ b/package/kernel/mac80211/patches/360-brcmfmac-fix-sdio-suspend-and-resume.patch @@ -0,0 +1,68 @@ +From: Arend van Spriel <arend@broadcom.com> +Date: Tue, 14 Apr 2015 20:10:30 +0200 +Subject: [PATCH] brcmfmac: fix sdio suspend and resume + +commit 330b4e4be937 ("brcmfmac: Add wowl support for SDIO devices.") +changed the behaviour by removing the MMC_PM_KEEP_POWER flag for +non-wowl scenario, which needs to be restored. Another necessary +change is to mark the card as being non-removable. With this in place +the suspend resume test passes successfully doing: + + # echo devices > /sys/power/pm_test + # echo mem > /sys/power/state + +Note that power may still be switched off when system is going +in S3 state. + +Reported-by: Fu, Zhonghui <<zhonghui.fu@linux.intel.com> +Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com> +Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com> +Signed-off-by: Arend van Spriel <arend@broadcom.com> +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +@@ -1011,6 +1011,14 @@ static int brcmf_sdiod_remove(struct brc + return 0; + } + ++static void brcmf_sdiod_host_fixup(struct mmc_host *host) ++{ ++ /* runtime-pm powers off the device */ ++ pm_runtime_forbid(host->parent); ++ /* avoid removal detection upon resume */ ++ host->caps |= MMC_CAP_NONREMOVABLE; ++} ++ + static int brcmf_sdiod_probe(struct brcmf_sdio_dev *sdiodev) + { + struct sdio_func *func; +@@ -1076,7 +1084,7 @@ static int brcmf_sdiod_probe(struct brcm + ret = -ENODEV; + goto out; + } +- pm_runtime_forbid(host->parent); ++ brcmf_sdiod_host_fixup(host); + out: + if (ret) + brcmf_sdiod_remove(sdiodev); +@@ -1246,15 +1254,15 @@ static int brcmf_ops_sdio_suspend(struct + brcmf_sdiod_freezer_on(sdiodev); + brcmf_sdio_wd_timer(sdiodev->bus, 0); + ++ sdio_flags = MMC_PM_KEEP_POWER; + if (sdiodev->wowl_enabled) { +- sdio_flags = MMC_PM_KEEP_POWER; + if (sdiodev->pdata->oob_irq_supported) + enable_irq_wake(sdiodev->pdata->oob_irq_nr); + else +- sdio_flags = MMC_PM_WAKE_SDIO_IRQ; +- if (sdio_set_host_pm_flags(sdiodev->func[1], sdio_flags)) +- brcmf_err("Failed to set pm_flags %x\n", sdio_flags); ++ sdio_flags |= MMC_PM_WAKE_SDIO_IRQ; + } ++ if (sdio_set_host_pm_flags(sdiodev->func[1], sdio_flags)) ++ brcmf_err("Failed to set pm_flags %x\n", sdio_flags); + return 0; + } + |