diff options
author | Sahitya Tummala <stummala@codeaurora.org> | 2013-06-20 14:00:18 +0530 |
---|---|---|
committer | Subhash Jadavani <subhashj@codeaurora.org> | 2016-05-27 10:28:43 -0700 |
commit | 7bb14bf282fce0829d110dfc05f215f6ad69b7cd (patch) | |
tree | 1bfd0360fd83ed5de0cafb14233d2d6dd46d4be4 | |
parent | ccbf0292799ead6e17cc175fe40fffecba435a47 (diff) |
mmc: sdhci-msm: Add polling sysfs entry
Add support for polling by providing sysfs entry. It can be
enabled/disabled, by writing 1/0 respectively to the sysfs node -
sys/bus/platform/devices/msm_sdcc.<slotno>/polling. The polling
will be available only if hardware based card detection is not
supported.
Change-Id: Ic58c36665e23cb921d76c482494a168289e83b83
Signed-off-by: Sahitya Tummala <stummala@codeaurora.org>
-rw-r--r-- | drivers/mmc/host/sdhci-msm.c | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c index b0af5d493898..2c71f9cf563b 100644 --- a/drivers/mmc/host/sdhci-msm.c +++ b/drivers/mmc/host/sdhci-msm.c @@ -235,6 +235,7 @@ struct sdhci_msm_host { u32 curr_io_level; struct completion pwr_irq_completion; struct sdhci_msm_bus_vote msm_bus_vote; + struct device_attribute polling; u32 clk_rate; /* Keeps track of current clock rate that is set */ }; @@ -1798,6 +1799,41 @@ static irqreturn_t sdhci_msm_pwr_irq(int irq, void *data) } static ssize_t +show_polling(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct sdhci_host *host = dev_get_drvdata(dev); + int poll; + unsigned long flags; + + spin_lock_irqsave(&host->lock, flags); + poll = !!(host->mmc->caps & MMC_CAP_NEEDS_POLL); + spin_unlock_irqrestore(&host->lock, flags); + + return snprintf(buf, PAGE_SIZE, "%d\n", poll); +} + +static ssize_t +store_polling(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct sdhci_host *host = dev_get_drvdata(dev); + int value; + unsigned long flags; + + if (!kstrtou32(buf, 0, &value)) { + spin_lock_irqsave(&host->lock, flags); + if (value) { + host->mmc->caps |= MMC_CAP_NEEDS_POLL; + mmc_detect_change(host->mmc, 0); + } else { + host->mmc->caps &= ~MMC_CAP_NEEDS_POLL; + } + spin_unlock_irqrestore(&host->lock, flags); + } + return count; +} + +static ssize_t show_sdhci_max_bus_bw(struct device *dev, struct device_attribute *attr, char *buf) { @@ -2357,9 +2393,21 @@ static int sdhci_msm_probe(struct platform_device *pdev) if (ret) goto remove_host; + if (!gpio_is_valid(msm_host->pdata->status_gpio)) { + msm_host->polling.show = show_polling; + msm_host->polling.store = store_polling; + sysfs_attr_init(&msm_host->polling.attr); + msm_host->polling.attr.name = "polling"; + msm_host->polling.attr.mode = S_IRUGO | S_IWUSR; + ret = device_create_file(&pdev->dev, &msm_host->polling); + if (ret) + goto remove_max_bus_bw_file; + } /* Successful initialization */ goto out; +remove_max_bus_bw_file: + device_remove_file(&pdev->dev, &msm_host->msm_bus_vote.max_bus_bw); remove_host: dead = (readl_relaxed(host->ioaddr + SDHCI_INT_STATUS) == 0xffffffff); sdhci_remove_host(host, dead); @@ -2398,6 +2446,8 @@ static int sdhci_msm_remove(struct platform_device *pdev) 0xffffffff); pr_debug("%s: %s\n", dev_name(&pdev->dev), __func__); + if (!gpio_is_valid(msm_host->pdata->status_gpio)) + device_remove_file(&pdev->dev, &msm_host->polling); device_remove_file(&pdev->dev, &msm_host->msm_bus_vote.max_bus_bw); sdhci_remove_host(host, dead); sdhci_pltfm_free(pdev); |