On Mon, 4 Nov 2024 at 08:34, Shawn Lin <shawn.lin@xxxxxxxxxxxxxx> wrote: > > RK3576 SoC contains a UFS controller, add initial support for it. > The features are: > (1) support UFS 2.0 features > (2) High speed up to HS-G3 > (3) 2RX-2TX lanes > (4) auto H8 entry and exit > > Software limitation: > (1) HCE procedure: enable controller->enable intr->dme_reset->dme_enable > (2) disable unipro timeout values before power mode change > > Signed-off-by: Shawn Lin <shawn.lin@xxxxxxxxxxxxxx> > --- > > Changes in v4: > - deal with power domain of rpm and spm suggested by Ulf > - Fix typo and disable clks in ufs_rockchip_remove > - remove clk_disable_unprepare(host->ref_out_clk) from > ufs_rockchip_remove > [...] > +#ifdef CONFIG_PM > +static int ufs_rockchip_runtime_suspend(struct device *dev) > +{ > + struct ufs_hba *hba = dev_get_drvdata(dev); > + struct ufs_rockchip_host *host = ufshcd_get_variant(hba); > + > + clk_disable_unprepare(host->ref_out_clk); > + > + /* Shouldn't power down if rpm_lvl is less than level 5. */ > + dev_pm_genpd_rpm_always_on(dev, hba->rpm_lvl < UFS_PM_LVL_5 ? true : false); > + > + return ufshcd_runtime_suspend(dev); > +} > + > +static int ufs_rockchip_runtime_resume(struct device *dev) > +{ > + struct ufs_hba *hba = dev_get_drvdata(dev); > + struct ufs_rockchip_host *host = ufshcd_get_variant(hba); > + int err; > + > + err = clk_prepare_enable(host->ref_out_clk); > + if (err) { > + dev_err(hba->dev, "failed to enable ref out clock %d\n", err); > + return err; > + } > + > + reset_control_assert(host->rst); > + usleep_range(1, 2); > + reset_control_deassert(host->rst); > + > + return ufshcd_runtime_resume(dev); > +} > +#endif > + > +#ifdef CONFIG_PM_SLEEP > +static int ufs_rockchip_system_suspend(struct device *dev) > +{ > + struct ufs_hba *hba = dev_get_drvdata(dev); > + > + if (hba->spm_lvl < 5) > + device_set_wakeup_path(dev); Please use device_set_awake_path() instead. Ideally all users of device_set_wakeup_path() should convert into device_set_awake_path(), it's just that we haven't been able to complete the conversion yet. > + else > + device_clr_wakeup_path(dev); This isn't needed. The flag is getting cleared in device_prepare(). > + > + return ufshcd_system_suspend(dev); Don't you want to disable the clock during system suspend too? If the device is runtime resumed at this point, the clock will be left enabled, no? > +} > +#endif > + > +static const struct dev_pm_ops ufs_rockchip_pm_ops = { > + SET_SYSTEM_SLEEP_PM_OPS(ufs_rockchip_system_suspend, ufshcd_system_resume) > + SET_RUNTIME_PM_OPS(ufs_rockchip_runtime_suspend, ufs_rockchip_runtime_resume, NULL) > + .prepare = ufshcd_suspend_prepare, > + .complete = ufshcd_resume_complete, > +}; > + [...] Kind regards Uffe