Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 09f39537 authored by Stanley Chu's avatar Stanley Chu Committed by Todd Kjos
Browse files

UPSTREAM: scsi: ufs: Introduce device quirk "DELAY_AFTER_LPM"

Some UFS devices require delay after VCC power rail is turned off.
Introduce a device quirk "DELAY_AFTER_LPM" to add 5ms delay after VCC
power-off during suspend flow.

Link: https://lore.kernel.org/r/20200729051840.31318-2-stanley.chu@mediatek.com


Reviewed-by: default avatarAndy Teng <andy.teng@mediatek.com>
Reviewed-by: default avatarPeter Wang <peter.wang@mediatek.com>
Reviewed-by: default avatarCan Guo <cang@codeaurora.org>
Acked-by: default avatarAvri Altman <Avri.Altman@wdc.com>
Signed-off-by: default avatarStanley Chu <stanley.chu@mediatek.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>

Bug: 166747994
(cherry picked from commit c4df6eed972e001a206a173738bec8c5f903257a)
Change-Id: Ia5c26f454374dfb591480acbf83007749ba11a0c
Signed-off-by: default avatarStanley Chu <stanley.chu@mediatek.com>
parent 982976f5
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -109,4 +109,11 @@ struct ufs_dev_fix {
 */
#define UFS_DEVICE_QUIRK_SUPPORT_EXTENDED_FEATURES (1 << 10)

/*
 * Some UFS devices require delay after VCC power rail is turned-off.
 * Enable this quirk to introduce 5ms delays after VCC power-off during
 * suspend flow.
 */
#define UFS_DEVICE_QUIRK_DELAY_AFTER_LPM        (1 << 11)

#endif /* UFS_QUIRKS_H_ */
+11 −0
Original line number Diff line number Diff line
@@ -8428,6 +8428,8 @@ static int ufshcd_link_state_transition(struct ufs_hba *hba,

static void ufshcd_vreg_set_lpm(struct ufs_hba *hba)
{
	bool vcc_off = false;

	/*
	 * It seems some UFS devices may keep drawing more than sleep current
	 * (atleast for 500us) from UFS rails (especially from VCCQ rail).
@@ -8456,13 +8458,22 @@ static void ufshcd_vreg_set_lpm(struct ufs_hba *hba)
	if (ufshcd_is_ufs_dev_poweroff(hba) && ufshcd_is_link_off(hba) &&
	    !hba->dev_info.is_lu_power_on_wp) {
		ufshcd_setup_vreg(hba, false);
		vcc_off = true;
	} else if (!ufshcd_is_ufs_dev_active(hba)) {
		ufshcd_toggle_vreg(hba->dev, hba->vreg_info.vcc, false);
		vcc_off = true;
		if (!ufshcd_is_link_active(hba)) {
			ufshcd_config_vreg_lpm(hba, hba->vreg_info.vccq);
			ufshcd_config_vreg_lpm(hba, hba->vreg_info.vccq2);
		}
	}

	/*
	 * Some UFS devices require delay after VCC power rail is turned-off.
	 */
	if (vcc_off && hba->vreg_info.vcc &&
		hba->dev_quirks & UFS_DEVICE_QUIRK_DELAY_AFTER_LPM)
		usleep_range(5000, 5100);
}

static int ufshcd_vreg_set_hpm(struct ufs_hba *hba)