Loading drivers/scsi/ufs/ufshcd.c +34 −0 Original line number Diff line number Diff line Loading @@ -3168,6 +3168,8 @@ ufshcd_dispatch_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd) /* Write UIC Cmd */ ufshcd_writel(hba, uic_cmd->command & COMMAND_OPCODE_MASK, REG_UIC_COMMAND); /* Make sure that UIC command is committed immediately */ wmb(); } /** Loading Loading @@ -5110,6 +5112,7 @@ static int ufshcd_uic_pwr_ctrl(struct ufs_hba *hba, struct uic_command *cmd) u8 status; int ret; bool reenable_intr = false; int wait_retries = 6; /* Allows 3secs max wait time */ mutex_lock(&hba->uic_cmd_mutex); init_completion(&uic_async_done); Loading @@ -5136,11 +5139,42 @@ static int ufshcd_uic_pwr_ctrl(struct ufs_hba *hba, struct uic_command *cmd) goto out; } more_wait: if (!wait_for_completion_timeout(hba->uic_async_done, msecs_to_jiffies(UIC_CMD_TIMEOUT))) { u32 intr_status = 0; s64 ts_since_last_intr; dev_err(hba->dev, "pwr ctrl cmd 0x%x with mode 0x%x completion timeout\n", cmd->command, cmd->argument3); /* * The controller must have triggered interrupt but ISR couldn't * run due to interrupt starvation. * Or ISR must have executed just after the timeout * (which clears IS registers) * If either of these two cases is true, then * wait for little more time for completion. */ intr_status = ufshcd_readl(hba, REG_INTERRUPT_STATUS); ts_since_last_intr = ktime_ms_delta(ktime_get(), hba->ufs_stats.last_intr_ts); if ((intr_status & UFSHCD_UIC_PWR_MASK) || ((hba->ufs_stats.last_intr_status & UFSHCD_UIC_PWR_MASK) && (ts_since_last_intr < (s64)UIC_CMD_TIMEOUT))) { dev_info(hba->dev, "IS:0x%08x last_intr_sts:0x%08x last_intr_ts:%lld, retry-cnt:%d\n", intr_status, hba->ufs_stats.last_intr_status, hba->ufs_stats.last_intr_ts, wait_retries); if (wait_retries--) goto more_wait; /* * If same state continues event after more wait time, * something must be hogging CPU. */ BUG_ON(hba->crash_on_err); } ret = -ETIMEDOUT; goto out; } Loading Loading
drivers/scsi/ufs/ufshcd.c +34 −0 Original line number Diff line number Diff line Loading @@ -3168,6 +3168,8 @@ ufshcd_dispatch_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd) /* Write UIC Cmd */ ufshcd_writel(hba, uic_cmd->command & COMMAND_OPCODE_MASK, REG_UIC_COMMAND); /* Make sure that UIC command is committed immediately */ wmb(); } /** Loading Loading @@ -5110,6 +5112,7 @@ static int ufshcd_uic_pwr_ctrl(struct ufs_hba *hba, struct uic_command *cmd) u8 status; int ret; bool reenable_intr = false; int wait_retries = 6; /* Allows 3secs max wait time */ mutex_lock(&hba->uic_cmd_mutex); init_completion(&uic_async_done); Loading @@ -5136,11 +5139,42 @@ static int ufshcd_uic_pwr_ctrl(struct ufs_hba *hba, struct uic_command *cmd) goto out; } more_wait: if (!wait_for_completion_timeout(hba->uic_async_done, msecs_to_jiffies(UIC_CMD_TIMEOUT))) { u32 intr_status = 0; s64 ts_since_last_intr; dev_err(hba->dev, "pwr ctrl cmd 0x%x with mode 0x%x completion timeout\n", cmd->command, cmd->argument3); /* * The controller must have triggered interrupt but ISR couldn't * run due to interrupt starvation. * Or ISR must have executed just after the timeout * (which clears IS registers) * If either of these two cases is true, then * wait for little more time for completion. */ intr_status = ufshcd_readl(hba, REG_INTERRUPT_STATUS); ts_since_last_intr = ktime_ms_delta(ktime_get(), hba->ufs_stats.last_intr_ts); if ((intr_status & UFSHCD_UIC_PWR_MASK) || ((hba->ufs_stats.last_intr_status & UFSHCD_UIC_PWR_MASK) && (ts_since_last_intr < (s64)UIC_CMD_TIMEOUT))) { dev_info(hba->dev, "IS:0x%08x last_intr_sts:0x%08x last_intr_ts:%lld, retry-cnt:%d\n", intr_status, hba->ufs_stats.last_intr_status, hba->ufs_stats.last_intr_ts, wait_retries); if (wait_retries--) goto more_wait; /* * If same state continues event after more wait time, * something must be hogging CPU. */ BUG_ON(hba->crash_on_err); } ret = -ETIMEDOUT; goto out; } Loading