diff options
author | Asutosh Das <asutoshd@codeaurora.org> | 2020-03-25 11:29:00 -0700 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2020-03-26 22:18:12 -0400 |
commit | 91831d3336627ff0585c1519935bc11b48de22c6 (patch) | |
tree | f13065a79210b910628f3b12e437c225a9c25769 /drivers/scsi/ufs | |
parent | 0c2039dc1591bb9a3b887753b37946f09f4bf208 (diff) | |
download | linux-stable-91831d3336627ff0585c1519935bc11b48de22c6.tar.gz linux-stable-91831d3336627ff0585c1519935bc11b48de22c6.tar.bz2 linux-stable-91831d3336627ff0585c1519935bc11b48de22c6.zip |
scsi: ufshcd: Update the set frequency to devfreq
Currently, the frequency that devfreq provides the driver always leads the
clocks to be scaled up. Hence, round the clock-rate to the nearest
frequency before deciding to scale.
Also update the devfreq statistics of current frequency.
Link: https://lore.kernel.org/r/d0c6c22455811e9f0eda01f9bc70d1398b51b2bd.1585160616.git.asutoshd@codeaurora.org
Acked-by: Avri Altman <Avri.Altman@wdc.com>
Signed-off-by: Asutosh Das <asutoshd@codeaurora.org>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/ufs')
-rw-r--r-- | drivers/scsi/ufs/ufshcd.c | 17 |
1 files changed, 16 insertions, 1 deletions
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 153743eef082..95e68a6cef3c 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -1199,6 +1199,9 @@ static int ufshcd_devfreq_target(struct device *dev, if (!ufshcd_is_clkscaling_supported(hba)) return -EINVAL; + clki = list_first_entry(&hba->clk_list_head, struct ufs_clk_info, list); + /* Override with the closest supported frequency */ + *freq = (unsigned long) clk_round_rate(clki->clk, *freq); spin_lock_irqsave(hba->host->host_lock, irq_flags); if (ufshcd_eh_in_progress(hba)) { spin_unlock_irqrestore(hba->host->host_lock, irq_flags); @@ -1213,8 +1216,11 @@ static int ufshcd_devfreq_target(struct device *dev, goto out; } - clki = list_first_entry(&hba->clk_list_head, struct ufs_clk_info, list); + /* Decide based on the rounded-off frequency and update */ scale_up = (*freq == clki->max_freq) ? true : false; + if (!scale_up) + *freq = clki->min_freq; + /* Update the frequency */ if (!ufshcd_is_devfreq_scaling_required(hba, scale_up)) { spin_unlock_irqrestore(hba->host->host_lock, irq_flags); ret = 0; @@ -1262,6 +1268,8 @@ static int ufshcd_devfreq_get_dev_status(struct device *dev, struct ufs_hba *hba = dev_get_drvdata(dev); struct ufs_clk_scaling *scaling = &hba->clk_scaling; unsigned long flags; + struct list_head *clk_list = &hba->clk_list_head; + struct ufs_clk_info *clki; if (!ufshcd_is_clkscaling_supported(hba)) return -EINVAL; @@ -1272,6 +1280,13 @@ static int ufshcd_devfreq_get_dev_status(struct device *dev, if (!scaling->window_start_t) goto start_window; + clki = list_first_entry(clk_list, struct ufs_clk_info, list); + /* + * If current frequency is 0, then the ondemand governor considers + * there's no initial frequency set. And it always requests to set + * to max. frequency. + */ + stat->current_frequency = clki->curr_freq; if (scaling->is_busy_started) scaling->tot_busy_t += ktime_to_us(ktime_sub(ktime_get(), scaling->busy_start_t)); |