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

Commit 0a811426 authored by Subhash Jadavani's avatar Subhash Jadavani Committed by David Keitel
Browse files

scsi: ufs: move dme peer quirk handling to ufshcd_dme_get_attr()



Some UFS host controllers may only allow accessing the peer DME attribute
in AUTO mode (FAST AUTO or SLOW AUTO) hence we had added a quirk for
switching to AUTO power mode before accessing the peer DME attribute.
But this quirk handling was only done in UFS driver's debugfs handling
hence this patch moves it to main driver ufshcd.c so that this quirk
handling is applied to all the peer DME accesses.

As we are doing this, this patch fixes 2 more related problem:
1. Current quirk was only handling the switch from FAST to FAST AUTO hence
this change adds the handling for SLOW to SLOW AUTO mode change as well.
2. ufsdbg_dme_read() helper function was always reading the local DME
attribute hence this change fix the same.

Change-Id: I475375fb57cd27cdafe1573c14d09dc7f9a2791b
Signed-off-by: default avatarSubhash Jadavani <subhashj@codeaurora.org>
[venkatg@codeaurora.org: resolved trivial merge conflicts]
Signed-off-by: default avatarVenkat Gopalakrishnan <venkatg@codeaurora.org>
parent 084930e1
Loading
Loading
Loading
Loading
+9 −31
Original line number Diff line number Diff line
@@ -42,6 +42,8 @@ struct desc_field_offset {
		}							\
	} while (0)

#define DOORBELL_CLR_TOUT_US	(1000 * 1000) /* 1 sec */

#ifdef CONFIG_UFS_FAULT_INJECTION

#define INJECT_COMMAND_HANG (0x0)
@@ -756,7 +758,6 @@ out:
static int ufsdbg_config_pwr_mode(struct ufs_hba *hba,
		struct ufs_pa_layer_attr *desired_pwr_mode)
{
	#define DOORBELL_CLR_TOUT_US	(1000 * 1000) /* 1 sec */
	int ret;

	pm_runtime_get_sync(hba->dev);
@@ -854,7 +855,11 @@ static int ufsdbg_dme_read(void *data, u64 *attr_val, bool peer)
	attr_id = peer ? hba->debugfs_files.dme_peer_attr_id :
			 hba->debugfs_files.dme_local_attr_id;
	pm_runtime_get_sync(hba->dev);
	ret = ufshcd_dme_get(hba, UIC_ARG_MIB(attr_id), &read_val);
	scsi_block_requests(hba->host);
	ret = ufshcd_wait_for_doorbell_clr(hba, DOORBELL_CLR_TOUT_US);
	if (!ret)
		ret = read_func(hba, UIC_ARG_MIB(attr_id), &read_val);
	scsi_unblock_requests(hba->host);
	pm_runtime_put_sync(hba->dev);

	if (!ret)
@@ -887,39 +892,12 @@ DEFINE_SIMPLE_ATTRIBUTE(ufsdbg_dme_local_read_ops,

static int ufsdbg_dme_peer_read(void *data, u64 *attr_val)
{
	int ret;
	struct ufs_hba *hba = data;
	struct ufs_pa_layer_attr orig_pwr_info;
	struct ufs_pa_layer_attr temp_pwr_info;
	bool restore_pwr_mode = false;

	if (!hba)
		return -EINVAL;

	if (hba->quirks & UFSHCD_QUIRK_DME_PEER_GET_FAST_MODE) {
		orig_pwr_info = hba->pwr_info;
		temp_pwr_info = orig_pwr_info;
		if (orig_pwr_info.pwr_tx == FAST_MODE ||
		    orig_pwr_info.pwr_rx == FAST_MODE) {
			temp_pwr_info.pwr_tx = FASTAUTO_MODE;
			temp_pwr_info.pwr_rx = FASTAUTO_MODE;
			ret = ufsdbg_config_pwr_mode(hba, &temp_pwr_info);
			if (ret)
				goto out;
	else
				restore_pwr_mode = true;
		}
	}

	ret = ufsdbg_dme_read(data, attr_val, true);

	if (hba->quirks & UFSHCD_QUIRK_DME_PEER_GET_FAST_MODE) {
		if (restore_pwr_mode)
			ufsdbg_config_pwr_mode(hba, &orig_pwr_info);
	}

out:
	return ret;
		return ufsdbg_dme_read(data, attr_val, true);
}

static int ufsdbg_dme_peer_set_attr_id(void *data, u64 attr_id)
+1 −1
Original line number Diff line number Diff line
@@ -768,7 +768,7 @@ static void ufs_qcom_advertise_quirks(struct ufs_hba *hba)
		hba->quirks |= (UFSHCD_QUIRK_DELAY_BEFORE_DME_CMDS
			      | UFSHCD_QUIRK_BROKEN_PA_RXHSUNTERMCAP
			      | UFSHCD_QUIRK_BROKEN_LCC
			      | UFSHCD_QUIRK_DME_PEER_GET_FAST_MODE);
			      | UFSHCD_QUIRK_DME_PEER_ACCESS_AUTO_MODE);

		if ((minor == 0x001) && (step == 0x0001))
			hba->quirks |= UFSHCD_QUIRK_BROKEN_INTR_AGGR;