summaryrefslogtreecommitdiff
path: root/drivers/mmc
diff options
context:
space:
mode:
authorDmitry Shmidt <dimitrysh@google.com>2011-05-03 11:14:53 -0700
committerDan Willemsen <dwillemsen@nvidia.com>2011-11-30 21:37:07 -0800
commitcd8e270e0c1ac97fe7a612007d705e8cbec1bfca (patch)
treeeb1c64a26da9679321a9adfa8bb4b31ed8b8fdb7 /drivers/mmc
parent95d1671b76dbe7d62658e269a4de9f6bdc335724 (diff)
mmc: tegra: Add explicit card-detect processing
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/host/sdhci-tegra.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
index 3692c00a3c08..58be962bcb26 100644
--- a/drivers/mmc/host/sdhci-tegra.c
+++ b/drivers/mmc/host/sdhci-tegra.c
@@ -84,6 +84,36 @@ static unsigned int tegra_sdhci_get_ro(struct sdhci_host *sdhci)
return gpio_get_value(plat->wp_gpio);
}
+static void sdhci_status_notify_cb(int card_present, void *dev_id)
+{
+ struct sdhci_host *sdhci = (struct sdhci_host *)dev_id;
+ struct platform_device *pdev = to_platform_device(mmc_dev(sdhci->mmc));
+ struct tegra_sdhci_platform_data *plat;
+ unsigned int status, oldstat;
+
+ pr_debug("%s: card_present %d\n", mmc_hostname(sdhci->mmc),
+ card_present);
+
+ plat = pdev->dev.platform_data;
+ if (!plat->mmc_data.status) {
+ mmc_detect_change(sdhci->mmc, 0);
+ return;
+ }
+
+ status = plat->mmc_data.status(mmc_dev(sdhci->mmc));
+
+ oldstat = plat->mmc_data.card_present;
+ plat->mmc_data.card_present = status;
+ if (status ^ oldstat) {
+ pr_debug("%s: Slot status change detected (%d -> %d)\n",
+ mmc_hostname(sdhci->mmc), oldstat, status);
+ if (status && !plat->mmc_data.built_in)
+ mmc_detect_change(sdhci->mmc, (5 * HZ) / 2);
+ else
+ mmc_detect_change(sdhci->mmc, 0);
+ }
+}
+
static irqreturn_t carddetect_irq(int irq, void *data)
{
struct sdhci_host *sdhost = (struct sdhci_host *)data;
@@ -153,6 +183,15 @@ static int __devinit sdhci_tegra_probe(struct platform_device *pdev)
goto err_no_plat;
}
+#ifdef CONFIG_MMC_EMBEDDED_SDIO
+ if (plat->mmc_data.embedded_sdio)
+ mmc_set_embedded_sdio_data(host->mmc,
+ &plat->mmc_data.embedded_sdio->cis,
+ &plat->mmc_data.embedded_sdio->cccr,
+ plat->mmc_data.embedded_sdio->funcs,
+ plat->mmc_data.embedded_sdio->num_funcs);
+#endif
+
if (gpio_is_valid(plat->power_gpio)) {
rc = gpio_request(plat->power_gpio, "sdhci_power");
if (rc) {
@@ -183,6 +222,12 @@ static int __devinit sdhci_tegra_probe(struct platform_device *pdev)
goto err_cd_irq_req;
}
+ } else if (plat->mmc_data.register_status_notify) {
+ plat->mmc_data.register_status_notify(sdhci_status_notify_cb, host);
+ }
+
+ if (plat->mmc_data.status) {
+ plat->mmc_data.card_present = plat->mmc_data.status(mmc_dev(host->mmc));
}
if (gpio_is_valid(plat->wp_gpio)) {