aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc/host')
-rw-r--r--drivers/mmc/host/omap_hsmmc.c35
-rw-r--r--drivers/mmc/host/sdhci.c2
2 files changed, 36 insertions, 1 deletions
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 046448d..26bd9e6 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -192,6 +192,30 @@ struct omap_hsmmc_host {
struct omap_mmc_platform_data *pdata;
};
+static void omap_hsmmc_status_notify_cb(int card_present, void *dev_id)
+{
+ struct omap_hsmmc_host *host = (struct omap_hsmmc_host *)dev_id;
+ unsigned int status, oldstat;
+
+ pr_debug("%s: card_present %d\n", mmc_hostname(host->mmc),
+ card_present);
+
+ if (!mmc_slot(host).mmc_data.status) {
+ mmc_detect_change(host->mmc, 0);
+ return;
+ }
+
+ status = mmc_slot(host).mmc_data.status(mmc_dev(host->mmc));
+
+ oldstat = mmc_slot(host).mmc_data.card_present;
+ mmc_slot(host).mmc_data.card_present = status;
+ if (status ^ oldstat) {
+ pr_debug("%s: Slot status change detected (%d -> %d)\n",
+ mmc_hostname(host->mmc), oldstat, status);
+ mmc_detect_change(host->mmc, 0);
+ }
+}
+
static int omap_hsmmc_card_detect(struct device *dev, int slot)
{
struct omap_mmc_platform_data *mmc = dev->platform_data;
@@ -2133,6 +2157,10 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev)
if (mmc_slot(host).nonremovable)
mmc->caps |= MMC_CAP_NONREMOVABLE;
+ mmc->pm_caps = MMC_PM_KEEP_POWER | MMC_PM_IGNORE_PM_NOTIFY;
+ if (mmc_slot(host).mmc_data.built_in)
+ mmc->pm_flags = MMC_PM_KEEP_POWER | MMC_PM_IGNORE_PM_NOTIFY;
+
omap_hsmmc_conf_bus_power(host);
res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx");
@@ -2188,7 +2216,12 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev)
}
pdata->suspend = omap_hsmmc_suspend_cdirq;
pdata->resume = omap_hsmmc_resume_cdirq;
+ } else if (mmc_slot(host).mmc_data.register_status_notify) {
+ mmc_slot(host).mmc_data.register_status_notify(omap_hsmmc_status_notify_cb, host);
}
+ if (mmc_slot(host).mmc_data.status)
+ mmc_slot(host).mmc_data.card_present =
+ mmc_slot(host).mmc_data.status(mmc_dev(host->mmc));
omap_hsmmc_disable_irq(host);
@@ -2309,6 +2342,8 @@ static int omap_hsmmc_suspend(struct device *dev)
}
}
cancel_work_sync(&host->mmc_carddetect_work);
+ if (mmc_slot(host).mmc_data.built_in)
+ host->mmc->pm_flags |= MMC_PM_KEEP_POWER;
ret = mmc_suspend_host(host->mmc);
if (ret == 0) {
mmc_host_enable(host->mmc);
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 6d3de08..32aeb42 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1044,7 +1044,7 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
u16 clk = 0;
unsigned long timeout;
- if (clock == host->clock)
+ if (clock && clock == host->clock)
return;
if (host->ops->set_clock) {