msm: smd_tty: use pm_qos for bt performance.

A2DP audio skips out every 8-10 seconds in idle.
cpuidle is working and sometime A2DP audio skips in that time.

Use pm_qos to avoid this problem.

Change-Id: I00701c89cb9d5723e17928f452696db21e107ab0
Signed-off-by: Iliyan Malchev <malchev@google.com>
diff --git a/arch/arm/mach-msm/smd_tty.c b/arch/arm/mach-msm/smd_tty.c
index 44ef822..98e5df9 100644
--- a/arch/arm/mach-msm/smd_tty.c
+++ b/arch/arm/mach-msm/smd_tty.c
@@ -24,6 +24,7 @@
 #include <linux/wakelock.h>
 #include <linux/platform_device.h>
 #include <linux/sched.h>
+#include <linux/pm_qos.h>
 
 #include <linux/tty.h>
 #include <linux/tty_driver.h>
@@ -93,15 +94,26 @@
 };
 #define DS_IDX 0
 #define LOOPBACK_IDX 36
+#define BT_ACL_IDX 2
+#define BT_CMD_IDX 3
 
 static struct delayed_work loopback_work;
 static struct smd_tty_info smd_tty[MAX_SMD_TTYS];
+static struct pm_qos_request smd_tty_qos_req;
+static struct work_struct pm_qos_set_work;
 
 static int is_in_reset(struct smd_tty_info *info)
 {
 	return info->in_reset;
 }
 
+static void pm_qos_set_worker(struct work_struct *work)
+{
+	/* keep the request for 500ms */
+	pm_qos_update_request_timeout(&smd_tty_qos_req,
+			0, jiffies_to_usecs(HZ / 2));
+}
+
 static void buf_req_retry(unsigned long param)
 {
 	struct smd_tty_info *info = (struct smd_tty_info *)param;
@@ -157,6 +169,9 @@
 			printk(KERN_ERR "OOPS - smd_tty_buffer mismatch?!");
 		}
 
+#ifdef CONFIG_HAS_WAKELOCK
+		pr_debug("%s: lock wakelock %s\n", __func__, info->wake_lock.name);
+#endif
 		wake_lock_timeout(&info->wake_lock, HZ / 2);
 		tty_flip_buffer_push(tty);
 	}
@@ -185,8 +200,14 @@
 		 */
 		if (smd_write_avail(info->ch)) {
 			smd_disable_read_intr(info->ch);
-			if (info->tty)
+			if (info->tty) {
+				unsigned int n = info->tty->index;
 				wake_up_interruptible(&info->tty->write_wait);
+
+				/* use pm_qos for BT performance */
+				if (n == BT_ACL_IDX || n == BT_CMD_IDX)
+					schedule_work(&pm_qos_set_work);
+			}
 		}
 		tasklet_hi_schedule(&info->tty_tsklt);
 		break;
@@ -578,7 +599,10 @@
 		}
 		smd_tty[idx].smd = &smd_configs[n];
 	}
+	INIT_WORK(&pm_qos_set_work, pm_qos_set_worker);
 	INIT_DELAYED_WORK(&loopback_work, loopback_probe_worker);
+	pm_qos_add_request(&smd_tty_qos_req, PM_QOS_CPU_DMA_LATENCY,
+			PM_QOS_DEFAULT_VALUE);
 	return 0;
 
 out: