mirror of
https://github.com/torvalds/linux.git
synced 2026-11-06 21:58:01 +01:00
scsi: ufs: host: mediatek: Disable auto-hibern8 during power mode changes
Disable auto-hibern8 during power mode transitions to prevent unintended entry into auto-hibern8. Restore the original auto-hibern8 timer value after completing the power mode change to maintain system stability and prevent potential issues during power state transitions. Signed-off-by: Peter Wang <peter.wang@mediatek.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
c73cd5e298
commit
f5ca8d0c7a
|
|
@ -1429,19 +1429,49 @@ static int ufs_mtk_pre_pwr_change(struct ufs_hba *hba,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ufs_mtk_auto_hibern8_disable(struct ufs_hba *hba)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* disable auto-hibern8 */
|
||||||
|
ufshcd_writel(hba, 0, REG_AUTO_HIBERNATE_IDLE_TIMER);
|
||||||
|
|
||||||
|
/* wait host return to idle state when auto-hibern8 off */
|
||||||
|
ufs_mtk_wait_idle_state(hba, 5);
|
||||||
|
|
||||||
|
ret = ufs_mtk_wait_link_state(hba, VS_LINK_UP, 100);
|
||||||
|
if (ret) {
|
||||||
|
dev_warn(hba->dev, "exit h8 state fail, ret=%d\n", ret);
|
||||||
|
|
||||||
|
ufshcd_force_error_recovery(hba);
|
||||||
|
|
||||||
|
/* trigger error handler and break suspend */
|
||||||
|
ret = -EBUSY;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static int ufs_mtk_pwr_change_notify(struct ufs_hba *hba,
|
static int ufs_mtk_pwr_change_notify(struct ufs_hba *hba,
|
||||||
enum ufs_notify_change_status stage,
|
enum ufs_notify_change_status stage,
|
||||||
const struct ufs_pa_layer_attr *dev_max_params,
|
const struct ufs_pa_layer_attr *dev_max_params,
|
||||||
struct ufs_pa_layer_attr *dev_req_params)
|
struct ufs_pa_layer_attr *dev_req_params)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
static u32 reg;
|
||||||
|
|
||||||
switch (stage) {
|
switch (stage) {
|
||||||
case PRE_CHANGE:
|
case PRE_CHANGE:
|
||||||
|
if (ufshcd_is_auto_hibern8_supported(hba)) {
|
||||||
|
reg = ufshcd_readl(hba, REG_AUTO_HIBERNATE_IDLE_TIMER);
|
||||||
|
ufs_mtk_auto_hibern8_disable(hba);
|
||||||
|
}
|
||||||
ret = ufs_mtk_pre_pwr_change(hba, dev_max_params,
|
ret = ufs_mtk_pre_pwr_change(hba, dev_max_params,
|
||||||
dev_req_params);
|
dev_req_params);
|
||||||
break;
|
break;
|
||||||
case POST_CHANGE:
|
case POST_CHANGE:
|
||||||
|
if (ufshcd_is_auto_hibern8_supported(hba))
|
||||||
|
ufshcd_writel(hba, reg, REG_AUTO_HIBERNATE_IDLE_TIMER);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
|
|
@ -1686,29 +1716,6 @@ static void ufs_mtk_dev_vreg_set_lpm(struct ufs_hba *hba, bool lpm)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ufs_mtk_auto_hibern8_disable(struct ufs_hba *hba)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
/* disable auto-hibern8 */
|
|
||||||
ufshcd_writel(hba, 0, REG_AUTO_HIBERNATE_IDLE_TIMER);
|
|
||||||
|
|
||||||
/* wait host return to idle state when auto-hibern8 off */
|
|
||||||
ufs_mtk_wait_idle_state(hba, 5);
|
|
||||||
|
|
||||||
ret = ufs_mtk_wait_link_state(hba, VS_LINK_UP, 100);
|
|
||||||
if (ret) {
|
|
||||||
dev_warn(hba->dev, "exit h8 state fail, ret=%d\n", ret);
|
|
||||||
|
|
||||||
ufshcd_force_error_recovery(hba);
|
|
||||||
|
|
||||||
/* trigger error handler and break suspend */
|
|
||||||
ret = -EBUSY;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ufs_mtk_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op,
|
static int ufs_mtk_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op,
|
||||||
enum ufs_notify_change_status status)
|
enum ufs_notify_change_status status)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user