aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsubhashj@codeaurora.org <subhashj@codeaurora.org>2017-04-04 15:32:20 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-04-12 06:41:19 -0400
commitc5fc946a15dc2da428f4cca19ed5be1ad20dff30 (patch)
tree328b16d6940b8b90be0bb2965b6656154ade5f9b
parenta17bddc4a78102ab55c7dbf76018b91e85694b07 (diff)
scsi: ufs: issue link starup 2 times if device isn't active
[ Upstream commit 7caf489b99a42a9017ef3d733912aea8794677e7 ] If we issue the link startup to the device while its UniPro state is LinkDown (and device state is sleep/power-down) then link startup will not move the device state to Active. Device will only move to active state if the link starup is issued when its UniPro state is LinkUp. So in this case, we would have to issue the link startup 2 times to make sure that device moves to active state. Reviewed-by: Gilad Broner <gbroner@codeaurora.org> Signed-off-by: Subhash Jadavani <subhashj@codeaurora.org> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> Signed-off-by: Sasha Levin <alexander.levin@verizon.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/scsi/ufs/ufshcd.c23
1 files changed, 20 insertions, 3 deletions
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 926b58b99811..edb06e466224 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -3130,7 +3130,16 @@ static int ufshcd_link_startup(struct ufs_hba *hba)
3130{ 3130{
3131 int ret; 3131 int ret;
3132 int retries = DME_LINKSTARTUP_RETRIES; 3132 int retries = DME_LINKSTARTUP_RETRIES;
3133 bool link_startup_again = false;
3133 3134
3135 /*
3136 * If UFS device isn't active then we will have to issue link startup
3137 * 2 times to make sure the device state move to active.
3138 */
3139 if (!ufshcd_is_ufs_dev_active(hba))
3140 link_startup_again = true;
3141
3142link_startup:
3134 do { 3143 do {
3135 ufshcd_vops_link_startup_notify(hba, PRE_CHANGE); 3144 ufshcd_vops_link_startup_notify(hba, PRE_CHANGE);
3136 3145
@@ -3156,6 +3165,12 @@ static int ufshcd_link_startup(struct ufs_hba *hba)
3156 /* failed to get the link up... retire */ 3165 /* failed to get the link up... retire */
3157 goto out; 3166 goto out;
3158 3167
3168 if (link_startup_again) {
3169 link_startup_again = false;
3170 retries = DME_LINKSTARTUP_RETRIES;
3171 goto link_startup;
3172 }
3173
3159 if (hba->quirks & UFSHCD_QUIRK_BROKEN_LCC) { 3174 if (hba->quirks & UFSHCD_QUIRK_BROKEN_LCC) {
3160 ret = ufshcd_disable_device_tx_lcc(hba); 3175 ret = ufshcd_disable_device_tx_lcc(hba);
3161 if (ret) 3176 if (ret)
@@ -6630,10 +6645,12 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)
6630 pm_runtime_get_sync(dev); 6645 pm_runtime_get_sync(dev);
6631 6646
6632 /* 6647 /*
6633 * The device-initialize-sequence hasn't been invoked yet. 6648 * We are assuming that device wasn't put in sleep/power-down
6634 * Set the device to power-off state 6649 * state exclusively during the boot stage before kernel.
6650 * This assumption helps avoid doing link startup twice during
6651 * ufshcd_probe_hba().
6635 */ 6652 */
6636 ufshcd_set_ufs_dev_poweroff(hba); 6653 ufshcd_set_ufs_dev_active(hba);
6637 6654
6638 async_schedule(ufshcd_async_scan, hba); 6655 async_schedule(ufshcd_async_scan, hba);
6639 6656