From 716bf64c825fba7d1b941d2f2b46ba3f78e762e0 Mon Sep 17 00:00:00 2001
From: Jianzheng Zhou <B38613@freescale.com>
Date: Wed, 27 Jun 2012 12:15:04 +0800
Subject: [PATCH 2/2] ENGR00214870-2:export sdio force detect or remove feature for some special case
For dongle sdio wifi modules,power and clock will still on althrough rmmod wifi
drivers. Add force detect or remove feature, wifi driver can control their own
power and clock when enable/disable wifi.
Signed-off-by: Jianzheng Zhou <B38613@freescale.com>
---
drivers/mmc/host/sdhci-esdhc-imx.c | 2 ++
drivers/mmc/host/sdhci-pltfm.c | 23 +++++++++++++++++++++++
drivers/mmc/host/sdhci.c | 1 +
include/linux/mmc/sdio_func.h | 1 +
4 files changed, 27 insertions(+), 0 deletions(-)
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 1a81571..a438242 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -674,6 +674,8 @@ static irqreturn_t cd_irq(int irq, void *data)
esdhc_reset(sdhost);
mdelay(1);
+ if (sdhost->mmc->sdio_force_remove)
+ sdhost->mmc->sdio_force_remove = false;
tasklet_schedule(&sdhost->card_tasklet);
return IRQ_HANDLED;
};
diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c
index dbab040..18b1944 100644
--- a/drivers/mmc/host/sdhci-pltfm.c
+++ b/drivers/mmc/host/sdhci-pltfm.c
@@ -41,10 +41,30 @@
* *
\*****************************************************************************/
+struct sdhci_host *__host;
static struct sdhci_ops sdhci_pltfm_ops = {
};
/*****************************************************************************\
+* *
+* Force detect with force remove sysmbol *
+* remove = false: force detect *
+* remove = true : force remove *
+* *
+******************************************************************************/
+
+void mmc_force_remove_sdio_detect(bool remove)
+{
+ struct mmc_host *host;
+ if (__host != NULL) {
+ host = __host->mmc;
+ host->sdio_force_remove = remove;
+ tasklet_schedule(&__host->card_tasklet);
+ }
+}
+EXPORT_SYMBOL_GPL(mmc_force_remove_sdio_detect);
+
+/*****************************************************************************\
* *
* Device probing/removal *
* *
@@ -80,6 +100,8 @@ static int __devinit sdhci_pltfm_probe(struct platform_device *pdev)
else
host = sdhci_alloc_host(&pdev->dev, sizeof(*pltfm_host));
+ __host = host;
+
if (IS_ERR(host)) {
ret = PTR_ERR(host);
goto err;
@@ -157,6 +179,7 @@ static int __devexit sdhci_pltfm_remove(struct platform_device *pdev)
iounmap(host->ioaddr);
release_mem_region(iomem->start, resource_size(iomem));
sdhci_free_host(host);
+ __host = NULL;
platform_set_drvdata(pdev, NULL);
return 0;
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 2f200b8..265c544 100755
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1556,6 +1556,7 @@ out:
mmiowb();
spin_unlock_irqrestore(&host->lock, flags);
+ sdhci_disable_clk(host, 0);
}
static int sdhci_start_signal_voltage_switch(struct mmc_host *mmc,
diff --git a/include/linux/mmc/sdio_func.h b/include/linux/mmc/sdio_func.h
index 557acae..d021702 100755
--- a/include/linux/mmc/sdio_func.h
+++ b/include/linux/mmc/sdio_func.h
@@ -170,6 +170,7 @@ extern void sdio_f0_writeb(struct sdio_func *func, unsigned char b,
extern mmc_pm_flag_t sdio_get_host_pm_caps(struct sdio_func *func);
extern int sdio_set_host_pm_flags(struct sdio_func *func, mmc_pm_flag_t flags);
+extern void mmc_force_remove_sdio_detect(bool remove);
#endif
--
1.7.1