scsi: ufs: core: Add Event Specific Interrupt configuration vendor specific ops
authorCan Guo <quic_cang@quicinc.com>
Thu, 15 Dec 2022 03:06:20 +0000 (19:06 -0800)
committerMartin K. Petersen <martin.petersen@oracle.com>
Sat, 14 Jan 2023 02:10:25 +0000 (21:10 -0500)
As Event Specific Interrupt message format is not defined in UFSHCI JEDEC
specs, and the ESI handling highly depends on how the format is designed,
hence add a vendor specific ops such that SoC vendors can configure their
own ESI handlers. If ESI vops is not provided or returning error, go with
the legacy (central) interrupt way.

Signed-off-by: Can Guo <quic_cang@quicinc.com>
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/ufs/core/ufshcd-priv.h
drivers/ufs/core/ufshcd.c
include/ufs/ufshcd.h

index 9b63090..529f850 100644 (file)
@@ -279,6 +279,14 @@ static inline int ufshcd_vops_get_outstanding_cqs(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;
+}
+
 extern const struct ufs_pm_lvl_states ufs_pm_lvl_states[];
 
 /**
index 54717c4..064a6d8 100644 (file)
@@ -8449,6 +8449,11 @@ err:
 
 static void ufshcd_config_mcq(struct ufs_hba *hba)
 {
+       int ret;
+
+       ret = ufshcd_mcq_vops_config_esi(hba);
+       dev_info(hba->dev, "ESI %sconfigured\n", ret ? "is not " : "");
+
        ufshcd_enable_intr(hba, UFSHCD_ENABLE_MCQ_INTRS);
        ufshcd_mcq_make_queues_operational(hba);
        ufshcd_mcq_config_mac(hba, hba->nutrs);
index 33973e9..1285787 100644 (file)
@@ -305,6 +305,7 @@ struct ufs_pwr_mode_info {
  * @get_hba_mac: called to get vendor specific mac value, mandatory for mcq mode
  * @op_runtime_config: called to config Operation and runtime regs Pointers
  * @get_outstanding_cqs: called to get outstanding completion queues
+ * @config_esi: called to config Event Specific Interrupt
  */
 struct ufs_hba_variant_ops {
        const char *name;
@@ -349,6 +350,7 @@ struct ufs_hba_variant_ops {
        int     (*op_runtime_config)(struct ufs_hba *hba);
        int     (*get_outstanding_cqs)(struct ufs_hba *hba,
                                       unsigned long *ocqs);
+       int     (*config_esi)(struct ufs_hba *hba);
 };
 
 /* clock gating state  */