@@ -457,3 +457,17 @@ unsigned long ufshcd_mcq_poll_cqe_lock(struct ufs_hba *hba,
return completed_reqs;
}
+
+void ufshcd_mcq_enable_esi(struct ufs_hba *hba)
+{
+ ufshcd_writel(hba, ufshcd_readl(hba, REG_UFS_MEM_CFG) | 0x2,
+ REG_UFS_MEM_CFG);
+}
+EXPORT_SYMBOL_GPL(ufshcd_mcq_enable_esi);
+
+void ufshcd_mcq_config_esi(struct ufs_hba *hba, struct msi_msg *msg)
+{
+ ufshcd_writel(hba, msg->address_lo, REG_UFS_ESILBA);
+ ufshcd_writel(hba, msg->address_hi, REG_UFS_ESIUBA);
+}
+EXPORT_SYMBOL_GPL(ufshcd_mcq_config_esi);
@@ -254,6 +254,14 @@ static inline int ufshcd_mcq_vops_get_hba_mac(struct ufs_hba *hba)
return -EOPNOTSUPP;
}
+static inline int ufshcd_mcq_vops_config_esi(struct ufs_hba *hba)
+{
+ if (hba->vops && hba->vops->config_esi)
+ return hba->vops->config_esi(hba);
+
+ return -EOPNOTSUPP;
+}
+
static inline void ufshcd_inc_tp(struct ufs_hw_queue *q)
{
u32 mask = q->max_entries - 1;
@@ -8306,6 +8306,12 @@ static int ufshcd_config_mcq(struct ufs_hba *hba)
goto err;
}
+ ret = ufshcd_mcq_vops_config_esi(hba);
+ if (ret) {
+ dev_info(hba->dev, "MCQ ESI not available %d\n", ret);
+ ret = 0;
+ }
+
ufshcd_enable_intr(hba, UFSHCD_ENABLE_MCQ_INTRS);
ufshcd_mcq_make_queues_operational(hba);
ufshcd_mcq_config_mac(hba, hba->nutrs);
@@ -16,6 +16,7 @@
#include <linux/blk-crypto-profile.h>
#include <linux/blk-mq.h>
#include <linux/devfreq.h>
+#include <linux/msi.h>
#include <linux/pm_runtime.h>
#include <scsi/scsi_device.h>
#include <ufs/unipro.h>
@@ -297,6 +298,7 @@ struct ufs_pwr_mode_info {
* @get_outstanding_cqs: called to get outstanding completion queues
* @config_queues: called to config Runtime Operation Pointers
* @get_hba_mac: called to get vendor specific mac value
+ * @config_esi: called to config Event Specific Interrupt
*/
struct ufs_hba_variant_ops {
const char *name;
@@ -339,6 +341,7 @@ struct ufs_hba_variant_ops {
unsigned long *ocqs);
int (*config_queues)(struct ufs_hba *hba);
int (*get_hba_mac)(struct ufs_hba *hba);
+ int (*config_esi)(struct ufs_hba *hba);
};
/* clock gating state */
@@ -1230,6 +1233,8 @@ extern int ufshcd_dme_get_attr(struct ufs_hba *hba, u32 attr_sel,
extern int ufshcd_config_pwr_mode(struct ufs_hba *hba,
struct ufs_pa_layer_attr *desired_pwr_mode);
extern int ufshcd_uic_change_pwr_mode(struct ufs_hba *hba, u8 mode);
+extern void ufshcd_mcq_enable_esi(struct ufs_hba *hba);
+extern void ufshcd_mcq_config_esi(struct ufs_hba *hba, struct msi_msg *msg);
/* UIC command interfaces for DME primitives */
#define DME_LOCAL 0