ac5584ec3cc869bd96251ef85192e3a962111c51
[openwrt/svn-archive/archive.git] / package / kernel / mac80211 / patches / 360-brcmfmac-fix-sdio-suspend-and-resume.patch
1 From: Arend van Spriel <arend@broadcom.com>
2 Date: Tue, 14 Apr 2015 20:10:30 +0200
3 Subject: [PATCH] brcmfmac: fix sdio suspend and resume
4
5 commit 330b4e4be937 ("brcmfmac: Add wowl support for SDIO devices.")
6 changed the behaviour by removing the MMC_PM_KEEP_POWER flag for
7 non-wowl scenario, which needs to be restored. Another necessary
8 change is to mark the card as being non-removable. With this in place
9 the suspend resume test passes successfully doing:
10
11 # echo devices > /sys/power/pm_test
12 # echo mem > /sys/power/state
13
14 Note that power may still be switched off when system is going
15 in S3 state.
16
17 Reported-by: Fu, Zhonghui <<zhonghui.fu@linux.intel.com>
18 Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
19 Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
20 Signed-off-by: Arend van Spriel <arend@broadcom.com>
21 ---
22
23 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
24 +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
25 @@ -1011,6 +1011,14 @@ static int brcmf_sdiod_remove(struct brc
26 return 0;
27 }
28
29 +static void brcmf_sdiod_host_fixup(struct mmc_host *host)
30 +{
31 + /* runtime-pm powers off the device */
32 + pm_runtime_forbid(host->parent);
33 + /* avoid removal detection upon resume */
34 + host->caps |= MMC_CAP_NONREMOVABLE;
35 +}
36 +
37 static int brcmf_sdiod_probe(struct brcmf_sdio_dev *sdiodev)
38 {
39 struct sdio_func *func;
40 @@ -1076,7 +1084,7 @@ static int brcmf_sdiod_probe(struct brcm
41 ret = -ENODEV;
42 goto out;
43 }
44 - pm_runtime_forbid(host->parent);
45 + brcmf_sdiod_host_fixup(host);
46 out:
47 if (ret)
48 brcmf_sdiod_remove(sdiodev);
49 @@ -1246,15 +1254,15 @@ static int brcmf_ops_sdio_suspend(struct
50 brcmf_sdiod_freezer_on(sdiodev);
51 brcmf_sdio_wd_timer(sdiodev->bus, 0);
52
53 + sdio_flags = MMC_PM_KEEP_POWER;
54 if (sdiodev->wowl_enabled) {
55 - sdio_flags = MMC_PM_KEEP_POWER;
56 if (sdiodev->pdata->oob_irq_supported)
57 enable_irq_wake(sdiodev->pdata->oob_irq_nr);
58 else
59 - sdio_flags = MMC_PM_WAKE_SDIO_IRQ;
60 - if (sdio_set_host_pm_flags(sdiodev->func[1], sdio_flags))
61 - brcmf_err("Failed to set pm_flags %x\n", sdio_flags);
62 + sdio_flags |= MMC_PM_WAKE_SDIO_IRQ;
63 }
64 + if (sdio_set_host_pm_flags(sdiodev->func[1], sdio_flags))
65 + brcmf_err("Failed to set pm_flags %x\n", sdio_flags);
66 return 0;
67 }
68