From: Andrew Halaney ahalaney@redhat.com
stable inclusion from stable-v6.6.33 commit 8f01dda10c65652bb3c63831bb969d6f655c381a category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/IAD6H2
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=...
--------------------------------
[ Upstream commit c4d28e06b0c94636f6e35d003fa9ebac0a94e1ae ]
Currently, the reset bit for the UFS provided reset controller (used by its phy) is written to, and then a mb() happens to try and ensure that hit the device. Immediately afterwards a usleep_range() occurs.
mb() ensures that the write completes, but completion doesn't mean that it isn't stored in a buffer somewhere. The recommendation for ensuring this bit has taken effect on the device is to perform a read back to force it to make it all the way to the device. This is documented in device-io.rst and a talk by Will Deacon on this can be seen over here:
https://youtu.be/i6DayghhA8Q?si=MiyxB5cKJXSaoc01&t=1678
Let's do that to ensure the bit hits the device. By doing so and guaranteeing the ordering against the immediately following usleep_range(), the mb() can safely be removed.
Fixes: 81c0fc51b7a7 ("ufs-qcom: add support for Qualcomm Technologies Inc platforms") Reviewed-by: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org Reviewed-by: Can Guo quic_cang@quicinc.com Signed-off-by: Andrew Halaney ahalaney@redhat.com Link: https://lore.kernel.org/r/20240329-ufs-reset-ensure-effect-before-delay-v5-1... Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org Signed-off-by: Wang Hai wanghai38@huawei.com --- drivers/ufs/host/ufs-qcom.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/ufs/host/ufs-qcom.h b/drivers/ufs/host/ufs-qcom.h index d6f8e74bd538..532667d8e6f0 100644 --- a/drivers/ufs/host/ufs-qcom.h +++ b/drivers/ufs/host/ufs-qcom.h @@ -149,10 +149,10 @@ static inline void ufs_qcom_assert_reset(struct ufs_hba *hba) REG_UFS_CFG1);
/* - * Make sure assertion of ufs phy reset is written to - * register before returning + * Dummy read to ensure the write takes effect before doing any sort + * of delay */ - mb(); + ufshcd_readl(hba, REG_UFS_CFG1); }
static inline void ufs_qcom_deassert_reset(struct ufs_hba *hba) @@ -161,10 +161,10 @@ static inline void ufs_qcom_deassert_reset(struct ufs_hba *hba) REG_UFS_CFG1);
/* - * Make sure de-assertion of ufs phy reset is written to - * register before returning + * Dummy read to ensure the write takes effect before doing any sort + * of delay */ - mb(); + ufshcd_readl(hba, REG_UFS_CFG1); }
/* Host controller hardware version: major.minor.step */