If someone plays with the UFS clk scaling devfreq governor through sysfs, ufshcd_devfreq_scale may be called even when hba is not runtime ACTIVE, which can lead to unexpected error. We cannot just protect it by calling pm_runtime_get_sync, because that may cause racing problem since hba runtime suspend ops needs to suspend clk scaling. In order to fix it, call pm_runtime_get_noresume and check hba's runtime status, then only proceed if hba is runtime ACTIVE, otherwise just bail. governor_store devfreq_performance_handler update_devfreq devfreq_set_target ufshcd_devfreq_target ufshcd_devfreq_scale Signed-off-by: Can Guo <cang@xxxxxxxxxxxxxx> diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index e4cb994..847f355 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -1294,8 +1294,15 @@ static int ufshcd_devfreq_target(struct device *dev, } spin_unlock_irqrestore(hba->host->host_lock, irq_flags); + pm_runtime_get_noresume(hba->dev); + if (!pm_runtime_active(hba->dev)) { + pm_runtime_put_noidle(hba->dev); + ret = -EAGAIN; + goto out; + } start = ktime_get(); ret = ufshcd_devfreq_scale(hba, scale_up); + pm_runtime_put(hba->dev); trace_ufshcd_profile_clk_scaling(dev_name(hba->dev), (scale_up ? "up" : "down"), -- Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project.