summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2019-01-23 21:24:27 -0800
committerGerrit - the friendly Code Review server <code-review@localhost>2019-01-23 21:24:26 -0800
commit86330cd7a198ac705d87637a8d5d677f3c132b62 (patch)
tree5d670e30fb78e68211389403888a06ef3e22673e /drivers
parent8b1c3f57dd7a8af6855d3b1eb2168def5531e698 (diff)
parent9727198d6d71ec5f624da1eb55b296c51d546742 (diff)
Merge "mmc: core: Initialize temperature controlled clock scaling"
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mmc/core/core.c10
-rw-r--r--drivers/mmc/core/sd.c40
2 files changed, 48 insertions, 2 deletions
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 76dbbbde884b..db4f4c8638b4 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -285,6 +285,7 @@ static int mmc_devfreq_get_dev_status(struct device *dev,
{
struct mmc_host *host = container_of(dev, struct mmc_host, class_dev);
struct mmc_devfeq_clk_scaling *clk_scaling;
+ bool disable = false;
if (!host) {
pr_err("bad host parameter\n");
@@ -312,7 +313,14 @@ static int mmc_devfreq_get_dev_status(struct device *dev,
}
}
- status->busy_time = clk_scaling->total_busy_time_us;
+ if (host->ops->check_temp &&
+ host->card->clk_scaling_highest > UHS_DDR50_MAX_DTR)
+ disable = host->ops->check_temp(host);
+ /* busy_time=0 for running at low freq*/
+ if (disable)
+ status->busy_time = 0;
+ else
+ status->busy_time = clk_scaling->total_busy_time_us;
status->total_time = ktime_to_us(ktime_sub(ktime_get(),
clk_scaling->measure_interval_start));
clk_scaling->total_busy_time_us = 0;
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index bf896b605487..9a7f9d27be1f 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -33,6 +33,8 @@
#define UHS_SDR25_MIN_DTR (25 * 1000 * 1000)
#define UHS_SDR12_MIN_DTR (12.5 * 1000 * 1000)
+#define ENOCALLBACK 1
+
static const unsigned int tran_exp[] = {
10000, 100000, 1000000, 10000000,
0, 0, 0, 0
@@ -498,7 +500,11 @@ static int sd_set_bus_speed_mode(struct mmc_card *card, u8 *status)
err = -EBUSY;
} else {
mmc_set_timing(card->host, timing);
- mmc_set_clock(card->host, card->sw_caps.uhs_max_dtr);
+ if (card->host->ops->check_temp(card->host) &&
+ timing == MMC_TIMING_UHS_SDR104)
+ mmc_set_clock(card->host, UHS_SDR50_MAX_DTR);
+ else
+ mmc_set_clock(card->host, card->sw_caps.uhs_max_dtr);
}
return err;
@@ -1122,6 +1128,34 @@ free_card:
return err;
}
+static int mmc_sd_init_temp_control_clk_scaling(struct mmc_host *host)
+{
+ int ret;
+
+ if (host->ops->reg_temp_callback) {
+ ret = host->ops->reg_temp_callback(host);
+ } else {
+ pr_err("%s: %s: couldn't find init temp control clk scaling cb\n",
+ mmc_hostname(host), __func__);
+ ret = -ENOCALLBACK;
+ }
+ return ret;
+}
+
+static int mmc_sd_dereg_temp_control_clk_scaling(struct mmc_host *host)
+{
+ int ret;
+
+ if (host->ops->dereg_temp_callback) {
+ ret = host->ops->dereg_temp_callback(host);
+ } else {
+ pr_err("%s: %s: couldn't find dereg temp control clk scaling cb\n",
+ mmc_hostname(host), __func__);
+ ret = -ENOCALLBACK;
+ }
+ return ret;
+}
+
/*
* Host is being removed. Free up the current card.
*/
@@ -1131,6 +1165,7 @@ static void mmc_sd_remove(struct mmc_host *host)
BUG_ON(!host->card);
mmc_exit_clk_scaling(host);
+ mmc_sd_dereg_temp_control_clk_scaling(host);
mmc_remove_card(host->card);
mmc_claim_host(host);
@@ -1458,6 +1493,9 @@ int mmc_attach_sd(struct mmc_host *host)
goto err;
}
+ if (mmc_sd_init_temp_control_clk_scaling(host))
+ pr_err("%s: failed to init temp control clk scaling\n",
+ mmc_hostname(host));
/*
* Detect and init the card.
*/