Merge cherrypicks of ['partner-android-review.googlesource.com/2640861'] into android13-msm-pixelwatch-5.15-24Q1-release.

Change-Id: Idd4a423b2ba404dbf384bcdb1d0f5024dd7681e3
diff --git a/display.c b/display.c
index 3593e99..0115b91 100644
--- a/display.c
+++ b/display.c
@@ -21,6 +21,7 @@
 static DEFINE_MUTEX(nanohub_display_mutex);
 static DECLARE_COMPLETION(message_callback);
 static int display_state;
+static bool allow_read_mcu_disp_state_once = false;
 
 ssize_t nanohub_pin_display_select_get(struct device *dev,
                                        struct device_attribute *attr, char *buf)
@@ -38,8 +39,11 @@
 	struct nanohub_data *data = dev_get_drvdata(dev);
 	const struct nanohub_platform_data *pdata = data->pdata;
 	if (count >= 1 && buf[0] == '0') {
+		allow_read_mcu_disp_state_once = false;
 		gpio_set_value(pdata->display_select_gpio, 0);
 	} else if (count >= 1 && buf[0] == '1') {
+		if (gpio_get_value(pdata->display_select_gpio) == 0)
+			allow_read_mcu_disp_state_once = true;
 		gpio_set_value(pdata->display_select_gpio, 1);
 	}
 	return count;
@@ -47,35 +51,56 @@
 
 ssize_t nanohub_get_display_state(struct device *dev, struct device_attribute *attr, char *buf)
 {
-	int display_state = nanohub_query_display_state();
+	struct nanohub_data *data = dev_get_drvdata(dev);
+	int display_state = nanohub_query_display_state_internal(data, true);
 	return scnprintf(buf, PAGE_SIZE, "%d", display_state);
 }
 
-#define NANOHUB_DISPLAY_COMMAND_TYPE_GET_STATE 0x06
+ssize_t nanohub_get_display_state_no_check(struct device *dev, struct device_attribute *attr,
+					   char *buf)
+{
+	struct nanohub_data *data = dev_get_drvdata(dev);
+	int display_state = nanohub_query_display_state_internal(data, false);
+	return scnprintf(buf, PAGE_SIZE, "%d", display_state);
+}
+
 #define NANOHUB_DISPLAY_GET_STATE_TIMEOUT_MS   100
 
+enum nanohub_display_command_type {
+	NANOHUB_DISPLAY_COMMAND_GET_STATE = 0x06,
+	NANOHUB_DISPLAY_COMMAND_GET_STATE_NO_CHECK = 0x07,
+};
+
 static void on_message_received(const char *buffer, size_t length)
 {
 	if (length == 3 && buffer[0] == NANOHUB_DISPLAY_COMMAND_VERSION &&
-	    buffer[1] == NANOHUB_DISPLAY_COMMAND_TYPE_GET_STATE) {
+	    buffer[1] == NANOHUB_DISPLAY_COMMAND_GET_STATE) {
 		display_state = buffer[2];
 	}
 	complete(&message_callback);
 }
 
-int nanohub_query_display_state_internal(struct nanohub_data *data)
+int nanohub_query_display_state_internal(struct nanohub_data *data, bool check_ownership)
 {
 	const char message[] = { NANOHUB_DISPLAY_COMMAND_VERSION,
-				 NANOHUB_DISPLAY_COMMAND_TYPE_GET_STATE };
+				 check_ownership ? NANOHUB_DISPLAY_COMMAND_GET_STATE :
+						   NANOHUB_DISPLAY_COMMAND_GET_STATE_NO_CHECK };
 	long ret;
-	const struct nanohub_platform_data *pdata;
 
-	if (unlikely(data == NULL))
-		return -EINVAL;
+	if (check_ownership) {
+		const struct nanohub_platform_data *pdata;
+		if (unlikely(data == NULL))
+			return -EINVAL;
 
-	pdata = data->pdata;
-	if (gpio_get_value(pdata->display_select_gpio) == 1)
-		return MCU_DISPLAY_NONE;
+		pdata = data->pdata;
+		if (gpio_get_value(pdata->display_select_gpio) == 1)
+			return MCU_DISPLAY_NONE;
+	} else {
+		if (allow_read_mcu_disp_state_once)
+			allow_read_mcu_disp_state_once = false;
+		else
+			return MCU_DISPLAY_NONE;
+	}
 
 	mutex_lock(&nanohub_display_mutex);
 
@@ -92,11 +117,13 @@
 
 	mutex_unlock(&nanohub_display_mutex);
 
-	if (ret < 0)
-		return ret;
-
-	if (ret == 0)
-		return -ETIMEDOUT;
+	if (ret <= 0) {
+		pr_err("nanohub : failed to query disp, ret = %d\n", ret);
+		if (ret == 0)
+			return -ETIMEDOUT;
+		else
+			return ret;
+	}
 
 	return display_state;
 }
diff --git a/display.h b/display.h
index f48e589..f2de19b 100644
--- a/display.h
+++ b/display.h
@@ -25,6 +25,9 @@
 
 ssize_t nanohub_get_display_state(struct device *dev, struct device_attribute *attr, char *buf);
 
-int nanohub_query_display_state_internal(struct nanohub_data *data);
+ssize_t nanohub_get_display_state_no_check(struct device *dev, struct device_attribute *attr,
+					   char *buf);
+
+int nanohub_query_display_state_internal(struct nanohub_data *data, bool check_ownership);
 
 #endif
diff --git a/main.c b/main.c
index 92ff055..43877a6 100644
--- a/main.c
+++ b/main.c
@@ -132,6 +132,7 @@
 EXPORT_SYMBOL(nanohub_register_listener);
 EXPORT_SYMBOL(nanohub_unregister_listener);
 EXPORT_SYMBOL(nanohub_query_display_state);
+EXPORT_SYMBOL(nanohub_query_display_state_no_check);
 
 static struct class *sensor_class;
 static int major;
@@ -1401,6 +1402,7 @@
 	__ATTR(display_select, 0660, nanohub_pin_display_select_get,
 	       nanohub_pin_display_select_set),
 	__ATTR(display_state, 0440, nanohub_get_display_state, NULL),
+	__ATTR(display_state_no_check, 0440, nanohub_get_display_state_no_check, NULL),
 #endif
 #ifdef CONFIG_NANOHUB_BL_ST
 	__ATTR(lock, 0220, NULL, nanohub_lock_bl),
@@ -1627,7 +1629,16 @@
 int nanohub_query_display_state(void)
 {
 #ifdef CONFIG_NANOHUB_DISPLAY
-	return nanohub_query_display_state_internal(priv_nanohub_data);
+	return nanohub_query_display_state_internal(priv_nanohub_data, true);
+#else
+	return -ENOSYS;
+#endif
+}
+
+int nanohub_query_display_state_no_check(void)
+{
+#ifdef CONFIG_NANOHUB_DISPLAY
+	return nanohub_query_display_state_internal(priv_nanohub_data, false);
 #else
 	return -ENOSYS;
 #endif
diff --git a/nanohub_exports.h b/nanohub_exports.h
index aab40c8..9695e1b 100644
--- a/nanohub_exports.h
+++ b/nanohub_exports.h
@@ -65,7 +65,12 @@
  * Query the display power state from MCU when display is controlled by MCU.
  * MCU_DISPLAY_NONE, when MCU doesn't control display.
  */
-
 extern int nanohub_query_display_state(void);
 
+/**
+ * Query the display power state from the MCU, regardless of whether the display is controlled by
+ * the MCU.
+ */
+extern int nanohub_query_display_state_no_check(void);
+
 #endif /* _NANOHUB_EXPORTS_H_ */