scsi: ufs: synchronize between rls handler and clock scaling

Fix race condition between rls handler thread and clock scaling thread when
LINERESET indication is sent out from host controller. A known scenario is
when clock scaling thread has put link to hibern8 after gear scaling down
is done, if rls handler thread, scheduled because of LINERESET indication
from controller, starts to run now to scale gear up (PWM to HS), it would
fail as the link state is still in hibern8 state. This change fixes this
race condition by using write semaphore to prevent rls handler thread and
clock scaling thread getting chance to run simultaneously.

Change-Id: Ia1731c921c42155cacb43029d56491ddffcf2ee2
Signed-off-by: Subhash Jadavani <subhashj@codeaurora.org>
Signed-off-by: Can Guo <cang@codeaurora.org>
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 02dfbcc..d250418 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -3,7 +3,7 @@
  *
  * This code is based on drivers/scsi/ufs/ufshcd.c
  * Copyright (C) 2011-2013 Samsung India Software Operations
- * Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
  *
  * Authors:
  *	Santosh Yaraganavi <santosh.sy@samsung.com>
@@ -6498,6 +6498,7 @@
 	hba = container_of(work, struct ufs_hba, rls_work);
 	ufshcd_scsi_block_requests(hba);
 	pm_runtime_get_sync(hba->dev);
+	down_write(&hba->lock);
 	ret = ufshcd_wait_for_doorbell_clr(hba, U64_MAX);
 	if (ret) {
 		dev_err(hba->dev,
@@ -6531,6 +6532,7 @@
 		hba->restore_needed = false;
 
 out:
+	up_write(&hba->lock);
 	ufshcd_scsi_unblock_requests(hba);
 	pm_runtime_put_sync(hba->dev);
 }