diff options
author | Bjorn Andersson <bjorn.andersson@linaro.org> | 2019-08-28 12:17:54 -0700 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2019-09-07 16:35:56 -0400 |
commit | d8d9f7931ac2698fc2b37d2db748c47122ee2a6f (patch) | |
tree | 8821c1805653144987f5d29e2b0bf9b935ee3d01 /drivers/scsi/ufs | |
parent | 4fb86a6bc549fc482bdb21086aa272668ed955d2 (diff) | |
download | linux-d8d9f7931ac2698fc2b37d2db748c47122ee2a6f.tar.gz linux-d8d9f7931ac2698fc2b37d2db748c47122ee2a6f.tar.bz2 linux-d8d9f7931ac2698fc2b37d2db748c47122ee2a6f.zip |
scsi: ufs: Introduce vops for resetting device
Some UFS memory devices needs their reset line toggled in order to get them
into a good state for initialization. Provide a new vops to allow the
platform driver to implement this operation.
Link: https://lore.kernel.org/r/20190828191756.24312-2-bjorn.andersson@linaro.org
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Reviewed-by: Alim Akhtar <alim.akhtar@samsung.com>
Reviewed-by: Bean Huo <beanhuo@micron.com>
Reviewed-by: Stanley Chu <stanley.chu@mediatek.com>
Acked-by: Avri Altman <Avri.Altman@wdc.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/ufs')
-rw-r--r-- | drivers/scsi/ufs/ufshcd.c | 6 | ||||
-rw-r--r-- | drivers/scsi/ufs/ufshcd.h | 8 |
2 files changed, 14 insertions, 0 deletions
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index ff6a440dc1c2..5c2eb4866044 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -6234,6 +6234,9 @@ static int ufshcd_reset_and_restore(struct ufs_hba *hba) int retries = MAX_HOST_RESET_RETRIES; do { + /* Reset the attached device */ + ufshcd_vops_device_reset(hba); + err = ufshcd_host_reset_and_restore(hba); } while (err && --retries); @@ -8367,6 +8370,9 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) goto exit_gating; } + /* Reset the attached device */ + ufshcd_vops_device_reset(hba); + /* Host controller enable */ err = ufshcd_hba_enable(hba); if (err) { diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 9f61550abc7f..c94cfda52829 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -298,6 +298,7 @@ struct ufs_pwr_mode_info { * @resume: called during host controller PM callback * @dbg_register_dump: used to dump controller debug information * @phy_initialization: used to initialize phys + * @device_reset: called to issue a reset pulse on the UFS device */ struct ufs_hba_variant_ops { const char *name; @@ -326,6 +327,7 @@ struct ufs_hba_variant_ops { int (*resume)(struct ufs_hba *, enum ufs_pm_op); void (*dbg_register_dump)(struct ufs_hba *hba); int (*phy_initialization)(struct ufs_hba *); + void (*device_reset)(struct ufs_hba *hba); }; /* clock gating state */ @@ -1070,6 +1072,12 @@ static inline void ufshcd_vops_dbg_register_dump(struct ufs_hba *hba) hba->vops->dbg_register_dump(hba); } +static inline void ufshcd_vops_device_reset(struct ufs_hba *hba) +{ + if (hba->vops && hba->vops->device_reset) + hba->vops->device_reset(hba); +} + extern struct ufs_pm_lvl_states ufs_pm_lvl_states[]; /* |