summaryrefslogtreecommitdiff
path: root/drivers/scsi/ufs/ufshcd.c
diff options
context:
space:
mode:
authorSubhash Jadavani <subhashj@codeaurora.org>2015-12-21 18:34:01 -0800
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-22 11:00:51 -0700
commit885a77f0e84d256f08dec8ba07f9f318c395ee5e (patch)
tree0051729309fc68c88c65570828be3a3ea2df9eff /drivers/scsi/ufs/ufshcd.c
parent6de2bbe87eae57fdac702af842145d9d5677eafd (diff)
scsi: ufs: add checks before setting hibern8/clk-gating on idle states
"Hibern8 on idle" and "Clock gating on idle" features can be turned on/off selectively which means their state information is only important if that particular feature is enabled. This change makes sure that we only look at state of these features if feature itself is enabled. Change-Id: I25ef3d9dd60e69afe3f2d9dce602ae48f1b4a044 Signed-off-by: Subhash Jadavani <subhashj@codeaurora.org>
Diffstat (limited to 'drivers/scsi/ufs/ufshcd.c')
-rw-r--r--drivers/scsi/ufs/ufshcd.c29
1 files changed, 21 insertions, 8 deletions
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index ae9e5367c05e..740509c34b0a 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -1490,6 +1490,8 @@ static void ufshcd_init_clk_gating(struct ufs_hba *hba)
{
struct ufs_clk_gating *gating = &hba->clk_gating;
+ hba->clk_gating.state = CLKS_ON;
+
if (!ufshcd_is_clkgating_allowed(hba))
return;
@@ -2592,7 +2594,8 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
clear_bit_unlock(tag, &hba->lrb_in_use);
goto out;
}
- WARN_ON(hba->clk_gating.state != CLKS_ON);
+ if (ufshcd_is_clkgating_allowed(hba))
+ WARN_ON(hba->clk_gating.state != CLKS_ON);
err = ufshcd_hibern8_hold(hba, true);
if (err) {
@@ -2601,7 +2604,8 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
ufshcd_release(hba, true);
goto out;
}
- WARN_ON(hba->hibern8_on_idle.state != HIBERN8_EXITED);
+ if (ufshcd_is_hibern8_on_idle_allowed(hba))
+ WARN_ON(hba->hibern8_on_idle.state != HIBERN8_EXITED);
/* Vote PM QoS for the request */
ufshcd_vops_pm_qos_req_start(hba, cmd->request);
@@ -7900,7 +7904,8 @@ static int ufshcd_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op)
if (ret)
goto set_dev_active;
- if (ufshcd_is_link_hibern8(hba))
+ if (ufshcd_is_link_hibern8(hba) &&
+ ufshcd_is_hibern8_on_idle_allowed(hba))
hba->hibern8_on_idle.state = HIBERN8_ENTERED;
ufshcd_vreg_set_lpm(hba);
@@ -7923,8 +7928,11 @@ disable_clks:
if (ret)
goto set_link_active;
- hba->clk_gating.state = CLKS_OFF;
- trace_ufshcd_clk_gating(dev_name(hba->dev), hba->clk_gating.state);
+ if (ufshcd_is_clkgating_allowed(hba)) {
+ hba->clk_gating.state = CLKS_OFF;
+ trace_ufshcd_clk_gating(dev_name(hba->dev),
+ hba->clk_gating.state);
+ }
/*
* Disable the host irq as host controller as there won't be any
* host controller transaction expected till resume.
@@ -8006,7 +8014,8 @@ static int ufshcd_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op)
ret = ufshcd_uic_hibern8_exit(hba);
if (!ret) {
ufshcd_set_link_active(hba);
- hba->hibern8_on_idle.state = HIBERN8_EXITED;
+ if (ufshcd_is_hibern8_on_idle_allowed(hba))
+ hba->hibern8_on_idle.state = HIBERN8_EXITED;
} else {
goto vendor_suspend;
}
@@ -8019,7 +8028,8 @@ static int ufshcd_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op)
if (ret || !ufshcd_is_link_active(hba))
goto vendor_suspend;
/* mark link state as hibern8 exited */
- hba->hibern8_on_idle.state = HIBERN8_EXITED;
+ if (ufshcd_is_hibern8_on_idle_allowed(hba))
+ hba->hibern8_on_idle.state = HIBERN8_EXITED;
}
if (!ufshcd_is_ufs_dev_active(hba)) {
@@ -8049,7 +8059,8 @@ static int ufshcd_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op)
set_old_link_state:
ufshcd_link_state_transition(hba, old_link_state, 0);
- if (ufshcd_is_link_hibern8(hba))
+ if (ufshcd_is_link_hibern8(hba) &&
+ ufshcd_is_hibern8_on_idle_allowed(hba))
hba->hibern8_on_idle.state = HIBERN8_ENTERED;
vendor_suspend:
ufshcd_vops_suspend(hba, pm_op);
@@ -8060,6 +8071,8 @@ disable_irq_and_vops_clks:
if (hba->clk_scaling.is_allowed)
ufshcd_suspend_clkscaling(hba);
ufshcd_disable_clocks(hba, false);
+ if (ufshcd_is_clkgating_allowed(hba))
+ hba->clk_gating.state = CLKS_OFF;
out:
hba->pm_op_in_progress = 0;