summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSahitya Tummala <stummala@codeaurora.org>2013-03-12 14:57:46 +0530
committerSubhash Jadavani <subhashj@codeaurora.org>2016-05-27 10:28:29 -0700
commitcff2042613214c2406de6ff81a6d937991e6f4fc (patch)
treeb1679c81052b2242beb7e8db0912b4e03c3d4999
parentca2adf7a7601c23b1922e6ec055ba01ba3d4b963 (diff)
mmc: sdhci-msm: Add support for hardware based card detection
Add support for hardware based card detection for external SD card slot. Change-Id: I3e081f2eff54d6932a89f826cc85c201c52ca840 Signed-off-by: Sahitya Tummala <stummala@codeaurora.org> [venkatg@codeaurora.org: Fix arguments for mmc_gpio_request_cd as the signature had changed in 3.14 kernel] Signed-off-by: Venkat Gopalakrishnan <venkatg@codeaurora.org>
-rw-r--r--drivers/mmc/host/sdhci-msm.c23
1 files changed, 22 insertions, 1 deletions
diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
index ccddf5560795..feddbaf8f370 100644
--- a/drivers/mmc/host/sdhci-msm.c
+++ b/drivers/mmc/host/sdhci-msm.c
@@ -32,6 +32,7 @@
#include <linux/scatterlist.h>
#include <linux/slab.h>
#include <linux/mmc/mmc.h>
+#include <linux/mmc/slot-gpio.h>
#include <mach/gpio.h>
#include <mach/msm_bus.h>
@@ -200,6 +201,7 @@ struct sdhci_msm_pltfm_data {
bool nonremovable;
struct sdhci_msm_pin_data *pin_data;
u32 cpu_dma_latency_us;
+ int status_gpio; /* card detection GPIO that is configured as IRQ */
struct sdhci_msm_bus_voting_data *voting_data;
};
@@ -1075,6 +1077,8 @@ static struct sdhci_msm_pltfm_data *sdhci_msm_populate_pdata(struct device *dev)
goto out;
}
+ pdata->status_gpio = of_get_named_gpio_flags(np, "cd-gpios", 0, 0);
+
of_property_read_u32(np, "qcom,bus-width", &bus_width);
if (bus_width == 8)
pdata->mmc_bus_width = MMC_CAP_8_BIT_DATA;
@@ -2021,10 +2025,20 @@ static int sdhci_msm_probe(struct platform_device *pdev)
INIT_DELAYED_WORK(&msm_host->msm_bus_vote.vote_work,
sdhci_msm_bus_work);
+ if (gpio_is_valid(msm_host->pdata->status_gpio)) {
+ ret = mmc_gpio_request_cd(msm_host->mmc,
+ msm_host->pdata->status_gpio, 0);
+ if (ret) {
+ dev_err(&pdev->dev, "%s: Failed to request card detection IRQ %d\n",
+ __func__, ret);
+ goto bus_unregister;
+ }
+ }
+
ret = sdhci_add_host(host);
if (ret) {
dev_err(&pdev->dev, "Add host failed (%d)\n", ret);
- goto bus_unregister;
+ goto free_cd_gpio;
}
/* Set core clk rate, optionally override from dts */
@@ -2052,6 +2066,9 @@ static int sdhci_msm_probe(struct platform_device *pdev)
remove_host:
dead = (readl_relaxed(host->ioaddr + SDHCI_INT_STATUS) == 0xffffffff);
sdhci_remove_host(host, dead);
+free_cd_gpio:
+ if (gpio_is_valid(msm_host->pdata->status_gpio))
+ mmc_gpio_free_cd(msm_host->mmc);
bus_unregister:
sdhci_msm_bus_unregister(msm_host);
vreg_deinit:
@@ -2085,6 +2102,10 @@ static int sdhci_msm_remove(struct platform_device *pdev)
device_remove_file(&pdev->dev, &msm_host->msm_bus_vote.max_bus_bw);
sdhci_remove_host(host, dead);
sdhci_pltfm_free(pdev);
+
+ if (gpio_is_valid(msm_host->pdata->status_gpio))
+ mmc_gpio_free_cd(msm_host->mmc);
+
sdhci_msm_vreg_init(&pdev->dev, msm_host->pdata, false);
if (pdata->pin_data)