Loading drivers/scsi/ufs/ufshcd.c +33 −10 Original line number Diff line number Diff line Loading @@ -8904,6 +8904,35 @@ static inline void ufshcd_add_sysfs_nodes(struct ufs_hba *hba) ufshcd_add_spm_lvl_sysfs_nodes(hba); } static void ufshcd_shutdown_clkscaling(struct ufs_hba *hba) { bool suspend = false; unsigned long flags; spin_lock_irqsave(hba->host->host_lock, flags); if (hba->clk_scaling.is_allowed) { hba->clk_scaling.is_allowed = false; suspend = true; } spin_unlock_irqrestore(hba->host->host_lock, flags); /** * Scaling may be scheduled before, hence make sure it * doesn't race with shutdown */ if (ufshcd_is_clkscaling_supported(hba)) { device_remove_file(hba->dev, &hba->clk_scaling.enable_attr); cancel_work_sync(&hba->clk_scaling.suspend_work); cancel_work_sync(&hba->clk_scaling.resume_work); if (suspend) ufshcd_suspend_clkscaling(hba); } /* Unregister so that devfreq_monitor can't race with shutdown */ if (hba->devfreq) devfreq_remove_device(hba->devfreq); } /** * ufshcd_shutdown - shutdown routine * @hba: per adapter instance Loading @@ -8921,16 +8950,14 @@ int ufshcd_shutdown(struct ufs_hba *hba) pm_runtime_get_sync(hba->dev); ufshcd_hold_all(hba); ufshcd_mark_shutdown_ongoing(hba); ufshcd_shutdown_clkscaling(hba); /** * (1) Set state to shutting down * (2) Acquire the lock to stop any more requests * (3) Suspend clock scaling * (4) Wait for all issued requests to complete * (1) Acquire the lock to stop any more requests * (2) Wait for all issued requests to complete */ ufshcd_mark_shutdown_ongoing(hba); ufshcd_get_write_lock(hba); ufshcd_scsi_block_requests(hba); ufshcd_suspend_clkscaling(hba); ret = ufshcd_wait_for_doorbell_clr(hba, U64_MAX); if (ret) dev_err(hba->dev, "%s: waiting for DB clear: failed: %d\n", Loading Loading @@ -9373,10 +9400,6 @@ static void ufshcd_clk_scaling_resume_work(struct work_struct *work) clk_scaling.resume_work); unsigned long irq_flags; /* Let's not resume scaling if shutdown is ongoing */ if (ufshcd_is_shutdown_ongoing(hba)) return; spin_lock_irqsave(hba->host->host_lock, irq_flags); if (!hba->clk_scaling.is_suspended) { spin_unlock_irqrestore(hba->host->host_lock, irq_flags); Loading Loading
drivers/scsi/ufs/ufshcd.c +33 −10 Original line number Diff line number Diff line Loading @@ -8904,6 +8904,35 @@ static inline void ufshcd_add_sysfs_nodes(struct ufs_hba *hba) ufshcd_add_spm_lvl_sysfs_nodes(hba); } static void ufshcd_shutdown_clkscaling(struct ufs_hba *hba) { bool suspend = false; unsigned long flags; spin_lock_irqsave(hba->host->host_lock, flags); if (hba->clk_scaling.is_allowed) { hba->clk_scaling.is_allowed = false; suspend = true; } spin_unlock_irqrestore(hba->host->host_lock, flags); /** * Scaling may be scheduled before, hence make sure it * doesn't race with shutdown */ if (ufshcd_is_clkscaling_supported(hba)) { device_remove_file(hba->dev, &hba->clk_scaling.enable_attr); cancel_work_sync(&hba->clk_scaling.suspend_work); cancel_work_sync(&hba->clk_scaling.resume_work); if (suspend) ufshcd_suspend_clkscaling(hba); } /* Unregister so that devfreq_monitor can't race with shutdown */ if (hba->devfreq) devfreq_remove_device(hba->devfreq); } /** * ufshcd_shutdown - shutdown routine * @hba: per adapter instance Loading @@ -8921,16 +8950,14 @@ int ufshcd_shutdown(struct ufs_hba *hba) pm_runtime_get_sync(hba->dev); ufshcd_hold_all(hba); ufshcd_mark_shutdown_ongoing(hba); ufshcd_shutdown_clkscaling(hba); /** * (1) Set state to shutting down * (2) Acquire the lock to stop any more requests * (3) Suspend clock scaling * (4) Wait for all issued requests to complete * (1) Acquire the lock to stop any more requests * (2) Wait for all issued requests to complete */ ufshcd_mark_shutdown_ongoing(hba); ufshcd_get_write_lock(hba); ufshcd_scsi_block_requests(hba); ufshcd_suspend_clkscaling(hba); ret = ufshcd_wait_for_doorbell_clr(hba, U64_MAX); if (ret) dev_err(hba->dev, "%s: waiting for DB clear: failed: %d\n", Loading Loading @@ -9373,10 +9400,6 @@ static void ufshcd_clk_scaling_resume_work(struct work_struct *work) clk_scaling.resume_work); unsigned long irq_flags; /* Let's not resume scaling if shutdown is ongoing */ if (ufshcd_is_shutdown_ongoing(hba)) return; spin_lock_irqsave(hba->host->host_lock, irq_flags); if (!hba->clk_scaling.is_suspended) { spin_unlock_irqrestore(hba->host->host_lock, irq_flags); Loading