diff options
| author | Bhupesh Sharma <[email protected]> | 2024-09-30 14:44:32 +0200 |
|---|---|---|
| committer | Neil Armstrong <[email protected]> | 2024-10-14 08:55:28 +0200 |
| commit | 5ce1a2c7de4936d19cbc0307be734aed9f8056a4 (patch) | |
| tree | 64ffc1281577db82f0359d8e96d3eba1d15f8614 /drivers | |
| parent | 00c54af3addfc1475525396ec707c0c799010197 (diff) | |
ufs: Add missing memory barriers
Add missing wmb() and mb() barriers in the u-boot UFS core
framework driver to allow registers updates to happen before
follow-up read operations.
This makes the barrier placement similar to the Linux UFS driver,
synced from the Linux v6.9 release.
Starting from the v6.10 release, the barriers were replaced with a register
read-back in [1], this will ported to u-boot in a second time.
[1] https://lore.kernel.org/all/20240329-ufs-reset-ensure-effect-before-delay-v5-0-181252004586@redhat.com/
Signed-off-by: Bhupesh Sharma <[email protected]>
Tested-by: Venkatesh Yadav Abbarapu <[email protected]>
Tested-by: Julius Lehmann <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Neil Armstrong <[email protected]>
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/ufs/ufs.c | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/drivers/ufs/ufs.c b/drivers/ufs/ufs.c index 565a6af1404..5d4e5424358 100644 --- a/drivers/ufs/ufs.c +++ b/drivers/ufs/ufs.c @@ -433,6 +433,12 @@ static int ufshcd_make_hba_operational(struct ufs_hba *hba) REG_UTP_TASK_REQ_LIST_BASE_H); /* + * Make sure base address and interrupt setup are updated before + * enabling the run/stop registers below. + */ + wmb(); + + /* * UCRDY, UTMRLDY and UTRLRDY bits must be 1 */ reg = ufshcd_readl(hba, REG_CONTROLLER_STATUS); @@ -861,6 +867,9 @@ static int ufshcd_send_command(struct ufs_hba *hba, unsigned int task_tag) ufshcd_writel(hba, 1 << task_tag, REG_UTP_TRANSFER_REQ_DOOR_BELL); + /* Make sure doorbell reg is updated before reading interrupt status */ + wmb(); + start = get_timer(0); do { intr_status = ufshcd_readl(hba, REG_INTERRUPT_STATUS); @@ -1994,6 +2003,8 @@ int ufshcd_probe(struct udevice *ufs_dev, struct ufs_hba_ops *hba_ops) REG_INTERRUPT_STATUS); ufshcd_writel(hba, 0, REG_INTERRUPT_ENABLE); + mb(); + err = ufshcd_hba_enable(hba); if (err) { dev_err(hba->dev, "Host controller enable failed\n"); |
