scsi: ufs: ufshcd: fix possible unclocked register access
authorSubhash Jadavani <subhashj@codeaurora.org>
Thu, 3 May 2018 11:07:17 +0000 (16:37 +0530)
committerMartin K. Petersen <martin.petersen@oracle.com>
Fri, 18 May 2018 16:20:48 +0000 (12:20 -0400)
Vendor specific setup_clocks ops may depend on clocks managed by ufshcd
driver so if the vendor specific setup_clocks callback is called when
the required clocks are turned off, it results into unclocked register
access.

This change make sure that required clocks are enabled before vendor
specific setup_clocks callback is called.

Signed-off-by: Subhash Jadavani <subhashj@codeaurora.org>
Signed-off-by: Venkat Gopalakrishnan <venkatg@codeaurora.org>
Signed-off-by: Can Guo <cang@codeaurora.org>
Signed-off-by: Asutosh Das <asutoshd@codeaurora.org>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/ufs/ufshcd.c

index 4dc4880..7959193 100644 (file)
@@ -6912,9 +6912,16 @@ static int __ufshcd_setup_clocks(struct ufs_hba *hba, bool on,
        if (list_empty(head))
                goto out;
 
-       ret = ufshcd_vops_setup_clocks(hba, on, PRE_CHANGE);
-       if (ret)
-               return ret;
+       /*
+        * vendor specific setup_clocks ops may depend on clocks managed by
+        * this standard driver hence call the vendor specific setup_clocks
+        * before disabling the clocks managed here.
+        */
+       if (!on) {
+               ret = ufshcd_vops_setup_clocks(hba, on, PRE_CHANGE);
+               if (ret)
+                       return ret;
+       }
 
        list_for_each_entry(clki, head, list) {
                if (!IS_ERR_OR_NULL(clki->clk)) {
@@ -6938,9 +6945,16 @@ static int __ufshcd_setup_clocks(struct ufs_hba *hba, bool on,
                }
        }
 
-       ret = ufshcd_vops_setup_clocks(hba, on, POST_CHANGE);
-       if (ret)
-               return ret;
+       /*
+        * vendor specific setup_clocks ops may depend on clocks managed by
+        * this standard driver hence call the vendor specific setup_clocks
+        * after enabling the clocks managed here.
+        */
+       if (on) {
+               ret = ufshcd_vops_setup_clocks(hba, on, POST_CHANGE);
+               if (ret)
+                       return ret;
+       }
 
 out:
        if (ret) {