Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 7 Jun 2025 03:02:51 +0000 (20:02 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 7 Jun 2025 03:02:51 +0000 (20:02 -0700)
Pull SCSI fixes from James Bottomley:
 "Mostly trivial updates and bug fixes (core update is a comment
  spelling fix).

  The bigger UFS update is the clock scaling and frequency fixes"

* tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi:
  scsi: ufs: qcom: Prevent calling phy_exit() before phy_init()
  scsi: ufs: qcom: Call ufs_qcom_cfg_timers() in clock scaling path
  scsi: ufs: qcom: Map devfreq OPP freq to UniPro Core Clock freq
  scsi: ufs: qcom: Check gear against max gear in vop freq_to_gear()
  scsi: aacraid: Remove useless code
  scsi: core: devinfo: Fix typo in comment
  scsi: ufs: core: Don't perform UFS clkscaling during host async scan

1  2 
drivers/ufs/core/ufshcd.c
drivers/ufs/host/ufs-qcom.c

Simple merge
@@@ -2065,38 -2071,90 +2092,80 @@@ static int ufs_qcom_config_esi(struct u
                return ret;
        }
  
 -      msi_lock_descs(hba->dev);
 -      msi_for_each_desc(desc, hba->dev, MSI_DESC_ALL) {
 -              ret = devm_request_irq(hba->dev, desc->irq,
 -                                     ufs_qcom_mcq_esi_handler,
 -                                     IRQF_SHARED, "qcom-mcq-esi", desc);
 +      for (int idx = 0; idx < nr_irqs; idx++) {
 +              qi[idx].irq = msi_get_virq(hba->dev, idx);
 +              qi[idx].idx = idx;
 +              qi[idx].hba = hba;
 +
 +              ret = devm_request_irq(hba->dev, qi[idx].irq, ufs_qcom_mcq_esi_handler,
 +                                     IRQF_SHARED, "qcom-mcq-esi", qi + idx);
                if (ret) {
                        dev_err(hba->dev, "%s: Fail to request IRQ for %d, err = %d\n",
 -                              __func__, desc->irq, ret);
 -                      failed_desc = desc;
 -                      break;
 +                              __func__, qi[idx].irq, ret);
 +                      qi[idx].irq = 0;
 +                      return ret;
                }
        }
 -      msi_unlock_descs(hba->dev);
  
 -      if (ret) {
 -              /* Rewind */
 -              msi_lock_descs(hba->dev);
 -              msi_for_each_desc(desc, hba->dev, MSI_DESC_ALL) {
 -                      if (desc == failed_desc)
 -                              break;
 -                      devm_free_irq(hba->dev, desc->irq, hba);
 -              }
 -              msi_unlock_descs(hba->dev);
 -              platform_device_msi_free_irqs_all(hba->dev);
 -      } else {
 -              if (host->hw_ver.major == 6 && host->hw_ver.minor == 0 &&
 -                  host->hw_ver.step == 0)
 -                      ufshcd_rmwl(hba, ESI_VEC_MASK,
 -                                  FIELD_PREP(ESI_VEC_MASK, MAX_ESI_VEC - 1),
 -                                  REG_UFS_CFG3);
 -              ufshcd_mcq_enable_esi(hba);
 -              host->esi_enabled = true;
 -      }
 +      retain_and_null_ptr(qi);
  
 -      return ret;
 +      if (host->hw_ver.major == 6 && host->hw_ver.minor == 0 &&
 +          host->hw_ver.step == 0) {
 +              ufshcd_rmwl(hba, ESI_VEC_MASK, FIELD_PREP(ESI_VEC_MASK, MAX_ESI_VEC - 1),
 +                          REG_UFS_CFG3);
 +      }
 +      ufshcd_mcq_enable_esi(hba);
 +      host->esi_enabled = true;
 +      return 0;
  }
  
+ static unsigned long ufs_qcom_opp_freq_to_clk_freq(struct ufs_hba *hba,
+                                                  unsigned long freq, char *name)
+ {
+       struct ufs_clk_info *clki;
+       struct dev_pm_opp *opp;
+       unsigned long clk_freq;
+       int idx = 0;
+       bool found = false;
+       opp = dev_pm_opp_find_freq_exact_indexed(hba->dev, freq, 0, true);
+       if (IS_ERR(opp)) {
+               dev_err(hba->dev, "Failed to find OPP for exact frequency %lu\n", freq);
+               return 0;
+       }
+       list_for_each_entry(clki, &hba->clk_list_head, list) {
+               if (!strcmp(clki->name, name)) {
+                       found = true;
+                       break;
+               }
+               idx++;
+       }
+       if (!found) {
+               dev_err(hba->dev, "Failed to find clock '%s' in clk list\n", name);
+               dev_pm_opp_put(opp);
+               return 0;
+       }
+       clk_freq = dev_pm_opp_get_freq_indexed(opp, idx);
+       dev_pm_opp_put(opp);
+       return clk_freq;
+ }
  static u32 ufs_qcom_freq_to_gear_speed(struct ufs_hba *hba, unsigned long freq)
  {
-       u32 gear = 0;
+       u32 gear = UFS_HS_DONT_CHANGE;
+       unsigned long unipro_freq;
  
-       switch (freq) {
+       if (!hba->use_pm_opp)
+               return gear;
+       unipro_freq = ufs_qcom_opp_freq_to_clk_freq(hba, freq, "core_clk_unipro");
+       switch (unipro_freq) {
        case 403000000:
                gear = UFS_HS_G5;
                break;