{
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");
}
}
- 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;
#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
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;
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.
*/
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);
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.
*/
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;