scsi: ufs: Add quirk to fix mishandling utrlclr/utmrlclr
authorAlim Akhtar <alim.akhtar@samsung.com>
Thu, 28 May 2020 01:16:49 +0000 (06:46 +0530)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 26 Aug 2020 09:49:14 +0000 (11:49 +0200)
[ Upstream commit 871838412adf533ffda0b4a0ede0c2984e3511e7 ]

With the correct behavior, setting the bit to '0' indicates clear and '1'
indicates no change. If host controller handles this the other way around,
UFSHCI_QUIRK_BROKEN_REQ_LIST_CLR can be used.

Link: https://lore.kernel.org/r/20200528011658.71590-2-alim.akhtar@samsung.com
Reviewed-by: Can Guo <cang@codeaurora.org>
Reviewed-by: Avri Altman <avri.altman@wdc.com>
Signed-off-by: Seungwon Jeon <essuuj@gmail.com>
Signed-off-by: Alim Akhtar <alim.akhtar@samsung.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/scsi/ufs/ufshcd.c
drivers/scsi/ufs/ufshcd.h

index dec56e99335f03e0885aad2e56ddb3f11fb581f0..9da44a389becb70fcd4d805d37604e952b0cf090 100644 (file)
@@ -674,7 +674,11 @@ static inline int ufshcd_get_tr_ocs(struct ufshcd_lrb *lrbp)
  */
 static inline void ufshcd_utrl_clear(struct ufs_hba *hba, u32 pos)
 {
-       ufshcd_writel(hba, ~(1 << pos), REG_UTP_TRANSFER_REQ_LIST_CLEAR);
+       if (hba->quirks & UFSHCI_QUIRK_BROKEN_REQ_LIST_CLR)
+               ufshcd_writel(hba, (1 << pos), REG_UTP_TRANSFER_REQ_LIST_CLEAR);
+       else
+               ufshcd_writel(hba, ~(1 << pos),
+                               REG_UTP_TRANSFER_REQ_LIST_CLEAR);
 }
 
 /**
@@ -684,7 +688,10 @@ static inline void ufshcd_utrl_clear(struct ufs_hba *hba, u32 pos)
  */
 static inline void ufshcd_utmrl_clear(struct ufs_hba *hba, u32 pos)
 {
-       ufshcd_writel(hba, ~(1 << pos), REG_UTP_TASK_REQ_LIST_CLEAR);
+       if (hba->quirks & UFSHCI_QUIRK_BROKEN_REQ_LIST_CLR)
+               ufshcd_writel(hba, (1 << pos), REG_UTP_TASK_REQ_LIST_CLEAR);
+       else
+               ufshcd_writel(hba, ~(1 << pos), REG_UTP_TASK_REQ_LIST_CLEAR);
 }
 
 /**
index 16187be98a94c7f90005042410ecbd9065326e45..2ddf4c2f76f55e5c9b6d5156dc7832288c548b37 100644 (file)
@@ -520,6 +520,11 @@ enum ufshcd_quirks {
         * ops (get_ufs_hci_version) to get the correct version.
         */
        UFSHCD_QUIRK_BROKEN_UFS_HCI_VERSION             = 1 << 5,
+
+       /*
+        * Clear handling for transfer/task request list is just opposite.
+        */
+       UFSHCI_QUIRK_BROKEN_REQ_LIST_CLR                = 1 << 6,
 };
 
 enum ufshcd_caps {