drm/msm/sde: add multi-client and ref counting for core irq

Add multiple client support for core irq interface. Multiple
clients can register/unregister callbacks for each core interrupt.
Callbacks for each interrupt will be invoked one by one in interrupt
handler. Core irq will maintain how many times each interrupt has
enabled, and keep it enabled until last disable call is invoked.

Change-Id: I8fe45305fd1bcc8bbdebf3e9ca931842f2c62daf
Signed-off-by: Alan Kwong <akwong@codeaurora.org>
diff --git a/drivers/gpu/drm/msm/sde/sde_kms.h b/drivers/gpu/drm/msm/sde/sde_kms.h
index 6dca0a1..f398890 100644
--- a/drivers/gpu/drm/msm/sde/sde_kms.h
+++ b/drivers/gpu/drm/msm/sde/sde_kms.h
@@ -80,10 +80,12 @@
 
 /*
  * struct sde_irq_callback - IRQ callback handlers
+ * @list: list to callback
  * @func: intr handler
  * @arg: argument for the handler
  */
 struct sde_irq_callback {
+	struct list_head list;
 	void (*func)(void *arg, int irq_idx);
 	void *arg;
 };
@@ -92,12 +94,17 @@
  * struct sde_irq: IRQ structure contains callback registration info
  * @total_irq:    total number of irq_idx obtained from HW interrupts mapping
  * @irq_cb_tbl:   array of IRQ callbacks setting
+ * @enable_counts array of IRQ enable counts
  * @cb_lock:      callback lock
+ * @debugfs_file: debugfs file for irq statistics
  */
 struct sde_irq {
 	u32 total_irqs;
-	struct sde_irq_callback *irq_cb_tbl;
+	struct list_head *irq_cb_tbl;
+	atomic_t *enable_counts;
+	atomic_t *irq_counts;
 	spinlock_t cb_lock;
+	struct dentry *debugfs_file;
 };
 
 /**