Loading drivers/scsi/ufs/ufs-qcom.c +20 −2 Original line number Diff line number Diff line Loading @@ -1236,7 +1236,18 @@ static void ufs_qcom_set_caps(struct ufs_hba *hba) } } static int ufs_qcom_setup_clocks(struct ufs_hba *hba, bool on) /** * ufs_qcom_setup_clocks - enables/disable clocks * @hba: host controller instance * @on: If true, enable clocks else disable them. * @is_gating_context: If true then it means this function is called from * aggressive clock gating context and we may only need to gate off important * clocks. If false then make sure to gate off all clocks. * * Returns 0 on success, non-zero on failure. */ static int ufs_qcom_setup_clocks(struct ufs_hba *hba, bool on, bool is_gating_context) { struct ufs_qcom_host *host = ufshcd_get_variant(hba); int err; Loading Loading @@ -1719,6 +1730,13 @@ static int ufs_qcom_init(struct ufs_hba *hba) host->hba = hba; ufshcd_bind_variant(hba, host); /* * voting/devoting device ref_clk source is time consuming hence * skip devoting it during aggressive clock gating. This clock * will still be gated off during runtime suspend. */ hba->no_ref_clk_gating = true; err = ufs_qcom_ice_get_dev(host); if (err == -EPROBE_DEFER) { /* Loading Loading @@ -1805,7 +1823,7 @@ static int ufs_qcom_init(struct ufs_hba *hba) ufs_qcom_set_caps(hba); ufs_qcom_advertise_quirks(hba); ufs_qcom_setup_clocks(hba, true); ufs_qcom_setup_clocks(hba, true, false); if (hba->dev->id < MAX_UFS_QCOM_HOSTS) ufs_qcom_hosts[hba->dev->id] = host; Loading drivers/scsi/ufs/ufshcd.c +36 −28 Original line number Diff line number Diff line Loading @@ -359,9 +359,11 @@ static int ufshcd_eh_host_reset_handler(struct scsi_cmnd *cmd); static int ufshcd_clear_tm_cmd(struct ufs_hba *hba, int tag); static void ufshcd_hba_exit(struct ufs_hba *hba); static int ufshcd_probe_hba(struct ufs_hba *hba); static int __ufshcd_setup_clocks(struct ufs_hba *hba, bool on, bool skip_ref_clk); static int ufshcd_setup_clocks(struct ufs_hba *hba, bool on); static int ufshcd_enable_clocks(struct ufs_hba *hba); static int ufshcd_disable_clocks(struct ufs_hba *hba, bool is_gating_context); static int ufshcd_disable_clocks_skip_ref_clk(struct ufs_hba *hba, bool is_gating_context); static int ufshcd_set_vccq_rail_unused(struct ufs_hba *hba, bool unused); static int ufshcd_uic_hibern8_exit(struct ufs_hba *hba); static int ufshcd_uic_hibern8_enter(struct ufs_hba *hba); Loading Loading @@ -1136,7 +1138,7 @@ static void ufshcd_ungate_work(struct work_struct *work) spin_unlock_irqrestore(hba->host->host_lock, flags); ufshcd_hba_vreg_set_hpm(hba); ufshcd_setup_clocks(hba, true); ufshcd_enable_clocks(hba); /* Exit from hibern8 */ if (ufshcd_can_hibern8_during_gating(hba)) { Loading Loading @@ -1270,11 +1272,11 @@ static void ufshcd_gate_work(struct work_struct *work) ufshcd_suspend_clkscaling(hba); if (!ufshcd_is_link_active(hba)) ufshcd_setup_clocks(hba, false); if (!ufshcd_is_link_active(hba) && !hba->no_ref_clk_gating) ufshcd_disable_clocks(hba, true); else /* If link is active, device ref_clk can't be switched off */ __ufshcd_setup_clocks(hba, false, true); ufshcd_disable_clocks_skip_ref_clk(hba, true); /* Put the host controller in low power mode if possible */ ufshcd_hba_vreg_set_lpm(hba); Loading Loading @@ -7057,8 +7059,8 @@ out: return ret; } static int __ufshcd_setup_clocks(struct ufs_hba *hba, bool on, bool skip_ref_clk) static int ufshcd_setup_clocks(struct ufs_hba *hba, bool on, bool skip_ref_clk, bool is_gating_context) { int ret = 0; struct ufs_clk_info *clki; Loading @@ -7076,7 +7078,7 @@ static int __ufshcd_setup_clocks(struct ufs_hba *hba, bool on, * before disabling the clocks managed here. */ if (!on) { ret = ufshcd_vops_setup_clocks(hba, on); ret = ufshcd_vops_setup_clocks(hba, on, is_gating_context); if (ret) return ret; } Loading Loading @@ -7109,7 +7111,7 @@ static int __ufshcd_setup_clocks(struct ufs_hba *hba, bool on, * after enabling the clocks managed here. */ if (on) ret = ufshcd_vops_setup_clocks(hba, on); ret = ufshcd_vops_setup_clocks(hba, on, is_gating_context); out: if (ret) { Loading @@ -7134,9 +7136,21 @@ out: return ret; } static int ufshcd_setup_clocks(struct ufs_hba *hba, bool on) static int ufshcd_enable_clocks(struct ufs_hba *hba) { return ufshcd_setup_clocks(hba, true, false, false); } static int ufshcd_disable_clocks(struct ufs_hba *hba, bool is_gating_context) { return ufshcd_setup_clocks(hba, false, false, is_gating_context); } static int ufshcd_disable_clocks_skip_ref_clk(struct ufs_hba *hba, bool is_gating_context) { return __ufshcd_setup_clocks(hba, on, false); return ufshcd_setup_clocks(hba, false, true, is_gating_context); } static int ufshcd_init_clocks(struct ufs_hba *hba) Loading Loading @@ -7209,8 +7223,6 @@ static void ufshcd_variant_hba_exit(struct ufs_hba *hba) if (!hba->var || !hba->var->vops) return; ufshcd_vops_setup_clocks(hba, false); ufshcd_vops_setup_regulators(hba, false); ufshcd_vops_exit(hba); Loading Loading @@ -7239,7 +7251,7 @@ static int ufshcd_hba_init(struct ufs_hba *hba) if (err) goto out_disable_hba_vreg; err = ufshcd_setup_clocks(hba, true); err = ufshcd_enable_clocks(hba); if (err) goto out_disable_hba_vreg; Loading @@ -7261,7 +7273,7 @@ static int ufshcd_hba_init(struct ufs_hba *hba) out_disable_vreg: ufshcd_setup_vreg(hba, false); out_disable_clks: ufshcd_setup_clocks(hba, false); ufshcd_disable_clocks(hba, false); out_disable_hba_vreg: ufshcd_setup_hba_vreg(hba, false); out: Loading @@ -7274,7 +7286,7 @@ static void ufshcd_hba_exit(struct ufs_hba *hba) ufshcd_variant_hba_exit(hba); ufshcd_setup_vreg(hba, false); ufshcd_suspend_clkscaling(hba); ufshcd_setup_clocks(hba, false); ufshcd_disable_clocks(hba, false); ufshcd_setup_hba_vreg(hba, false); hba->is_powered = false; } Loading Loading @@ -7619,15 +7631,13 @@ disable_clks: if (ret) goto set_link_active; ret = ufshcd_vops_setup_clocks(hba, false); if (ret) goto vops_resume; if (!ufshcd_is_link_active(hba)) ufshcd_setup_clocks(hba, false); ret = ufshcd_disable_clocks(hba, false); else /* If link is active, device ref_clk can't be switched off */ __ufshcd_setup_clocks(hba, false, true); ret = ufshcd_disable_clocks_skip_ref_clk(hba, false); if (ret) goto set_link_active; hba->clk_gating.state = CLKS_OFF; trace_ufshcd_clk_gating(dev_name(hba->dev), hba->clk_gating.state); Loading @@ -7640,8 +7650,6 @@ disable_clks: ufshcd_hba_vreg_set_lpm(hba); goto out; vops_resume: ufshcd_vops_resume(hba, pm_op); set_link_active: ufshcd_resume_clkscaling(hba); ufshcd_vreg_set_hpm(hba); Loading Loading @@ -7688,7 +7696,7 @@ static int ufshcd_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op) ufshcd_hba_vreg_set_hpm(hba); /* Make sure clocks are enabled before accessing controller */ ret = ufshcd_setup_clocks(hba, true); ret = ufshcd_enable_clocks(hba); if (ret) goto out; Loading Loading @@ -7764,7 +7772,7 @@ disable_vreg: disable_irq_and_vops_clks: ufshcd_disable_irq(hba); ufshcd_suspend_clkscaling(hba); ufshcd_setup_clocks(hba, false); ufshcd_disable_clocks(hba, false); out: hba->pm_op_in_progress = 0; Loading drivers/scsi/ufs/ufshcd.h +7 −3 Original line number Diff line number Diff line Loading @@ -313,7 +313,7 @@ struct ufs_hba_variant_ops { void (*exit)(struct ufs_hba *); u32 (*get_ufs_hci_version)(struct ufs_hba *); int (*clk_scale_notify)(struct ufs_hba *, bool, bool); int (*setup_clocks)(struct ufs_hba *, bool); int (*setup_clocks)(struct ufs_hba *, bool, bool); int (*setup_regulators)(struct ufs_hba *, bool); int (*hce_enable_notify)(struct ufs_hba *, enum ufs_notify_change_status); Loading Loading @@ -840,6 +840,9 @@ struct ufs_hba { bool is_urgent_bkops_lvl_checked; struct rw_semaphore clk_scaling_lock; /* If set, don't gate device ref_clk during clock gating */ bool no_ref_clk_gating; }; /* Returns true if clocks can be gated. Otherwise false */ Loading Loading @@ -1070,10 +1073,11 @@ static inline int ufshcd_vops_clk_scale_notify(struct ufs_hba *hba, return 0; } static inline int ufshcd_vops_setup_clocks(struct ufs_hba *hba, bool on) static inline int ufshcd_vops_setup_clocks(struct ufs_hba *hba, bool on, bool is_gating_context) { if (hba->var && hba->var->vops && hba->var->vops->setup_clocks) return hba->var->vops->setup_clocks(hba, on); return hba->var->vops->setup_clocks(hba, on, is_gating_context); return 0; } Loading Loading
drivers/scsi/ufs/ufs-qcom.c +20 −2 Original line number Diff line number Diff line Loading @@ -1236,7 +1236,18 @@ static void ufs_qcom_set_caps(struct ufs_hba *hba) } } static int ufs_qcom_setup_clocks(struct ufs_hba *hba, bool on) /** * ufs_qcom_setup_clocks - enables/disable clocks * @hba: host controller instance * @on: If true, enable clocks else disable them. * @is_gating_context: If true then it means this function is called from * aggressive clock gating context and we may only need to gate off important * clocks. If false then make sure to gate off all clocks. * * Returns 0 on success, non-zero on failure. */ static int ufs_qcom_setup_clocks(struct ufs_hba *hba, bool on, bool is_gating_context) { struct ufs_qcom_host *host = ufshcd_get_variant(hba); int err; Loading Loading @@ -1719,6 +1730,13 @@ static int ufs_qcom_init(struct ufs_hba *hba) host->hba = hba; ufshcd_bind_variant(hba, host); /* * voting/devoting device ref_clk source is time consuming hence * skip devoting it during aggressive clock gating. This clock * will still be gated off during runtime suspend. */ hba->no_ref_clk_gating = true; err = ufs_qcom_ice_get_dev(host); if (err == -EPROBE_DEFER) { /* Loading Loading @@ -1805,7 +1823,7 @@ static int ufs_qcom_init(struct ufs_hba *hba) ufs_qcom_set_caps(hba); ufs_qcom_advertise_quirks(hba); ufs_qcom_setup_clocks(hba, true); ufs_qcom_setup_clocks(hba, true, false); if (hba->dev->id < MAX_UFS_QCOM_HOSTS) ufs_qcom_hosts[hba->dev->id] = host; Loading
drivers/scsi/ufs/ufshcd.c +36 −28 Original line number Diff line number Diff line Loading @@ -359,9 +359,11 @@ static int ufshcd_eh_host_reset_handler(struct scsi_cmnd *cmd); static int ufshcd_clear_tm_cmd(struct ufs_hba *hba, int tag); static void ufshcd_hba_exit(struct ufs_hba *hba); static int ufshcd_probe_hba(struct ufs_hba *hba); static int __ufshcd_setup_clocks(struct ufs_hba *hba, bool on, bool skip_ref_clk); static int ufshcd_setup_clocks(struct ufs_hba *hba, bool on); static int ufshcd_enable_clocks(struct ufs_hba *hba); static int ufshcd_disable_clocks(struct ufs_hba *hba, bool is_gating_context); static int ufshcd_disable_clocks_skip_ref_clk(struct ufs_hba *hba, bool is_gating_context); static int ufshcd_set_vccq_rail_unused(struct ufs_hba *hba, bool unused); static int ufshcd_uic_hibern8_exit(struct ufs_hba *hba); static int ufshcd_uic_hibern8_enter(struct ufs_hba *hba); Loading Loading @@ -1136,7 +1138,7 @@ static void ufshcd_ungate_work(struct work_struct *work) spin_unlock_irqrestore(hba->host->host_lock, flags); ufshcd_hba_vreg_set_hpm(hba); ufshcd_setup_clocks(hba, true); ufshcd_enable_clocks(hba); /* Exit from hibern8 */ if (ufshcd_can_hibern8_during_gating(hba)) { Loading Loading @@ -1270,11 +1272,11 @@ static void ufshcd_gate_work(struct work_struct *work) ufshcd_suspend_clkscaling(hba); if (!ufshcd_is_link_active(hba)) ufshcd_setup_clocks(hba, false); if (!ufshcd_is_link_active(hba) && !hba->no_ref_clk_gating) ufshcd_disable_clocks(hba, true); else /* If link is active, device ref_clk can't be switched off */ __ufshcd_setup_clocks(hba, false, true); ufshcd_disable_clocks_skip_ref_clk(hba, true); /* Put the host controller in low power mode if possible */ ufshcd_hba_vreg_set_lpm(hba); Loading Loading @@ -7057,8 +7059,8 @@ out: return ret; } static int __ufshcd_setup_clocks(struct ufs_hba *hba, bool on, bool skip_ref_clk) static int ufshcd_setup_clocks(struct ufs_hba *hba, bool on, bool skip_ref_clk, bool is_gating_context) { int ret = 0; struct ufs_clk_info *clki; Loading @@ -7076,7 +7078,7 @@ static int __ufshcd_setup_clocks(struct ufs_hba *hba, bool on, * before disabling the clocks managed here. */ if (!on) { ret = ufshcd_vops_setup_clocks(hba, on); ret = ufshcd_vops_setup_clocks(hba, on, is_gating_context); if (ret) return ret; } Loading Loading @@ -7109,7 +7111,7 @@ static int __ufshcd_setup_clocks(struct ufs_hba *hba, bool on, * after enabling the clocks managed here. */ if (on) ret = ufshcd_vops_setup_clocks(hba, on); ret = ufshcd_vops_setup_clocks(hba, on, is_gating_context); out: if (ret) { Loading @@ -7134,9 +7136,21 @@ out: return ret; } static int ufshcd_setup_clocks(struct ufs_hba *hba, bool on) static int ufshcd_enable_clocks(struct ufs_hba *hba) { return ufshcd_setup_clocks(hba, true, false, false); } static int ufshcd_disable_clocks(struct ufs_hba *hba, bool is_gating_context) { return ufshcd_setup_clocks(hba, false, false, is_gating_context); } static int ufshcd_disable_clocks_skip_ref_clk(struct ufs_hba *hba, bool is_gating_context) { return __ufshcd_setup_clocks(hba, on, false); return ufshcd_setup_clocks(hba, false, true, is_gating_context); } static int ufshcd_init_clocks(struct ufs_hba *hba) Loading Loading @@ -7209,8 +7223,6 @@ static void ufshcd_variant_hba_exit(struct ufs_hba *hba) if (!hba->var || !hba->var->vops) return; ufshcd_vops_setup_clocks(hba, false); ufshcd_vops_setup_regulators(hba, false); ufshcd_vops_exit(hba); Loading Loading @@ -7239,7 +7251,7 @@ static int ufshcd_hba_init(struct ufs_hba *hba) if (err) goto out_disable_hba_vreg; err = ufshcd_setup_clocks(hba, true); err = ufshcd_enable_clocks(hba); if (err) goto out_disable_hba_vreg; Loading @@ -7261,7 +7273,7 @@ static int ufshcd_hba_init(struct ufs_hba *hba) out_disable_vreg: ufshcd_setup_vreg(hba, false); out_disable_clks: ufshcd_setup_clocks(hba, false); ufshcd_disable_clocks(hba, false); out_disable_hba_vreg: ufshcd_setup_hba_vreg(hba, false); out: Loading @@ -7274,7 +7286,7 @@ static void ufshcd_hba_exit(struct ufs_hba *hba) ufshcd_variant_hba_exit(hba); ufshcd_setup_vreg(hba, false); ufshcd_suspend_clkscaling(hba); ufshcd_setup_clocks(hba, false); ufshcd_disable_clocks(hba, false); ufshcd_setup_hba_vreg(hba, false); hba->is_powered = false; } Loading Loading @@ -7619,15 +7631,13 @@ disable_clks: if (ret) goto set_link_active; ret = ufshcd_vops_setup_clocks(hba, false); if (ret) goto vops_resume; if (!ufshcd_is_link_active(hba)) ufshcd_setup_clocks(hba, false); ret = ufshcd_disable_clocks(hba, false); else /* If link is active, device ref_clk can't be switched off */ __ufshcd_setup_clocks(hba, false, true); ret = ufshcd_disable_clocks_skip_ref_clk(hba, false); if (ret) goto set_link_active; hba->clk_gating.state = CLKS_OFF; trace_ufshcd_clk_gating(dev_name(hba->dev), hba->clk_gating.state); Loading @@ -7640,8 +7650,6 @@ disable_clks: ufshcd_hba_vreg_set_lpm(hba); goto out; vops_resume: ufshcd_vops_resume(hba, pm_op); set_link_active: ufshcd_resume_clkscaling(hba); ufshcd_vreg_set_hpm(hba); Loading Loading @@ -7688,7 +7696,7 @@ static int ufshcd_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op) ufshcd_hba_vreg_set_hpm(hba); /* Make sure clocks are enabled before accessing controller */ ret = ufshcd_setup_clocks(hba, true); ret = ufshcd_enable_clocks(hba); if (ret) goto out; Loading Loading @@ -7764,7 +7772,7 @@ disable_vreg: disable_irq_and_vops_clks: ufshcd_disable_irq(hba); ufshcd_suspend_clkscaling(hba); ufshcd_setup_clocks(hba, false); ufshcd_disable_clocks(hba, false); out: hba->pm_op_in_progress = 0; Loading
drivers/scsi/ufs/ufshcd.h +7 −3 Original line number Diff line number Diff line Loading @@ -313,7 +313,7 @@ struct ufs_hba_variant_ops { void (*exit)(struct ufs_hba *); u32 (*get_ufs_hci_version)(struct ufs_hba *); int (*clk_scale_notify)(struct ufs_hba *, bool, bool); int (*setup_clocks)(struct ufs_hba *, bool); int (*setup_clocks)(struct ufs_hba *, bool, bool); int (*setup_regulators)(struct ufs_hba *, bool); int (*hce_enable_notify)(struct ufs_hba *, enum ufs_notify_change_status); Loading Loading @@ -840,6 +840,9 @@ struct ufs_hba { bool is_urgent_bkops_lvl_checked; struct rw_semaphore clk_scaling_lock; /* If set, don't gate device ref_clk during clock gating */ bool no_ref_clk_gating; }; /* Returns true if clocks can be gated. Otherwise false */ Loading Loading @@ -1070,10 +1073,11 @@ static inline int ufshcd_vops_clk_scale_notify(struct ufs_hba *hba, return 0; } static inline int ufshcd_vops_setup_clocks(struct ufs_hba *hba, bool on) static inline int ufshcd_vops_setup_clocks(struct ufs_hba *hba, bool on, bool is_gating_context) { if (hba->var && hba->var->vops && hba->var->vops->setup_clocks) return hba->var->vops->setup_clocks(hba, on); return hba->var->vops->setup_clocks(hba, on, is_gating_context); return 0; } Loading