scsi: ufs: recover link state after entering hibernation fails
authorhgchu <hg.chu@samsung.com>
Fri, 12 Jan 2018 02:34:29 +0000 (11:34 +0900)
committerJaeHun Jung <jh0801.jung@samsung.com>
Tue, 8 May 2018 08:20:19 +0000 (17:20 +0900)
Change-Id: I9dccb778410033510e6e38ee399c93ce721a4a36
Signed-off-by: hgchu <hg.chu@samsung.com>
drivers/scsi/ufs/ufshcd.c

index 04c0e869f9203e9a460c85b9b76bf4989e10ecc0..1e06f3d25c76406c3f8b82563a964eb991d43d1b 100644 (file)
@@ -1430,7 +1430,9 @@ static void ufshcd_ungate_work(struct work_struct *work)
        if (gating_allowed) {
                ufshcd_setup_clocks(hba, true);
        } else {
+               spin_lock_irqsave(hba->host->host_lock, flags);
                hba->clk_gating.state = CLKS_ON;
+               spin_unlock_irqrestore(hba->host->host_lock, flags);
        }
 
        /* Exit from hibern8 */
@@ -1574,7 +1576,13 @@ static void ufshcd_gate_work(struct work_struct *work)
        if (ufshcd_can_hibern8_during_gating(hba)) {
                ufshcd_set_link_trans_hibern8(hba);
                if (ufshcd_link_hibern8_ctrl(hba, true)) {
+                       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_reset_and_restore(hba);
                        hba->clk_gating.state = CLKS_ON;
+                       hba->clk_gating.is_suspended = false;
                        trace_ufshcd_clk_gating(dev_name(hba->dev),
                                                hba->clk_gating.state);
                        goto out;
@@ -7305,6 +7313,7 @@ static int ufshcd_link_state_transition(struct ufs_hba *hba,
                if (!ret)
                        ufshcd_set_link_hibern8(hba);
                else {
+                       ufshcd_host_reset_and_restore(hba);
                        goto out;
        }
        /*