msm: bam_dmux: add notification registration API

Add an API to allow non-direct clients of bam_dmux to register a
notification callback function to recieve A2 power status notifications.

Change-Id: Ida32a3d305d279b381d512073949b6a23e75657d
Signed-off-by: Jeffrey Hugo <jhugo@codeaurora.org>
diff --git a/arch/arm/mach-msm/bam_dmux.c b/arch/arm/mach-msm/bam_dmux.c
index 6361d6d..66d2a57 100644
--- a/arch/arm/mach-msm/bam_dmux.c
+++ b/arch/arm/mach-msm/bam_dmux.c
@@ -239,6 +239,13 @@
 static int wakelock_reference_count;
 static int a2_pc_disabled_wakelock_skipped;
 static int disconnect_ack;
+static LIST_HEAD(bam_other_notify_funcs);
+
+struct outside_notify_func {
+	void (*notify)(void *, int, unsigned long);
+	void *priv;
+	struct list_head list_node;
+};
 /* End A2 power collaspe */
 
 /* subsystem restart */
@@ -1377,6 +1384,8 @@
 static void notify_all(int event, unsigned long data)
 {
 	int i;
+	struct list_head *temp;
+	struct outside_notify_func *func;
 
 	for (i = 0; i < BAM_DMUX_NUM_CHANNELS; ++i) {
 		if (bam_ch_is_open(i)) {
@@ -1385,6 +1394,12 @@
 					__func__, i, event, data);
 		}
 	}
+
+	__list_for_each(temp, &bam_other_notify_funcs) {
+		func = container_of(temp, struct outside_notify_func,
+								list_node);
+		func->notify(func->priv, event, data);
+	}
 }
 
 static void kickoff_ul_wakeup_func(struct work_struct *work)
@@ -1498,6 +1513,26 @@
 	return vote == 0;
 }
 
+int msm_bam_dmux_reg_notify(void *priv,
+			void (*notify)(void *priv, int event_type,
+						unsigned long data))
+{
+	struct outside_notify_func *func;
+
+	if (!notify)
+		return -EINVAL;
+
+	func = kmalloc(sizeof(struct outside_notify_func), GFP_KERNEL);
+	if (!func)
+		return -ENOMEM;
+
+	func->notify = notify;
+	func->priv = priv;
+	list_add(&func->list_node, &bam_other_notify_funcs);
+
+	return 0;
+}
+
 static void ul_timeout(struct work_struct *work)
 {
 	unsigned long flags;