Currently, the frequency that devfreq provides the driver to set 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. Signed-off-by: Asutosh Das <asutoshd@xxxxxxxxxxxxxx> --- drivers/scsi/ufs/ufshcd.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 2a2a63b..7916c8b 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -1187,6 +1187,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); @@ -1201,8 +1204,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; @@ -1250,6 +1256,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; @@ -1260,6 +1268,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)); -- Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project.