DEFINE_DEBUGFS_ATTRIBUTE(ee_usr_mask_fops, ee_usr_mask_get, ee_usr_mask_set, "%#llx\n");
 
+void ufs_debugfs_exception_event(struct ufs_hba *hba, u16 status)
+{
+       bool chgd = false;
+       u16 ee_ctrl_mask;
+       int err = 0;
+
+       if (!hba->debugfs_ee_rate_limit_ms || !status)
+               return;
+
+       mutex_lock(&hba->ee_ctrl_mutex);
+       ee_ctrl_mask = hba->ee_drv_mask | (hba->ee_usr_mask & ~status);
+       chgd = ee_ctrl_mask != hba->ee_ctrl_mask;
+       if (chgd) {
+               err = __ufshcd_write_ee_control(hba, ee_ctrl_mask);
+               if (err)
+                       dev_err(hba->dev, "%s: failed to write ee control %d\n",
+                               __func__, err);
+       }
+       mutex_unlock(&hba->ee_ctrl_mutex);
+
+       if (chgd && !err) {
+               unsigned long delay = msecs_to_jiffies(hba->debugfs_ee_rate_limit_ms);
+
+               queue_delayed_work(system_freezable_wq, &hba->debugfs_ee_work, delay);
+       }
+}
+
+static void ufs_debugfs_restart_ee(struct work_struct *work)
+{
+       struct ufs_hba *hba = container_of(work, struct ufs_hba, debugfs_ee_work.work);
+
+       if (!hba->ee_usr_mask || pm_runtime_suspended(hba->dev) ||
+           ufs_debugfs_get_user_access(hba))
+               return;
+       ufshcd_write_ee_control(hba);
+       ufs_debugfs_put_user_access(hba);
+}
+
 void ufs_debugfs_hba_init(struct ufs_hba *hba)
 {
+       /* Set default exception event rate limit period to 20ms */
+       hba->debugfs_ee_rate_limit_ms = 20;
+       INIT_DELAYED_WORK(&hba->debugfs_ee_work, ufs_debugfs_restart_ee);
        hba->debugfs_root = debugfs_create_dir(dev_name(hba->dev), ufs_debugfs_root);
        debugfs_create_file("stats", 0400, hba->debugfs_root, hba, &ufs_debugfs_stats_fops);
        debugfs_create_file("exception_event_mask", 0600, hba->debugfs_root,
                            hba, &ee_usr_mask_fops);
+       debugfs_create_u32("exception_event_rate_limit_ms", 0600, hba->debugfs_root,
+                          &hba->debugfs_ee_rate_limit_ms);
 }
 
 void ufs_debugfs_hba_exit(struct ufs_hba *hba)
 {
        debugfs_remove_recursive(hba->debugfs_root);
+       cancel_delayed_work_sync(&hba->debugfs_ee_work);
 }
 
 void __exit ufs_debugfs_exit(void);
 void ufs_debugfs_hba_init(struct ufs_hba *hba);
 void ufs_debugfs_hba_exit(struct ufs_hba *hba);
+void ufs_debugfs_exception_event(struct ufs_hba *hba, u16 status);
 #else
 static inline void ufs_debugfs_init(void) {}
 static inline void ufs_debugfs_exit(void) {}
 static inline void ufs_debugfs_hba_init(struct ufs_hba *hba) {}
 static inline void ufs_debugfs_hba_exit(struct ufs_hba *hba) {}
+static inline void ufs_debugfs_exception_event(struct ufs_hba *hba, u16 status) {}
 #endif
 
 #endif
 
        }
 }
 
-static int __ufshcd_write_ee_control(struct ufs_hba *hba, u32 ee_ctrl_mask)
+int __ufshcd_write_ee_control(struct ufs_hba *hba, u32 ee_ctrl_mask)
 {
        return ufshcd_query_attr_retry(hba, UPIU_QUERY_OPCODE_WRITE_ATTR,
                                       QUERY_ATTR_IDN_EE_CONTROL, 0, 0,
                                       &ee_ctrl_mask);
 }
 
-static int ufshcd_write_ee_control(struct ufs_hba *hba)
+int ufshcd_write_ee_control(struct ufs_hba *hba)
 {
        int err;
 
        if (status & hba->ee_drv_mask & MASK_EE_URGENT_BKOPS)
                ufshcd_bkops_exception_event_handler(hba);
 
+       ufs_debugfs_exception_event(hba, status);
 out:
        ufshcd_scsi_unblock_requests(hba);
        /*
 
 #endif
 #ifdef CONFIG_DEBUG_FS
        struct dentry *debugfs_root;
+       struct delayed_work debugfs_ee_work;
+       u32 debugfs_ee_rate_limit_ms;
 #endif
 };
 
 int ufshcd_dump_regs(struct ufs_hba *hba, size_t offset, size_t len,
                     const char *prefix);
 
+int __ufshcd_write_ee_control(struct ufs_hba *hba, u32 ee_ctrl_mask);
+int ufshcd_write_ee_control(struct ufs_hba *hba);
 int ufshcd_update_ee_control(struct ufs_hba *hba, u16 *mask, u16 *other_mask,
                             u16 set, u16 clr);