Merge "mmc: sdhci-msm: get the load notification from clock scaling"
diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
index 60e8ca0..55d9cf5 100644
--- a/drivers/mmc/host/sdhci-msm.c
+++ b/drivers/mmc/host/sdhci-msm.c
@@ -1902,8 +1902,16 @@ struct sdhci_msm_pltfm_data *sdhci_msm_populate_pdata(struct device *dev,
dev_err(dev, "Invalid clock table\n");
goto out;
}
+ if (ice_clk_table_len != 2) {
+ dev_err(dev, "Need max and min frequencies in the table\n");
+ goto out;
+ }
pdata->sup_ice_clk_table = ice_clk_table;
pdata->sup_ice_clk_cnt = ice_clk_table_len;
+ pdata->ice_clk_max = pdata->sup_ice_clk_table[0];
+ pdata->ice_clk_min = pdata->sup_ice_clk_table[1];
+ dev_dbg(dev, "supported ICE clock rates (Hz): max: %u min: %u\n",
+ pdata->ice_clk_max, pdata->ice_clk_min);
}
pdata->vreg_data = devm_kzalloc(dev, sizeof(struct
@@ -4115,6 +4123,32 @@ static unsigned int sdhci_msm_get_current_limit(struct sdhci_host *host)
return max_curr;
}
+static int sdhci_msm_notify_load(struct sdhci_host *host, enum mmc_load state)
+{
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+ struct sdhci_msm_host *msm_host = pltfm_host->priv;
+ int ret = 0;
+ u32 clk_rate = 0;
+
+ if (!IS_ERR(msm_host->ice_clk)) {
+ clk_rate = (state == MMC_LOAD_LOW) ?
+ msm_host->pdata->ice_clk_min :
+ msm_host->pdata->ice_clk_max;
+ if (msm_host->ice_clk_rate == clk_rate)
+ return 0;
+ pr_debug("%s: changing ICE clk rate to %u\n",
+ mmc_hostname(host->mmc), clk_rate);
+ ret = clk_set_rate(msm_host->ice_clk, clk_rate);
+ if (ret) {
+ pr_err("%s: ICE_CLK rate set failed (%d) for %u\n",
+ mmc_hostname(host->mmc), ret, clk_rate);
+ return ret;
+ }
+ msm_host->ice_clk_rate = clk_rate;
+ }
+ return 0;
+}
+
static struct sdhci_ops sdhci_msm_ops = {
.crypto_engine_cfg = sdhci_msm_ice_cfg,
.crypto_engine_cmdq_cfg = sdhci_msm_ice_cmdq_cfg,
@@ -4142,6 +4176,7 @@ static struct sdhci_ops sdhci_msm_ops = {
.pre_req = sdhci_msm_pre_req,
.post_req = sdhci_msm_post_req,
.get_current_limit = sdhci_msm_get_current_limit,
+ .notify_load = sdhci_msm_notify_load,
};
static void sdhci_set_default_hw_caps(struct sdhci_msm_host *msm_host,
@@ -4439,11 +4474,11 @@ static int sdhci_msm_probe(struct platform_device *pdev)
if (!IS_ERR(msm_host->ice_clk)) {
/* ICE core has only one clock frequency for now */
ret = clk_set_rate(msm_host->ice_clk,
- msm_host->pdata->sup_ice_clk_table[0]);
+ msm_host->pdata->ice_clk_max);
if (ret) {
dev_err(&pdev->dev, "ICE_CLK rate set failed (%d) for %u\n",
ret,
- msm_host->pdata->sup_ice_clk_table[0]);
+ msm_host->pdata->ice_clk_max);
goto pclk_disable;
}
ret = clk_prepare_enable(msm_host->ice_clk);
@@ -4451,7 +4486,7 @@ static int sdhci_msm_probe(struct platform_device *pdev)
goto pclk_disable;
msm_host->ice_clk_rate =
- msm_host->pdata->sup_clk_table[0];
+ msm_host->pdata->ice_clk_max;
}
}
diff --git a/drivers/mmc/host/sdhci-msm.h b/drivers/mmc/host/sdhci-msm.h
index cdbaaa9..7c0b873 100644
--- a/drivers/mmc/host/sdhci-msm.h
+++ b/drivers/mmc/host/sdhci-msm.h
@@ -151,6 +151,8 @@ struct sdhci_msm_pltfm_data {
unsigned char sup_ice_clk_cnt;
struct sdhci_msm_pm_qos_data pm_qos_data;
bool sdr104_wa;
+ u32 ice_clk_max;
+ u32 ice_clk_min;
};
struct sdhci_msm_bus_vote {