summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorDong Aisheng <aisheng.dong@nxp.com>2016-01-29 21:34:45 +0800
committerDong Aisheng <aisheng.dong@nxp.com>2016-02-16 15:49:15 +0800
commit66b534082968214707d54d96ba142bc528a6e1de (patch)
treeaacc85aea20e2a92a8d2a9a89352b7c9bd117978 /drivers
parent250899a9ca2fdb31fc8d9d5405ac7b1c86beef44 (diff)
MLK-12360-3 bcmdhd: fix bcmdhd blocks system suspend issue
When enable WIFi and connected with AP, the system is unable to suspend. root@imx6qdlsolo:~# echo standby > /sys/power/state PM: Syncing filesystems ... done. Freezing user space processes ... (elapsed 0.001 seconds) done. Freezing remaining freezable tasks ... (elapsed 0.001 seconds) done. dhdsdio_isr: Enter dhdsdio_isr: Enter dhdsdio_isr: disable SDIO interrupts Calling dhdsdio_dpc() from dhdsdio_isr dhdsdio_dpc: Enter dhdsdio_bussleep: request WAKE (currently SLEEP) (Keypress still response here.... ) It's caused by Broadcom WiFi driver will keep handling SDIO irq even after the driver is already suspended. This weird behavior will block the MMC host suspend during its irq synchronize operation in free_irq(), then the system suspend is blocked too and hanged. Add SDHCI_QUIRK2_SDIO_IRQ_THREAD for BCM WiFi to use kernel thread to process sdio interrupts which won't block system suspend and process freeze operation. Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mmc/host/sdhci-esdhc-imx.c1
-rw-r--r--drivers/mmc/host/sdhci.c3
-rw-r--r--drivers/mmc/host/sdhci.h3
3 files changed, 6 insertions, 1 deletions
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index f64a591f2b42..03c3d9a02161 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -1046,6 +1046,7 @@ sdhci_esdhc_imx_probe_dt(struct platform_device *pdev,
if (of_get_property(np, "wifi-host", NULL)) {
wifi_mmc_host = host->mmc;
+ host->quirks2 |= SDHCI_QUIRK2_SDIO_IRQ_THREAD;
dev_info(mmc_dev(host->mmc), "assigned as wifi host\n");
}
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index c638b91a7a88..35cb4535a150 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -3116,7 +3116,8 @@ int sdhci_add_host(struct sdhci_host *host)
host->timeout_clk = override_timeout_clk;
mmc->caps |= MMC_CAP_SDIO_IRQ | MMC_CAP_ERASE | MMC_CAP_CMD23;
- mmc->caps2 |= MMC_CAP2_SDIO_IRQ_NOTHREAD;
+ if (!(host->quirks2 & SDHCI_QUIRK2_SDIO_IRQ_THREAD))
+ mmc->caps2 |= MMC_CAP2_SDIO_IRQ_NOTHREAD;
if (host->quirks & SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12)
host->flags |= SDHCI_AUTO_CMD12;
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 7c02ff46c8ac..e934a599340c 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -412,6 +412,9 @@ struct sdhci_host {
#define SDHCI_QUIRK2_ACMD23_BROKEN (1<<14)
/* Broken Clock divider zero in controller */
#define SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN (1<<15)
+/* Host or Card can't support no thread sdio irq */
+#define SDHCI_QUIRK2_SDIO_IRQ_THREAD (1<<16)
+
int irq; /* Device IRQ */
void __iomem *ioaddr; /* Mapped address */