*/
static inline void ufshcd_utrl_clear(struct ufs_hba *hba, u32 pos)
{
- ufshcd_writel(hba, ~(1 << pos), REG_UTP_TRANSFER_REQ_LIST_CLEAR);
+ u32 clear;
+
+ if (hba->quirks & UFSHCD_QUIRK_BROKEN_REQ_LIST_CLR)
+ clear = (1 << pos);
+ else
+ clear = ~(1 << pos);
+
+ ufshcd_writel(hba, clear, REG_UTP_TRANSFER_REQ_LIST_CLEAR);
+}
+
+/**
+ * ufshcd_utmrl_clear - Clear a bit in UTRMLCLR register
+ * @hba: per adapter instance
+ * @pos: position of the bit to be cleared
+ */
+static inline void ufshcd_utmrl_clear(struct ufs_hba *hba, u32 pos)
+{
+ u32 clear;
+
+ if (hba->quirks & UFSHCD_QUIRK_BROKEN_REQ_LIST_CLR)
+ clear = (1 << pos);
+ else
+ clear = ~(1 << pos);
+
+ ufshcd_writel(hba, clear, REG_UTP_TASK_REQ_LIST_CLEAR);
}
/**
goto out;
spin_lock_irqsave(hba->host->host_lock, flags);
- ufshcd_writel(hba, ~(1 << tag), REG_UTP_TASK_REQ_LIST_CLEAR);
+ ufshcd_utmrl_clear(hba, tag);
spin_unlock_irqrestore(hba->host->host_lock, flags);
/* poll for max. 1 sec to clear door bell register by h/w */
*/
#define UFSHCD_QUIRK_BROKEN_UFS_HCI_VERSION UFS_BIT(5)
+ #define UFSHCD_QUIRK_BROKEN_REQ_LIST_CLR UFS_BIT(6)
/*
* This quirk needs to be enabled if the host contoller regards
* resolution of the values of PRDTO and PRDTL in UTRD as byte.