diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index f9f22a2fe0dd..436cf467ff9d 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -156,6 +156,33 @@ static void sdhci_dumpregs(struct sdhci_host *host) pr_info(DRIVER_NAME ": ===========================================\n"); } +#define MAX_PM_QOS_TIMEOUT_VALUE 100000 /* 100 ms */ +static ssize_t +show_sdhci_pm_qos_tout(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct sdhci_host *host = dev_get_drvdata(dev); + + return snprintf(buf, PAGE_SIZE, "%d us\n", host->pm_qos_timeout_us); +} + +static ssize_t +store_sdhci_pm_qos_tout(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct sdhci_host *host = dev_get_drvdata(dev); + uint32_t value; + unsigned long flags; + + if (!kstrtou32(buf, 0, &value)) { + spin_lock_irqsave(&host->lock, flags); + if (value <= MAX_PM_QOS_TIMEOUT_VALUE) + host->pm_qos_timeout_us = value; + spin_unlock_irqrestore(&host->lock, flags); + } + return count; +} + /*****************************************************************************\ * * * Low level functions * @@ -3633,7 +3660,18 @@ int sdhci_add_host(struct sdhci_host *host) host->pm_qos_timeout_us = 10000; /* default value */ pm_qos_add_request(&host->pm_qos_req_dma, PM_QOS_CPU_DMA_LATENCY, PM_QOS_DEFAULT_VALUE); + + host->pm_qos_tout.show = show_sdhci_pm_qos_tout; + host->pm_qos_tout.store = store_sdhci_pm_qos_tout; + sysfs_attr_init(&host->pm_qos_tout.attr); + host->pm_qos_tout.attr.name = "pm_qos_unvote_delay"; + host->pm_qos_tout.attr.mode = S_IRUGO | S_IWUSR; + ret = device_create_file(mmc_dev(mmc), &host->pm_qos_tout); + if (ret) + pr_err("%s: cannot create pm_qos_unvote_delay %d\n", + mmc_hostname(mmc), ret); } + mmc_add_host(mmc); pr_info("%s: SDHCI controller on %s [%s] using %s\n", diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 8aa0f4e077de..21d49a109c2b 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -574,6 +574,8 @@ struct sdhci_host { ktime_t data_start_time; unsigned int pm_qos_timeout_us; /* timeout for PM QoS request */ + struct device_attribute pm_qos_tout; + enum sdhci_power_policy power_policy; unsigned long private[0] ____cacheline_aligned;