From 40e137af23a6533e8fcd01a6ab0ddbbb7993a637 Mon Sep 17 00:00:00 2001 From: hgchu Date: Fri, 12 Jan 2018 12:43:34 +0900 Subject: [PATCH] scsi: ufs: prevent i/o request during recovery-seq Change-Id: I658dd2d95dcda721a9cd8ee8af50968975adc718 Signed-off-by: hgchu --- drivers/scsi/ufs/ufshcd.c | 19 +++++++++++++++++++ drivers/scsi/ufs/ufshcd.h | 1 + 2 files changed, 20 insertions(+) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 1e06f3d25c76..01c706d4deae 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -1479,6 +1479,10 @@ int ufshcd_hold(struct ufs_hba *hba, bool async) start: switch (hba->clk_gating.state) { + case __CLKS_ON: + rc = -EAGAIN; + if (async) + hba->clk_gating.active_reqs--; case CLKS_ON: /* * Wait for the ungate work to complete if in progress. @@ -1581,7 +1585,9 @@ static void ufshcd_gate_work(struct work_struct *work) spin_unlock_irqrestore(hba->host->host_lock, flags); hba->clk_gating.is_suspended = true; ufshcd_reset_and_restore(hba); + spin_lock_irqsave(hba->host->host_lock, flags); hba->clk_gating.state = CLKS_ON; + spin_unlock_irqrestore(hba->host->host_lock, flags); hba->clk_gating.is_suspended = false; trace_ufshcd_clk_gating(dev_name(hba->dev), hba->clk_gating.state); @@ -7313,7 +7319,20 @@ static int ufshcd_link_state_transition(struct ufs_hba *hba, if (!ret) ufshcd_set_link_hibern8(hba); else { + unsigned long flags; + bool saved_is_suspended = hba->clk_gating.is_suspended; + + spin_lock_irqsave(hba->host->host_lock, flags); + hba->clk_gating.state = __CLKS_ON; + spin_unlock_irqrestore(hba->host->host_lock, flags); + + hba->clk_gating.is_suspended = true; ufshcd_host_reset_and_restore(hba); + spin_lock_irqsave(hba->host->host_lock, flags); + hba->clk_gating.state = CLKS_ON; + spin_unlock_irqrestore(hba->host->host_lock, flags); + hba->clk_gating.is_suspended = saved_is_suspended; + goto out; } /* diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index abe402788a43..00930bc7984c 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -345,6 +345,7 @@ enum clk_gating_state { CLKS_ON, REQ_CLKS_OFF, REQ_CLKS_ON, + __CLKS_ON, }; /** -- 2.20.1