OSDN Git Service

mmc: core: Initialize temperature controlled clock scaling
authorRam Prakash Gupta <rampraka@codeaurora.org>
Mon, 23 Jul 2018 07:26:28 +0000 (12:56 +0530)
committerRam Prakash Gupta <rampraka@codeaurora.org>
Thu, 26 Jul 2018 17:23:22 +0000 (22:53 +0530)
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>
drivers/mmc/core/core.c
drivers/mmc/core/sd.c
include/linux/mmc/host.h

index e4e4e04..b555540 100644 (file)
@@ -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;
index bf896b6..9a7f9d2 100644 (file)
@@ -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.
         */
index 48849ac..49648aa 100644 (file)
@@ -185,6 +185,9 @@ struct mmc_host_ops {
        int     (*notify_load)(struct mmc_host *, enum mmc_load);
        void    (*notify_halt)(struct mmc_host *mmc, bool halt);
        void    (*force_err_irq)(struct mmc_host *host, u64 errmask);
+       int     (*check_temp)(struct mmc_host *host);
+       int     (*reg_temp_callback)(struct mmc_host *host);
+       int     (*dereg_temp_callback)(struct mmc_host *host);
 };
 
 struct mmc_card;