Please remind me what the spin lock is protecting here?
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 | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 2a2a63b..4607bc6 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);
Good point - I'll change it.
if (ufshcd_eh_in_progress(hba)) {This was already established 2 lines above ?
spin_unlock_irqrestore(hba->host->host_lock, irq_flags);
@@ -1201,8 +1204,13 @@ 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->max_freq;
Sure - I'll add a comment. If stat->current_frequency is not updated, the governor would always ask to set the max freq because the initial frequency was unknown to it. Reference - devfreq_simple_ondemand_func(...)
+ elseIs this a bug fix? > devfreq_simple_ondemand_func is trying to establish the busy period,
+ *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 +1258,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 +1270,8 @@ 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);
+ stat->current_frequency = clki->curr_freq;
but also uses the frequency in its calculation - which I wasn't able to understand how.
Can you add a short comment why updating current_frequency is needed?
Thanks,
Avri