| From 8eecddfca30e1651dc1c74531ed5eef21dcce7e3 Mon Sep 17 00:00:00 2001 |
| From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> |
| Date: Wed, 4 May 2022 14:12:10 +0530 |
| Subject: scsi: ufs: qcom: Add a readl() to make sure ref_clk gets enabled |
| |
| From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> |
| |
| commit 8eecddfca30e1651dc1c74531ed5eef21dcce7e3 upstream. |
| |
| In ufs_qcom_dev_ref_clk_ctrl(), it was noted that the ref_clk needs to be |
| stable for at least 1us. Even though there is wmb() to make sure the write |
| gets "completed", there is no guarantee that the write actually reached the |
| UFS device. There is a good chance that the write could be stored in a |
| Write Buffer (WB). In that case, even though the CPU waits for 1us, the |
| ref_clk might not be stable for that period. |
| |
| So lets do a readl() to make sure that the previous write has reached the |
| UFS device before udelay(). |
| |
| Also, the wmb() after writel_relaxed() is not really needed. Both writel() |
| and readl() are ordered on all architectures and the CPU won't speculate |
| instructions after readl() due to the in-built control dependency with read |
| value on weakly ordered architectures. So it can be safely removed. |
| |
| Link: https://lore.kernel.org/r/20220504084212.11605-4-manivannan.sadhasivam@linaro.org |
| Fixes: f06fcc7155dc ("scsi: ufs-qcom: add QUniPro hardware support and power optimizations") |
| Cc: stable@vger.kernel.org |
| Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org> |
| Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> |
| Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/scsi/ufs/ufs-qcom.c | 7 +++++-- |
| 1 file changed, 5 insertions(+), 2 deletions(-) |
| |
| --- a/drivers/scsi/ufs/ufs-qcom.c |
| +++ b/drivers/scsi/ufs/ufs-qcom.c |
| @@ -915,8 +915,11 @@ static void ufs_qcom_dev_ref_clk_ctrl(st |
| |
| writel_relaxed(temp, host->dev_ref_clk_ctrl_mmio); |
| |
| - /* ensure that ref_clk is enabled/disabled before we return */ |
| - wmb(); |
| + /* |
| + * Make sure the write to ref_clk reaches the destination and |
| + * not stored in a Write Buffer (WB). |
| + */ |
| + readl(host->dev_ref_clk_ctrl_mmio); |
| |
| /* |
| * If we call hibern8 exit after this, we need to make sure that |