Commit 7bac6568 authored by Manivannan Sadhasivam's avatar Manivannan Sadhasivam Committed by Martin K. Petersen
Browse files

scsi: ufs: qcom: Power off the PHY if it was already powered on in ufs_qcom_power_up_sequence()



PHY might already be powered on during ufs_qcom_power_up_sequence() in a
couple of cases:

 1. During UFSHCD_QUIRK_REINIT_AFTER_MAX_GEAR_SWITCH quirk

 2. Resuming from spm_lvl = 5 suspend

In those cases, it is necessary to call phy_power_off() and phy_exit() in
ufs_qcom_power_up_sequence() function to power off the PHY before calling
phy_init() and phy_power_on().

Case (1) is doing it via ufs_qcom_reinit_notify() callback, but case (2) is
not handled. So to satisfy both cases, call phy_power_off() and phy_exit()
if the phy_count is non-zero. And with this change, the reinit_notify()
callback is no longer needed.

This fixes the below UFS resume failure with spm_lvl = 5:

ufshcd-qcom 1d84000.ufshc: Enabling the controller failed
ufshcd-qcom 1d84000.ufshc: Enabling the controller failed
ufshcd-qcom 1d84000.ufshc: Enabling the controller failed
ufshcd-qcom 1d84000.ufshc: ufshcd_host_reset_and_restore: Host init failed -5
ufshcd-qcom 1d84000.ufshc: Enabling the controller failed
ufshcd-qcom 1d84000.ufshc: Enabling the controller failed
ufshcd-qcom 1d84000.ufshc: Enabling the controller failed
ufshcd-qcom 1d84000.ufshc: ufshcd_host_reset_and_restore: Host init failed -5
ufshcd-qcom 1d84000.ufshc: Enabling the controller failed
ufshcd-qcom 1d84000.ufshc: Enabling the controller failed
ufshcd-qcom 1d84000.ufshc: Enabling the controller failed
ufshcd-qcom 1d84000.ufshc: ufshcd_host_reset_and_restore: Host init failed -5
ufshcd-qcom 1d84000.ufshc: Enabling the controller failed
ufshcd-qcom 1d84000.ufshc: Enabling the controller failed
ufshcd-qcom 1d84000.ufshc: Enabling the controller failed
ufshcd-qcom 1d84000.ufshc: ufshcd_host_reset_and_restore: Host init failed -5
ufshcd-qcom 1d84000.ufshc: Enabling the controller failed
ufshcd-qcom 1d84000.ufshc: Enabling the controller failed
ufshcd-qcom 1d84000.ufshc: Enabling the controller failed
ufshcd-qcom 1d84000.ufshc: ufshcd_host_reset_and_restore: Host init failed -5
ufs_device_wlun 0:0:0:49488: ufshcd_wl_resume failed: -5
ufs_device_wlun 0:0:0:49488: PM: dpm_run_callback(): scsi_bus_resume returns -5
ufs_device_wlun 0:0:0:49488: PM: failed to resume async: error -5

Cc: stable@vger.kernel.org # 6.3
Fixes: baf5ddac ("scsi: ufs: ufs-qcom: Add support for reinitializing the UFS device")
Reported-by: default avatarRam Kumar Dwivedi <quic_rdwivedi@quicinc.com>
Tested-by: Amit Pundir <amit.pundir@linaro.org> # on SM8550-HDK
Reviewed-by: default avatarBart Van Assche <bvanassche@acm.org>
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-QRD
Signed-off-by: default avatarManivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Link: https://lore.kernel.org/r/20241219-ufs-qcom-suspend-fix-v3-1-63c4b95a70b9@linaro.org


Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent f103396a
Loading
Loading
Loading
Loading
+0 −6
Original line number Diff line number Diff line
@@ -237,12 +237,6 @@ static inline void ufshcd_vops_config_scaling_param(struct ufs_hba *hba,
		hba->vops->config_scaling_param(hba, p, data);
}

static inline void ufshcd_vops_reinit_notify(struct ufs_hba *hba)
{
	if (hba->vops && hba->vops->reinit_notify)
		hba->vops->reinit_notify(hba);
}

static inline int ufshcd_vops_mcq_config_resource(struct ufs_hba *hba)
{
	if (hba->vops && hba->vops->mcq_config_resource)
+0 −1
Original line number Diff line number Diff line
@@ -8858,7 +8858,6 @@ static int ufshcd_probe_hba(struct ufs_hba *hba, bool init_dev_params)
		ufshcd_device_reset(hba);
		ufs_put_device_desc(hba);
		ufshcd_hba_stop(hba);
		ufshcd_vops_reinit_notify(hba);
		ret = ufshcd_hba_enable(hba);
		if (ret) {
			dev_err(hba->dev, "Host controller enable failed\n");
+5 −8
Original line number Diff line number Diff line
@@ -368,6 +368,11 @@ static int ufs_qcom_power_up_sequence(struct ufs_hba *hba)
	if (ret)
		return ret;

	if (phy->power_count) {
		phy_power_off(phy);
		phy_exit(phy);
	}

	/* phy initialization - calibrate the phy */
	ret = phy_init(phy);
	if (ret) {
@@ -1579,13 +1584,6 @@ static void ufs_qcom_config_scaling_param(struct ufs_hba *hba,
}
#endif

static void ufs_qcom_reinit_notify(struct ufs_hba *hba)
{
	struct ufs_qcom_host *host = ufshcd_get_variant(hba);

	phy_power_off(host->generic_phy);
}

/* Resources */
static const struct ufshcd_res_info ufs_res_info[RES_MAX] = {
	{.name = "ufs_mem",},
@@ -1825,7 +1823,6 @@ static const struct ufs_hba_variant_ops ufs_hba_qcom_vops = {
	.device_reset		= ufs_qcom_device_reset,
	.config_scaling_param = ufs_qcom_config_scaling_param,
	.program_key		= ufs_qcom_ice_program_key,
	.reinit_notify		= ufs_qcom_reinit_notify,
	.mcq_config_resource	= ufs_qcom_mcq_config_resource,
	.get_hba_mac		= ufs_qcom_get_hba_mac,
	.op_runtime_config	= ufs_qcom_op_runtime_config,
+0 −2
Original line number Diff line number Diff line
@@ -329,7 +329,6 @@ struct ufs_pwr_mode_info {
 * @program_key: program or evict an inline encryption key
 * @fill_crypto_prdt: initialize crypto-related fields in the PRDT
 * @event_notify: called to notify important events
 * @reinit_notify: called to notify reinit of UFSHCD during max gear switch
 * @mcq_config_resource: called to configure MCQ platform resources
 * @get_hba_mac: reports maximum number of outstanding commands supported by
 *	the controller. Should be implemented for UFSHCI 4.0 or later
@@ -381,7 +380,6 @@ struct ufs_hba_variant_ops {
				    void *prdt, unsigned int num_segments);
	void	(*event_notify)(struct ufs_hba *hba,
				enum ufs_event_type evt, void *data);
	void	(*reinit_notify)(struct ufs_hba *);
	int	(*mcq_config_resource)(struct ufs_hba *hba);
	int	(*get_hba_mac)(struct ufs_hba *hba);
	int	(*op_runtime_config)(struct ufs_hba *hba);