OSDN Git Service

scsi: ufs: move dme peer quirk handling to ufshcd_dme_get_attr()
authorSubhash Jadavani <subhashj@codeaurora.org>
Thu, 25 Sep 2014 21:23:18 +0000 (14:23 -0700)
committerDavid Keitel <dkeitel@codeaurora.org>
Tue, 22 Mar 2016 17:57:31 +0000 (10:57 -0700)
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: Subhash Jadavani <subhashj@codeaurora.org>
[venkatg@codeaurora.org: resolved trivial merge conflicts]
Signed-off-by: Venkat Gopalakrishnan <venkatg@codeaurora.org>
drivers/scsi/ufs/debugfs.c
drivers/scsi/ufs/ufs-qcom.c

index 9cfb12c..50e23d0 100644 (file)
@@ -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;
+       else
+               return ufsdbg_dme_read(data, attr_val, true);
 }
 
 static int ufsdbg_dme_peer_set_attr_id(void *data, u64 attr_id)
index 036b0a7..ae206fd 100644 (file)
@@ -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;