scsi: ufshcd: Update the set frequency to devfreq
authorAsutosh Das <asutoshd@codeaurora.org>
Wed, 25 Mar 2020 18:29:00 +0000 (11:29 -0700)
committerMartin K. Petersen <martin.petersen@oracle.com>
Fri, 27 Mar 2020 02:18:12 +0000 (22:18 -0400)
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>
drivers/scsi/ufs/ufshcd.c

index 153743e..95e68a6 100644 (file)
@@ -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));