Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

scsi: ufs: core: Set default runtime/system PM levels before ufshcd_hba_init()

Commit bb9850704c04 ("scsi: ufs: core: Honor runtime/system PM levels if
set by host controller drivers") introduced the check for setting default
PM levels only if the levels are uninitialized by the host controller
drivers. But it missed the fact that the levels could be initialized to 0
(UFS_PM_LVL_0) on purpose by the controller drivers. Even though none of
the drivers are doing so now, the logic should be fixed irrespectively.

So set the default levels unconditionally before calling ufshcd_hba_init()
API which initializes the controller drivers. It ensures that the
controller drivers could override the default levels if required.

Fixes: bb9850704c04 ("scsi: ufs: core: Honor runtime/system PM levels if set by host controller drivers")
Reported-by: Bao D. Nguyen <quic_nguyenb@quicinc.com>
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Link: https://lore.kernel.org/r/20250219105047.49932-1-manivannan.sadhasivam@linaro.org
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>

authored by

Manivannan Sadhasivam and committed by
Martin K. Petersen
fe06b7c0 dce5c4af

+15 -15
+15 -15
drivers/ufs/core/ufshcd.c
··· 10431 10431 */ 10432 10432 spin_lock_init(&hba->clk_gating.lock); 10433 10433 10434 + /* 10435 + * Set the default power management level for runtime and system PM. 10436 + * Host controller drivers can override them in their 10437 + * 'ufs_hba_variant_ops::init' callback. 10438 + * 10439 + * Default power saving mode is to keep UFS link in Hibern8 state 10440 + * and UFS device in sleep state. 10441 + */ 10442 + hba->rpm_lvl = ufs_get_desired_pm_lvl_for_dev_link_state( 10443 + UFS_SLEEP_PWR_MODE, 10444 + UIC_LINK_HIBERN8_STATE); 10445 + hba->spm_lvl = ufs_get_desired_pm_lvl_for_dev_link_state( 10446 + UFS_SLEEP_PWR_MODE, 10447 + UIC_LINK_HIBERN8_STATE); 10448 + 10434 10449 err = ufshcd_hba_init(hba); 10435 10450 if (err) 10436 10451 goto out_error; ··· 10558 10543 ufshcd_print_host_state(hba); 10559 10544 goto out_disable; 10560 10545 } 10561 - 10562 - /* 10563 - * Set the default power management level for runtime and system PM if 10564 - * not set by the host controller drivers. 10565 - * Default power saving mode is to keep UFS link in Hibern8 state 10566 - * and UFS device in sleep state. 10567 - */ 10568 - if (!hba->rpm_lvl) 10569 - hba->rpm_lvl = ufs_get_desired_pm_lvl_for_dev_link_state( 10570 - UFS_SLEEP_PWR_MODE, 10571 - UIC_LINK_HIBERN8_STATE); 10572 - if (!hba->spm_lvl) 10573 - hba->spm_lvl = ufs_get_desired_pm_lvl_for_dev_link_state( 10574 - UFS_SLEEP_PWR_MODE, 10575 - UIC_LINK_HIBERN8_STATE); 10576 10546 10577 10547 INIT_DELAYED_WORK(&hba->rpm_dev_flush_recheck_work, ufshcd_rpm_dev_flush_recheck_work); 10578 10548 INIT_DELAYED_WORK(&hba->ufs_rtc_update_work, ufshcd_rtc_work);