Merge android12-gs-pixel-5.10-sc-v2 into android13-gs-pixel-5.10

Bug: 211546634
Signed-off-by: Robin Peng <robinpeng@google.com>
Change-Id: Ia98180def8a25497a8afdeb646c4cae215b364c8
diff --git a/lwis_device.h b/lwis_device.h
index 03488aa..8154166 100644
--- a/lwis_device.h
+++ b/lwis_device.h
@@ -254,6 +254,8 @@
 	int pm_hibernation;
 	/* Is device read only */
 	bool is_read_only;
+	/* Adjust thread priority */
+	int adjust_thread_priority;
 
 	/* LWIS allocator block manager */
 	struct lwis_allocator_block_mgr *block_mgr;
diff --git a/lwis_dt.c b/lwis_dt.c
index f069f13..0f31961 100644
--- a/lwis_dt.c
+++ b/lwis_dt.c
@@ -922,11 +922,9 @@
 
 static int parse_pm_hibernation(struct lwis_device *lwis_dev)
 {
-	struct device *dev;
 	struct device_node *dev_node;
 
-	dev = &(lwis_dev->plat_dev->dev);
-	dev_node = dev->of_node;
+	dev_node = lwis_dev->plat_dev->dev.of_node;
 	lwis_dev->pm_hibernation = 1;
 
 	of_property_read_u32(dev_node, "pm-hibernation", &lwis_dev->pm_hibernation);
@@ -945,6 +943,18 @@
 	return 0;
 }
 
+static int parse_thread_priority(struct lwis_device *lwis_dev)
+{
+	struct device_node *dev_node;
+
+	dev_node = lwis_dev->plat_dev->dev.of_node;
+	lwis_dev->adjust_thread_priority = 0;
+
+	of_property_read_u32(dev_node, "thread-priority", &lwis_dev->adjust_thread_priority);
+
+	return 0;
+}
+
 int lwis_base_parse_dt(struct lwis_device *lwis_dev)
 {
 	struct device *dev;
@@ -1053,6 +1063,8 @@
 
 	parse_access_mode(lwis_dev);
 
+	parse_thread_priority(lwis_dev);
+
 	parse_bitwidths(lwis_dev);
 
 	iommus = of_find_property(dev_node, "iommus", &iommus_len);
diff --git a/lwis_transaction.c b/lwis_transaction.c
index 7fa7ab0..1c9fac2 100644
--- a/lwis_transaction.c
+++ b/lwis_transaction.c
@@ -331,7 +331,14 @@
 	INIT_LIST_HEAD(&client->transaction_process_queue_tasklet);
 	tasklet_init(&client->transaction_tasklet, transaction_tasklet_func, (unsigned long)client);
 	INIT_LIST_HEAD(&client->transaction_process_queue);
-	client->transaction_wq = create_workqueue("lwistran");
+	if (client->lwis_dev->adjust_thread_priority != 0) {
+		/* Since I2C transactions can only be executed in workqueues, putting them in high
+		 * priority to avoid scheduling delays. */
+		client->transaction_wq = alloc_ordered_workqueue(
+			"lwistran-i2c", __WQ_LEGACY | WQ_MEM_RECLAIM | WQ_HIGHPRI);
+	} else {
+		client->transaction_wq = create_workqueue("lwistran");
+	}
 	INIT_WORK(&client->transaction_work, transaction_work_func);
 	client->transaction_counter = 0;
 	hash_init(client->transaction_list);