summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorRam Prakash Gupta <rampraka@codeaurora.org>2018-07-23 12:56:28 +0530
committerRam Prakash Gupta <rampraka@codeaurora.org>2018-07-26 22:53:22 +0530
commit9727198d6d71ec5f624da1eb55b296c51d546742 (patch)
tree38ce46475e944243b1bfd21d74339665b74226de /drivers
parent24e44f04e9588864f7caefe9676b109f7dd55921 (diff)
mmc: core: Initialize temperature controlled clock scaling
Register and deregister for temperature controlled clk scaling when card is attached and dettached from the device. This will allow to control the clock frequency based on temperature. Change-Id: Ie01d573406c273847fb31a5dd64e2b39671e4ac0 Signed-off-by: Ram Prakash Gupta <rampraka@codeaurora.org>
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 e4e4e04e1d0c..b55554079452 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.
*/