Commit 71d848b8 authored by Can Guo's avatar Can Guo Committed by Martin K. Petersen

scsi: ufs: Fix up auto hibern8 enablement

Fix up possible unclocked register access to auto hibern8 register in
resume path and through sysfs entry. Meanwhile, enable auto hibern8 only
after device is fully initialized in probe path.

Link: https://lore.kernel.org/r/1573798172-20534-4-git-send-email-cang@codeaurora.orgReviewed-by: default avatarStanley Chu <stanley.chu@mediatek.com>
Signed-off-by: default avatarCan Guo <cang@codeaurora.org>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 870b1279
...@@ -126,13 +126,16 @@ static void ufshcd_auto_hibern8_update(struct ufs_hba *hba, u32 ahit) ...@@ -126,13 +126,16 @@ static void ufshcd_auto_hibern8_update(struct ufs_hba *hba, u32 ahit)
return; return;
spin_lock_irqsave(hba->host->host_lock, flags); spin_lock_irqsave(hba->host->host_lock, flags);
if (hba->ahit == ahit) if (hba->ahit != ahit)
goto out_unlock; hba->ahit = ahit;
hba->ahit = ahit;
if (!pm_runtime_suspended(hba->dev))
ufshcd_writel(hba, hba->ahit, REG_AUTO_HIBERNATE_IDLE_TIMER);
out_unlock:
spin_unlock_irqrestore(hba->host->host_lock, flags); spin_unlock_irqrestore(hba->host->host_lock, flags);
if (!pm_runtime_suspended(hba->dev)) {
pm_runtime_get_sync(hba->dev);
ufshcd_hold(hba, false);
ufshcd_auto_hibern8_enable(hba);
ufshcd_release(hba);
pm_runtime_put(hba->dev);
}
} }
/* Convert Auto-Hibernate Idle Timer register value to microseconds */ /* Convert Auto-Hibernate Idle Timer register value to microseconds */
......
...@@ -3947,7 +3947,7 @@ static int ufshcd_uic_hibern8_exit(struct ufs_hba *hba) ...@@ -3947,7 +3947,7 @@ static int ufshcd_uic_hibern8_exit(struct ufs_hba *hba)
return ret; return ret;
} }
static void ufshcd_auto_hibern8_enable(struct ufs_hba *hba) void ufshcd_auto_hibern8_enable(struct ufs_hba *hba)
{ {
unsigned long flags; unsigned long flags;
...@@ -6884,9 +6884,6 @@ static int ufshcd_probe_hba(struct ufs_hba *hba) ...@@ -6884,9 +6884,6 @@ static int ufshcd_probe_hba(struct ufs_hba *hba)
/* UniPro link is active now */ /* UniPro link is active now */
ufshcd_set_link_active(hba); ufshcd_set_link_active(hba);
/* Enable Auto-Hibernate if configured */
ufshcd_auto_hibern8_enable(hba);
ret = ufshcd_verify_dev_init(hba); ret = ufshcd_verify_dev_init(hba);
if (ret) if (ret)
goto out; goto out;
...@@ -6937,6 +6934,9 @@ static int ufshcd_probe_hba(struct ufs_hba *hba) ...@@ -6937,6 +6934,9 @@ static int ufshcd_probe_hba(struct ufs_hba *hba)
/* set the state as operational after switching to desired gear */ /* set the state as operational after switching to desired gear */
hba->ufshcd_state = UFSHCD_STATE_OPERATIONAL; hba->ufshcd_state = UFSHCD_STATE_OPERATIONAL;
/* Enable Auto-Hibernate if configured */
ufshcd_auto_hibern8_enable(hba);
/* /*
* If we are in error handling context or in power management callbacks * If we are in error handling context or in power management callbacks
* context, no need to scan the host * context, no need to scan the host
...@@ -7954,12 +7954,12 @@ static int ufshcd_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op) ...@@ -7954,12 +7954,12 @@ static int ufshcd_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op)
if (hba->clk_scaling.is_allowed) if (hba->clk_scaling.is_allowed)
ufshcd_resume_clkscaling(hba); ufshcd_resume_clkscaling(hba);
/* Schedule clock gating in case of no access to UFS device yet */
ufshcd_release(hba);
/* Enable Auto-Hibernate if configured */ /* Enable Auto-Hibernate if configured */
ufshcd_auto_hibern8_enable(hba); ufshcd_auto_hibern8_enable(hba);
/* Schedule clock gating in case of no access to UFS device yet */
ufshcd_release(hba);
goto out; goto out;
set_old_link_state: set_old_link_state:
......
...@@ -926,6 +926,8 @@ int ufshcd_query_attr(struct ufs_hba *hba, enum query_opcode opcode, ...@@ -926,6 +926,8 @@ int ufshcd_query_attr(struct ufs_hba *hba, enum query_opcode opcode,
int ufshcd_query_flag(struct ufs_hba *hba, enum query_opcode opcode, int ufshcd_query_flag(struct ufs_hba *hba, enum query_opcode opcode,
enum flag_idn idn, bool *flag_res); enum flag_idn idn, bool *flag_res);
void ufshcd_auto_hibern8_enable(struct ufs_hba *hba);
#define SD_ASCII_STD true #define SD_ASCII_STD true
#define SD_RAW false #define SD_RAW false
int ufshcd_read_string_desc(struct ufs_hba *hba, u8 desc_index, int ufshcd_read_string_desc(struct ufs_hba *hba, u8 desc_index,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment