From cff2042613214c2406de6ff81a6d937991e6f4fc Mon Sep 17 00:00:00 2001 From: Sahitya Tummala Date: Tue, 12 Mar 2013 14:57:46 +0530 Subject: 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 [venkatg@codeaurora.org: Fix arguments for mmc_gpio_request_cd as the signature had changed in 3.14 kernel] Signed-off-by: Venkat Gopalakrishnan --- drivers/mmc/host/sdhci-msm.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) 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 #include #include +#include #include #include @@ -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) -- cgit v1.2.3