}
 
 /**
- * ufshcd_intr - Main interrupt service routine
+ * ufshcd_threaded_intr - Threaded interrupt service routine
  * @irq: irq number
  * @__hba: pointer to adapter instance
  *
  *  IRQ_HANDLED - If interrupt is valid
  *  IRQ_NONE    - If invalid interrupt
  */
-static irqreturn_t ufshcd_intr(int irq, void *__hba)
+static irqreturn_t ufshcd_threaded_intr(int irq, void *__hba)
 {
        u32 last_intr_status, intr_status, enabled_intr_status = 0;
        irqreturn_t retval = IRQ_NONE;
        return retval;
 }
 
+/**
+ * ufshcd_intr - Main interrupt service routine
+ * @irq: irq number
+ * @__hba: pointer to adapter instance
+ *
+ * Return:
+ *  IRQ_HANDLED     - If interrupt is valid
+ *  IRQ_WAKE_THREAD - If handling is moved to threaded handled
+ *  IRQ_NONE        - If invalid interrupt
+ */
+static irqreturn_t ufshcd_intr(int irq, void *__hba)
+{
+       struct ufs_hba *hba = __hba;
+
+       /* Move interrupt handling to thread when MCQ & ESI are not enabled */
+       if (!hba->mcq_enabled || !hba->mcq_esi_enabled)
+               return IRQ_WAKE_THREAD;
+
+       /* Directly handle interrupts since MCQ ESI handlers does the hard job */
+       return ufshcd_sl_intr(hba, ufshcd_readl(hba, REG_INTERRUPT_STATUS) &
+                                  ufshcd_readl(hba, REG_INTERRUPT_ENABLE));
+}
+
 static int ufshcd_clear_tm_cmd(struct ufs_hba *hba, int tag)
 {
        int err = 0;
        ufshcd_readl(hba, REG_INTERRUPT_ENABLE);
 
        /* IRQ registration */
-       err = devm_request_irq(dev, irq, ufshcd_intr, IRQF_SHARED, UFSHCD, hba);
+       err = devm_request_threaded_irq(dev, irq, ufshcd_intr, ufshcd_threaded_intr,
+                                       IRQF_ONESHOT | IRQF_SHARED, UFSHCD, hba);
        if (err) {
                dev_err(hba->dev, "request irq failed\n");
                goto out_disable;