thermal: tsens8974: Use a dedicated tsense high-priority workqueue

Thermal-mitigation software subscribing the temperature updates
relies upon timely notifications of temperature changes. The existing
implementation scheduled these notifications on the system workqueue,
which may result in addition latency when the system is under heavy
load. Use a high-priority workqueue to solve this problem and ensure
time-sensitive temperature notifications are received as quickly as
possible.

Change-Id: Ic8a18cecfae5a26d61d7179d9d9a2a1273e72744
Signed-off-by: Matt Wagantall <mattw@codeaurora.org>
diff --git a/drivers/thermal/msm8974-tsens.c b/drivers/thermal/msm8974-tsens.c
index f01a078..52608af 100644
--- a/drivers/thermal/msm8974-tsens.c
+++ b/drivers/thermal/msm8974-tsens.c
@@ -17,6 +17,7 @@
 #include <linux/platform_device.h>
 #include <linux/thermal.h>
 #include <linux/interrupt.h>
+#include <linux/workqueue.h>
 #include <linux/delay.h>
 #include <linux/kernel.h>
 #include <linux/io.h>
@@ -258,6 +259,7 @@
 
 struct tsens_tm_device {
 	struct platform_device		*pdev;
+	struct workqueue_struct		*tsens_wq;
 	bool				prev_reading_avail;
 	bool				calibration_less_mode;
 	bool				tsens_local_init;
@@ -655,7 +657,7 @@
 		}
 		if (upper_thr || lower_thr) {
 			/* Notify user space */
-			schedule_work(&tm->sensor[i].work);
+			queue_work(tm->tsens_wq, &tm->sensor[i].work);
 			rc = tsens_get_sw_id_mapping(
 					tm->sensor[i].sensor_hw_num,
 					&sensor_sw_id);
@@ -673,7 +675,7 @@
 
 static irqreturn_t tsens_isr(int irq, void *data)
 {
-	schedule_work(&tmdev->tsens_work);
+	queue_work(tmdev->tsens_wq, &tmdev->tsens_work);
 
 	return IRQ_HANDLED;
 }
@@ -1506,6 +1508,12 @@
 		return -ENODEV;
 
 	tmdev->pdev = pdev;
+	tmdev->tsens_wq = alloc_workqueue("tsens_wq", WQ_HIGHPRI, 0);
+	if (!tmdev->tsens_wq) {
+		rc = -ENOMEM;
+		goto fail;
+	}
+
 	rc = tsens_calib_sensors();
 	if (rc < 0) {
 		pr_err("Calibration failed\n");
@@ -1520,6 +1528,8 @@
 
 	return 0;
 fail:
+	if (tmdev->tsens_wq)
+		destroy_workqueue(tmdev->tsens_wq);
 	if (tmdev->tsens_calib_addr)
 		iounmap(tmdev->tsens_calib_addr);
 	if (tmdev->res_calib_mem)
@@ -1610,6 +1620,7 @@
 		release_mem_region(tmdev->res_tsens_mem->start,
 			tmdev->tsens_len);
 	free_irq(tmdev->tsens_irq, tmdev);
+	destroy_workqueue(tmdev->tsens_wq);
 	platform_set_drvdata(pdev, NULL);
 
 	return 0;