diff options
Diffstat (limited to 'drivers/ufs')
-rw-r--r-- | drivers/ufs/core/ufshcd.c | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c index 0f08234def3f..1839e188a2c5 100644 --- a/drivers/ufs/core/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -7708,6 +7708,19 @@ static int ufshcd_eh_host_reset_handler(struct scsi_cmnd *cmd) hba = shost_priv(cmd->device->host); + /* + * If runtime PM sent SSU and got a timeout, scsi_error_handler is + * stuck in this function waiting for flush_work(&hba->eh_work). And + * ufshcd_err_handler(eh_work) is stuck waiting for runtime PM. Do + * ufshcd_link_recovery instead of eh_work to prevent deadlock. + */ + if (hba->pm_op_in_progress) { + if (ufshcd_link_recovery(hba)) + err = FAILED; + + return err; + } + spin_lock_irqsave(hba->host->host_lock, flags); hba->force_reset = true; ufshcd_schedule_eh_work(hba); |