diff --git a/drivers/scsi/ufs/ufs-qcom.c b/drivers/scsi/ufs/ufs-qcom.c index 7bff6414e6a6..5f9373b8b4a2 100644 --- a/drivers/scsi/ufs/ufs-qcom.c +++ b/drivers/scsi/ufs/ufs-qcom.c @@ -1995,6 +1995,8 @@ static int ufs_qcom_setup_clocks(struct ufs_hba *hba, bool on, { struct ufs_qcom_host *host = ufshcd_get_variant(hba); int err = 0; + struct list_head *head = &hba->clk_list_head; + struct ufs_clk_info *clki; /* * In case ufs_qcom_init() is not yet done, simply ignore. @@ -2021,6 +2023,33 @@ static int ufs_qcom_setup_clocks(struct ufs_hba *hba, bool on, return err; } } + + if (list_empty(head)) { + dev_err(hba->dev, "%s: clk list is empty\n", __func__); + return err; + } + /* + * As per the latest hardware programming guide, + * during Hibern8 enter with power collapse : + * SW should disable HW clock control for UFS ICE + * clock (GCC_UFS_ICE_CORE_CBCR.HW_CTL=0) + * before ufs_ice_core_clk is turned off. + * In device tree, we need to add UFS ICE clocks + * in below fixed order: + * clock-names = + * "core_clk_ice"; + * "core_clk_ice_hw_ctl"; + * This way no extra check is required in UFS + * clock enable path as clk enable order will be + * already taken care in ufshcd_setup_clocks(). + */ + list_for_each_entry(clki, head, list) { + if (!IS_ERR_OR_NULL(clki->clk) && + !strcmp(clki->name, "core_clk_ice_hw_ctl")) { + clk_disable_unprepare(clki->clk); + clki->enabled = on; + } + } } break; case POST_CHANGE: diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index d365dc3fa9ce..2e837f20fb88 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -1014,7 +1014,8 @@ static int ufshcd_set_clk_freq(struct ufs_hba *hba, bool scale_up) list_for_each_entry(clki, head, list) { if (!IS_ERR_OR_NULL(clki->clk)) { if (scale_up && clki->max_freq) { - if (clki->curr_freq == clki->max_freq) + if ((clki->curr_freq == clki->max_freq) || + (!strcmp(clki->name, "core_clk_ice_hw_ctl"))) continue; ret = clk_set_rate(clki->clk, clki->max_freq); @@ -1032,7 +1033,8 @@ static int ufshcd_set_clk_freq(struct ufs_hba *hba, bool scale_up) clki->curr_freq = clki->max_freq; } else if (!scale_up && clki->min_freq) { - if (clki->curr_freq == clki->min_freq) + if ((clki->curr_freq == clki->min_freq) || + (!strcmp(clki->name, "core_clk_ice_hw_ctl"))) continue; ret = clk_set_rate(clki->clk, clki->min_freq); @@ -8316,7 +8318,8 @@ static int ufshcd_init_clocks(struct ufs_hba *hba) goto out; list_for_each_entry(clki, head, list) { - if (!clki->name) + if ((!clki->name) || + (!strcmp(clki->name, "core_clk_ice_hw_ctl"))) continue; clki->clk = devm_clk_get(dev, clki->name);