Browse Source

Merge "touch: offload fw boot up to workqueue"

qctecmdr 2 năm trước cách đây
mục cha
commit
8988644ee3
3 tập tin đã thay đổi với 412 bổ sung69 xóa
  1. 395 63
      pt/pt_core.c
  2. 5 4
      pt/pt_mt_common.c
  3. 12 2
      pt/pt_regs.h

+ 395 - 63
pt/pt_core.c

@@ -41,6 +41,11 @@
 #define FT_I2C_VTG_MIN_UV       1800000
 #define FT_I2C_VTG_MAX_UV       1800000
 
+#define PWR_SUSPEND_LOAD_UA  165
+#define I2C_SUSPEND_LOAD_UA  100
+#define PWR_ACTIVE_LOAD_MA  12000
+#define I2C_ACTIVE_LOAD_MA  30000
+
 #define PT_CORE_STARTUP_RETRY_COUNT		3
 
 #define PT_STATUS_STR_LEN (50)
@@ -51,6 +56,7 @@ static struct drm_panel *active_panel;
 
 MODULE_FIRMWARE(PT_FW_FILE_NAME);
 
+static int pt_lpm_regulator(struct regulator *reg, int load_uA);
 static const char *pt_driver_core_name = PT_CORE_NAME;
 static const char *pt_driver_core_version = PT_DRIVER_VERSION;
 static const char *pt_driver_core_date = PT_DRIVER_DATE;
@@ -7653,11 +7659,14 @@ static int pt_core_sleep_(struct pt_core_data *cd)
 	int rc = 0;
 
 	mutex_lock(&cd->system_lock);
-	if (cd->sleep_state == SS_SLEEP_OFF) {
+	pt_debug(cd->dev, DL_INFO, "%s - sleep_state %d\n", __func__, cd->sleep_state);
+	if (cd->sleep_state == SS_SLEEP_OFF || cd->sleep_state == SS_SLEEP_NONE) {
 		cd->sleep_state = SS_SLEEPING;
 	} else {
 		mutex_unlock(&cd->system_lock);
-		return 1;
+		pt_debug(cd->dev, DL_INFO,
+			"%s - Skip slee[ state %d\n", __func__, cd->sleep_state);
+		return 0;
 	}
 	mutex_unlock(&cd->system_lock);
 
@@ -7666,14 +7675,24 @@ static int pt_core_sleep_(struct pt_core_data *cd)
 	cancel_work_sync(&cd->enum_work);
 	pt_stop_wd_timer(cd);
 
-	if (IS_EASY_WAKE_CONFIGURED(cd->easy_wakeup_gesture) && cd->runtime)
-		rc = pt_put_device_into_easy_wakeup_(cd);
-	else if (cd->cpdata->flags & PT_CORE_FLAG_POWEROFF_ON_SLEEP)
+	if (cd->cpdata->flags & PT_CORE_FLAG_POWEROFF_ON_SLEEP) {
+		pt_debug(cd->dev, DL_INFO, "%s: Entering into power off mode:\n", __func__);
 		rc = pt_core_poweroff_device_(cd);
-	else if (cd->cpdata->flags & PT_CORE_FLAG_DEEP_STANDBY)
+		if (rc)
+			pr_err("%s: Power off error detected :rc=%d\n", __func__, rc);
+	} else if (cd->cpdata->flags & PT_CORE_FLAG_DEEP_STANDBY) {
+		pt_debug(cd->dev, DL_INFO,
+			"%s: Entering into deep standby mode:\n", __func__);
 		rc = pt_put_device_into_deep_standby_(cd);
-	else
+		if (rc)
+			pr_err("%s: Deep standby error detected :rc=%d\n", __func__, rc);
+	} else {
+		pt_debug(cd->dev, DL_INFO,
+			"%s: Entering into deep sleep mode:\n", __func__);
 		rc = pt_put_device_into_deep_sleep_(cd);
+		if (rc)
+			pr_err("%s: Deep sleep error detected :rc=%d\n", __func__, rc);
+	}
 
 	mutex_lock(&cd->system_lock);
 	cd->sleep_state = SS_SLEEP_ON;
@@ -7682,6 +7701,89 @@ static int pt_core_sleep_(struct pt_core_data *cd)
 	return rc;
 }
 
+/*******************************************************************************
+ * FUNCTION: pt_core_easywake_on_
+ *
+ * SUMMARY: Suspend the device with easy wake on the
+ *  configuration in the core platform data structure.
+ *
+ * RETURN:
+ *   0 = success
+ *  !0 = failure
+ *
+ * PARAMETERS:
+ *  *cd  - pointer to core data
+ ******************************************************************************/
+static int pt_core_easywake_on_(struct pt_core_data *cd)
+{
+	int rc = 0;
+
+	mutex_lock(&cd->system_lock);
+
+	if (cd->sleep_state == SS_EASY_WAKING_ON) {
+		mutex_unlock(&cd->system_lock);
+		pt_debug(cd->dev, DL_INFO, "%s - Skip sleep state %d\n",
+			__func__, cd->sleep_state);
+		return 0;
+	}
+	mutex_unlock(&cd->system_lock);
+
+	/* Ensure watchdog and startup works stopped */
+	pt_stop_wd_timer(cd);
+	cancel_work_sync(&cd->enum_work);
+	pt_stop_wd_timer(cd);
+
+	if (IS_EASY_WAKE_CONFIGURED(cd->easy_wakeup_gesture)) {
+		rc = pt_put_device_into_easy_wakeup_(cd);
+		pt_debug(cd->dev, DL_INFO, "%s :Entering into easywakeup: rc=%d\n", __func__, rc);
+		if (rc)
+			pr_err("%s: Easy wakeup error detected :rc=%d\n", __func__, rc);
+	}
+	mutex_lock(&cd->system_lock);
+	cd->sleep_state = SS_EASY_WAKING_ON;
+	mutex_unlock(&cd->system_lock);
+
+	return rc;
+}
+
+
+/*******************************************************************************
+ * FUNCTION: pt_core_easywake_on
+ *
+ * SUMMARY: Protected call to pt_core_easywake_on_ by exclusive access to the DUT.
+ *
+ * RETURN:
+ *   0 = success
+ *  !0 = failure
+ *
+ * PARAMETERS:
+ *  *cd  - pointer to core data
+ ******************************************************************************/
+static int pt_core_easywake_on(struct pt_core_data *cd)
+{
+	int rc = 0;
+
+	rc = request_exclusive(cd, cd->dev, PT_REQUEST_EXCLUSIVE_TIMEOUT);
+	if (rc < 0) {
+		pt_debug(cd->dev, DL_ERROR,
+			"%s: fail get exclusive ex=%p own=%p\n",
+			__func__, cd->exclusive_dev, cd->dev);
+		return rc;
+	}
+
+	rc = pt_core_easywake_on_(cd);
+
+	if (release_exclusive(cd, cd->dev) < 0)
+		pt_debug(cd->dev, DL_ERROR,
+			"%s: fail to release exclusive\n", __func__);
+	else
+		pt_debug(cd->dev, DL_DEBUG, "%s: pass release exclusive\n",
+			__func__);
+
+	return rc;
+}
+
+
 /*******************************************************************************
  * FUNCTION: pt_core_sleep
  *
@@ -8405,8 +8507,8 @@ static int pt_read_input(struct pt_core_data *cd)
 	 */
 	mutex_lock(&cd->system_lock);
 
-	if (IS_EASY_WAKE_CONFIGURED(cd->easy_wakeup_gesture) && cd->runtime) {
-		if (cd->sleep_state == SS_SLEEP_ON) {
+	if (IS_EASY_WAKE_CONFIGURED(cd->easy_wakeup_gesture)) {
+		if (cd->sleep_state == SS_SLEEP_ON || cd->sleep_state == SS_EASY_WAKING_ON) {
 			mutex_unlock(&cd->system_lock);
 			if (!dev->power.is_suspended)
 				goto read;
@@ -8999,13 +9101,16 @@ static int pt_core_wake_device_from_deep_sleep_(
  ******************************************************************************/
 static int pt_core_wake_device_from_easy_wake_(struct pt_core_data *cd)
 {
+	int rc = 0;
+
 	mutex_lock(&cd->system_lock);
 	cd->wait_until_wake = 1;
 	mutex_unlock(&cd->system_lock);
 	wake_up(&cd->wait_q);
 	msleep(20);
 
-	return pt_core_wake_device_from_deep_sleep_(cd);
+	rc = pt_core_wake_device_from_deep_sleep_(cd);
+	return rc;
 }
 
 /*******************************************************************************
@@ -9465,6 +9570,84 @@ exit:
 	return rc;
 }
 
+/*******************************************************************************
+ * FUNCTION: pt_core_easywake_off_
+ *
+ * SUMMARY: Resume the device with a power on or wake from deep sleep based on
+ *  the configuration in the core platform data structure.
+ *
+ * RETURN:
+ *   0 = success
+ *  !0 = failure
+ *
+ * PARAMETERS:
+ *  *cd  - pointer to core data
+ ******************************************************************************/
+static int pt_core_easywake_off_(struct pt_core_data *cd)
+{
+	int rc = 0;
+
+	mutex_lock(&cd->system_lock);
+	if (cd->sleep_state == SS_EASY_WAKING_OFF) {
+		mutex_unlock(&cd->system_lock);
+		pt_debug(cd->dev, DL_INFO,
+			"%s - %d skip wakeoff\n", __func__, cd->sleep_state);
+		return 0;
+	}
+	mutex_unlock(&cd->system_lock);
+
+	if (!(cd->cpdata->flags & PT_CORE_FLAG_SKIP_RESUME)) {
+		if (IS_EASY_WAKE_CONFIGURED(cd->easy_wakeup_gesture))
+			rc = pt_core_wake_device_from_easy_wake_(cd);
+		if (rc < 0)
+			pt_debug(cd->dev, DL_ERROR,
+				"%s - %d failed %d\n", __func__, rc);
+	}
+
+	mutex_lock(&cd->system_lock);
+	cd->sleep_state = SS_EASY_WAKING_OFF;
+	mutex_unlock(&cd->system_lock);
+	pt_start_wd_timer(cd);
+	return rc;
+}
+
+/*******************************************************************************
+ * FUNCTION: pt_core_easywake_off
+ *
+ * SUMMARY: Protected call to pt_core_easywake_off by exclusive access to the DUT.
+ *
+ * RETURN:
+ *   0 = success
+ *  !0 = failure
+ *
+ * PARAMETERS:
+ *  *cd  - pointer to core data
+ ******************************************************************************/
+static int pt_core_easywake_off(struct pt_core_data *cd)
+{
+	int rc;
+
+	rc = request_exclusive(cd, cd->dev, PT_REQUEST_EXCLUSIVE_TIMEOUT);
+	if (rc < 0) {
+		pt_debug(cd->dev, DL_ERROR,
+				"%s: fail get exclusive ex=%p own=%p\n",
+				__func__, cd->exclusive_dev, cd->dev);
+		return rc;
+	}
+
+	rc = pt_core_easywake_off_(cd);
+
+	if (release_exclusive(cd, cd->dev) < 0)
+		pt_debug(cd->dev, DL_ERROR, "%s: fail to release exclusive\n",
+			__func__);
+	else
+		pt_debug(cd->dev, DL_DEBUG, "%s: pass release exclusive\n",
+			__func__);
+
+	return rc;
+}
+
+
 /*******************************************************************************
  * FUNCTION: pt_core_wake_
  *
@@ -9483,18 +9666,18 @@ static int pt_core_wake_(struct pt_core_data *cd)
 	int rc = 0;
 
 	mutex_lock(&cd->system_lock);
-	if (cd->sleep_state == SS_SLEEP_ON) {
+	if (cd->sleep_state == SS_SLEEP_ON || cd->sleep_state == SS_SLEEP_NONE) {
 		cd->sleep_state = SS_WAKING;
 	} else {
 		mutex_unlock(&cd->system_lock);
-		return 1;
+		pt_debug(cd->dev, DL_INFO,
+			"%s - skip wake sleep state %d\n", __func__, cd->sleep_state);
+		return 0;
 	}
 	mutex_unlock(&cd->system_lock);
 
 	if (!(cd->cpdata->flags & PT_CORE_FLAG_SKIP_RESUME)) {
-		if (IS_EASY_WAKE_CONFIGURED(cd->easy_wakeup_gesture) && cd->runtime)
-			rc = pt_core_wake_device_from_easy_wake_(cd);
-		else if (cd->cpdata->flags & PT_CORE_FLAG_POWEROFF_ON_SLEEP) {
+		if (cd->cpdata->flags & PT_CORE_FLAG_POWEROFF_ON_SLEEP) {
 			pt_debug(cd->dev, DL_INFO,
 				"%s: Entering into poweron mode:\n", __func__);
 			rc = pt_core_poweron_device_(cd);
@@ -9530,7 +9713,7 @@ static int pt_core_wake_(struct pt_core_data *cd)
  ******************************************************************************/
 static int pt_core_wake(struct pt_core_data *cd)
 {
-	int rc;
+	int rc = 0;
 
 	rc = request_exclusive(cd, cd->dev, PT_REQUEST_EXCLUSIVE_TIMEOUT);
 	if (rc < 0) {
@@ -10341,6 +10524,49 @@ regulator_put:
 	return rc;
 }
 
+static int pt_enable_vdd_regulator(struct pt_core_data *cd, bool en)
+{
+	int rc;
+
+	if (!en) {
+		rc = 0;
+		goto disable_vdd_reg;
+	}
+
+	if (cd->vdd) {
+		if (regulator_count_voltages(cd->vdd) > 0) {
+			rc = regulator_set_voltage(cd->vdd, FT_VTG_MIN_UV,
+						FT_VTG_MAX_UV);
+			if (rc) {
+				dev_err(cd->dev,
+					"Regulator set_vtg failed vdd rc=%d\n", rc);
+				goto exit;
+			}
+		}
+
+		rc = regulator_enable(cd->vdd);
+		if (rc) {
+			dev_err(cd->dev,
+				"Regulator vdd enable failed rc=%d\n", rc);
+			goto exit;
+		}
+	}
+
+	return 0;
+
+disable_vdd_reg:
+	if (cd->vdd) {
+		if (regulator_count_voltages(cd->vdd) > 0)
+			regulator_set_voltage(cd->vdd, FT_VTG_MIN_UV,
+						FT_VTG_MAX_UV);
+
+		regulator_disable(cd->vdd);
+	}
+
+exit:
+	return rc;
+}
+
 static int pt_enable_regulator(struct pt_core_data *cd, bool en)
 {
 	int rc;
@@ -10435,21 +10661,9 @@ exit:
 static int pt_core_rt_suspend(struct device *dev)
 {
 	struct pt_core_data *cd = dev_get_drvdata(dev);
-	int rc = 0;
 
-	dev_info(dev, "%s: Entering into runtime suspend mode:\n",
-		__func__);
-	if (cd->cpdata->flags & PT_CORE_FLAG_SKIP_RUNTIME)
-		return 0;
-
-	if (cd->sleep_state == SS_SLEEP_OFF)
-		cd->runtime = 1;
-
-	rc = pt_core_sleep(cd);
-	if (rc < 0) {
-		pt_debug(dev, DL_ERROR, "%s: Error on sleep\n", __func__);
-		return -EAGAIN;
-	}
+	pt_debug(dev, DL_DEBUG, "%s Skip - probe state %d\n",
+		__func__, cd->core_probe_complete);
 
 	return 0;
 }
@@ -10469,21 +10683,8 @@ static int pt_core_rt_suspend(struct device *dev)
 static int pt_core_rt_resume(struct device *dev)
 {
 	struct pt_core_data *cd = dev_get_drvdata(dev);
-	int rc = 0;
-
-	dev_info(dev, "%s: Entering into runtime resume mode:\n",
-		__func__);
-	if (cd->cpdata->flags & PT_CORE_FLAG_SKIP_RUNTIME)
-		return 0;
-
-	rc = pt_core_wake(cd);
-	if (rc < 0) {
-		pt_debug(dev, DL_ERROR, "%s: Error on wake\n", __func__);
-		return -EAGAIN;
-	}
-
-	if (cd->sleep_state == SS_SLEEP_OFF)
-		cd->runtime = 0;
+	pt_debug(dev, DL_DEBUG, "%s Skip - probe state %d\n",
+		__func__, cd->core_probe_complete);
 
 	return 0;
 }
@@ -10512,20 +10713,23 @@ static int pt_core_suspend_(struct device *dev)
 	pt_debug(dev, DL_INFO, "%s: Entering into suspend mode:\n",
 		__func__);
 	rc = pt_core_sleep(cd);
-	if (rc < 0) {
+	if (rc) {
 		pt_debug(dev, DL_ERROR, "%s: Error on sleep\n", __func__);
 		return -EAGAIN;
 	}
 
-	rc = pt_enable_regulator(cd, false);
+	rc = pt_enable_vdd_regulator(cd, false);
 	if (rc) {
-		dev_err(dev, "%s: Failed to disable regulators: rc=%d\n",
+		dev_err(dev, "%s: Failed to disable vdd regulators: rc=%d\n",
+			__func__, rc);
+	}
+	rc = pt_lpm_regulator(cd->vcc_i2c, I2C_ACTIVE_LOAD_MA);
+	if (rc) {
+		dev_err(dev, "%s: Failed to enter to lpm mode rc=%d\n",
 			__func__, rc);
 	}
-	dev_info(dev, "%s: Sayantan1: Voltage regulators disabled: rc=%d\n",
-		__func__, rc);
 
-	if (!IS_EASY_WAKE_CONFIGURED(cd->easy_wakeup_gesture) && !cd->runtime)
+	if (!IS_EASY_WAKE_CONFIGURED(cd->easy_wakeup_gesture))
 		return 0;
 
 	/* Required to prevent interrupts before bus awake */
@@ -10545,6 +10749,13 @@ static int pt_core_suspend_(struct device *dev)
 	return rc;
 }
 
+static int pt_lpm_regulator(struct regulator *reg, int load_uA)
+{
+
+	return (regulator_count_voltages(reg) > 0) ?
+		regulator_set_load(reg, load_uA) : 0;
+}
+
 /*******************************************************************************
  * FUNCTION: pt_core_suspend
  *
@@ -10562,10 +10773,14 @@ static int pt_core_suspend_(struct device *dev)
 static int pt_core_suspend(struct device *dev)
 {
 	struct pt_core_data *cd = dev_get_drvdata(dev);
+	int rc = 0;
+
 	if (cd->cpdata->flags & PT_CORE_FLAG_SKIP_SYS_SLEEP)
 		return 0;
 
-	return pt_core_suspend_(dev);
+	rc = pt_core_suspend_(dev);
+	pt_debug(dev, DL_WARN, "%s Exit - rc = %d\n", __func__, rc);
+	return 0;
 }
 
 /*******************************************************************************
@@ -10588,15 +10803,23 @@ static int pt_core_resume_(struct device *dev)
 
 	dev_info(dev, "%s: Entering into resume mode:\n",
 		__func__);
-	rc = pt_enable_regulator(cd, true);
+
+	rc = pt_lpm_regulator(cd->vcc_i2c, I2C_ACTIVE_LOAD_MA);
+	if (rc < 0) {
+		dev_err(dev, "%s: Failed to exit lpm mode: rc=%d\n",
+			__func__, rc);
+	}
+
+	rc = pt_enable_vdd_regulator(cd, true);
 	if (rc < 0) {
-		dev_err(dev, "%s: Failed to enable regulators: rc=%d\n",
+		dev_err(dev, "%s: Failed to enable vdd regulators: rc=%d\n",
 			__func__, rc);
 	}
+
 	dev_info(dev, "%s: Voltage regulator enabled: rc=%d\n",
 		__func__, rc);
 
-	if (!IS_EASY_WAKE_CONFIGURED(cd->easy_wakeup_gesture) && !cd->runtime)
+	if (!IS_EASY_WAKE_CONFIGURED(cd->easy_wakeup_gesture))
 		goto exit;
 
 	/*
@@ -10621,11 +10844,60 @@ static int pt_core_resume_(struct device *dev)
 	}
 
 exit:
-	pt_core_wake(cd);
+	rc = pt_core_wake(cd);
+	if (rc) {
+		dev_err(dev, "%s: Failed to wake up: rc=%d\n",
+			__func__, rc);
+		return -EAGAIN;
+	}
 
-	return 0;
+	return rc;
 }
 
+/*******************************************************************************
+ * FUNCTION: resume_offload_work
+ *
+ * SUMMARY: Wrapper function of pt_core_resume_() to avoid TP to be waken/slept
+ *  along with kernel power state even the display is off based on the check of
+ *  TTDL core platform flag.
+ *
+ * RETURN:
+ *	 0 = success
+ *	!0 = failure
+ *
+ * PARAMETERS:
+ *      *dev  - pointer to core device
+ ******************************************************************************/
+static void pt_resume_offload_work(struct work_struct *work)
+
+{
+	int rc = 0;
+	int retry_count = 10;
+	struct pt_core_data *pt_data = container_of(work, struct pt_core_data,
+					resume_offload_work);
+
+	do {
+		retry_count--;
+	rc = pt_core_resume_(pt_data->dev);
+	if (rc < 0)
+		pt_debug(pt_data->dev, DL_ERROR,
+			"%s: Error on wake\n", __func__);
+	} while (retry_count && rc < 0);
+
+#ifdef TOUCH_TO_WAKE_POWER_FEATURE_WORK_AROUND
+	rc = pt_core_easywake_on(pt_data);
+	if (rc < 0) {
+		pt_debug(pt_data->dev, DL_ERROR,
+			"%s: Error on enable touch to wake key\n",
+			__func__);
+		return;
+	}
+	pt_data->fb_state = FB_OFF;
+	pt_debug(pt_data->dev, DL_INFO, "%s End\n", __func__);
+#endif
+}
+
+
 /*******************************************************************************
  * FUNCTION: pt_core_resume
  *
@@ -10643,10 +10915,14 @@ exit:
 static int pt_core_resume(struct device *dev)
 {
 	struct pt_core_data *cd = dev_get_drvdata(dev);
+	int rc = 0;
 	if (cd->cpdata->flags & PT_CORE_FLAG_SKIP_SYS_SLEEP)
 		return 0;
 
-	return pt_core_resume_(dev);
+	queue_work(cd->pt_workqueue, &cd->resume_offload_work);
+	pt_debug(cd->dev, DL_ERROR, "%s End\n", __func__);
+
+	return rc;
 }
 #endif
 
@@ -12398,6 +12674,43 @@ static void pt_setup_early_suspend(struct pt_core_data *cd)
 }
 #elif defined(CONFIG_DRM)
 
+static void pt_resume_work(struct work_struct *work)
+{
+	struct pt_core_data *pt_data = container_of(work, struct pt_core_data,
+					resume_work);
+	int rc = 0;
+
+	if (pt_data->cpdata->flags & PT_CORE_FLAG_SKIP_RUNTIME)
+		return;
+
+	rc = pt_core_easywake_off(pt_data);
+	if (rc < 0) {
+		pt_debug(pt_data->dev, DL_ERROR,
+			"%s: Error on wake\n", __func__);
+	}
+	return;
+}
+
+static void pt_suspend_work(struct work_struct *work)
+{
+	struct pt_core_data *pt_data = container_of(work, struct pt_core_data,
+					suspend_work);
+	int rc = 0;
+
+	pt_debug(pt_data->dev, DL_INFO, "%s Start\n", __func__);
+
+	if (pt_data->cpdata->flags & PT_CORE_FLAG_SKIP_RUNTIME)
+		return;
+
+	rc = pt_core_easywake_on(pt_data);
+	if (rc < 0) {
+		pt_debug(pt_data->dev, DL_ERROR, "%s: Error on sleep\n", __func__);
+		return;
+	}
+	pt_debug(pt_data->dev, DL_INFO, "%s Exit\n", __func__);
+	return;
+}
+
 /*******************************************************************************
  * FUNCTION: drm_notifier_callback
  *
@@ -12433,7 +12746,11 @@ static int drm_notifier_callback(struct notifier_block *self,
 	}
 
 	blank = evdata->data;
-	pt_debug(cd->dev, DL_INFO, "%s: DRM event:%lu,blank:%d", __func__, event, *blank);
+	pt_debug(cd->dev, DL_INFO, "%s: DRM event:%lu,blank:%d fb_state %d sleep state %d ",
+		__func__, event, *blank, cd->fb_state, cd->sleep_state);
+	pt_debug(cd->dev, DL_INFO, "%s: DRM Power - %s - FB state %d ",
+		__func__, (*blank == DRM_PANEL_BLANK_UNBLANK)?"UP":"DOWN", cd->fb_state);
+
 	if (*blank == DRM_PANEL_BLANK_UNBLANK) {
 		pt_debug(cd->dev, DL_INFO, "%s: UNBLANK!\n", __func__);
 		if (event == DRM_PANEL_EARLY_EVENT_BLANK) {
@@ -12441,7 +12758,9 @@ static int drm_notifier_callback(struct notifier_block *self,
 				__func__, event);
 		} else if (event == DRM_PANEL_EVENT_BLANK) {
 			if (cd->fb_state != FB_ON) {
-				call_atten_cb(cd, PT_ATTEN_RESUME, 0);
+				pt_debug(cd->dev, DL_INFO, "%s: Resume notifier called!\n",
+					__func__);
+				queue_work(cd->pt_workqueue, &cd->resume_work);
 #if defined(CONFIG_PM_SLEEP)
 				pt_debug(cd->dev, DL_INFO, "%s: Resume notifier called!\n",
 					__func__);
@@ -12462,7 +12781,8 @@ static int drm_notifier_callback(struct notifier_block *self,
 				if (cd->cpdata->flags & PT_CORE_FLAG_SKIP_RUNTIME)
 					pt_core_suspend_(cd->dev);
 #endif
-				call_atten_cb(cd, PT_ATTEN_SUSPEND, 0);
+				cancel_work_sync(&cd->resume_work);
+				queue_work(cd->pt_workqueue, &cd->suspend_work);
 				cd->fb_state = FB_OFF;
 				pt_debug(cd->dev, DL_INFO, "%s: Suspend notified!\n", __func__);
 			}
@@ -12488,7 +12808,7 @@ exit:
  ******************************************************************************/
 static void pt_setup_drm_notifier(struct pt_core_data *cd)
 {
-	cd->fb_state = FB_ON;
+	cd->fb_state = FB_NONE;
 	cd->fb_notifier.notifier_call = drm_notifier_callback;
 	pt_debug(cd->dev, DL_INFO, "%s: Setting up drm notifier\n", __func__);
 
@@ -12496,6 +12816,17 @@ static void pt_setup_drm_notifier(struct pt_core_data *cd)
 		pt_debug(cd->dev, DL_ERROR,
 			"%s: Active panel not registered!\n", __func__);
 
+	cd->pt_workqueue = create_singlethread_workqueue("ts_wq");
+	if (!cd->pt_workqueue) {
+		pt_debug(cd->dev, DL_ERROR,
+			"%s: worker thread creation failed !\n", __func__);
+	}
+
+	if (cd->pt_workqueue) {
+		INIT_WORK(&cd->resume_work, pt_resume_work);
+		INIT_WORK(&cd->suspend_work, pt_suspend_work);
+	}
+
 	if (active_panel &&
 		drm_panel_notifier_register(active_panel,
 			&cd->fb_notifier) < 0)
@@ -17059,7 +17390,6 @@ int pt_probe(const struct pt_bus_ops *ops, struct device *dev,
 	cd->watchdog_enabled           = 0;
 	cd->startup_retry_count        = 0;
 	cd->core_probe_complete        = 0;
-	cd->runtime                    = 0;
 	cd->fw_system_mode             = FW_SYS_MODE_BOOT;
 	cd->pip_cmd_timeout            = PT_PIP_CMD_DEFAULT_TIMEOUT;
 	cd->pip_cmd_timeout_default    = PT_PIP_CMD_DEFAULT_TIMEOUT;
@@ -17069,6 +17399,7 @@ int pt_probe(const struct pt_bus_ops *ops, struct device *dev,
 	cd->cal_cache_in_host          = PT_FEATURE_DISABLE;
 	cd->multi_chip                 = PT_FEATURE_DISABLE;
 	cd->tthe_hid_usb_format        = PT_FEATURE_DISABLE;
+	cd->sleep_state					= SS_SLEEP_NONE;
 
 	if (cd->cpdata->config_dut_generation == CONFIG_DUT_PIP2_CAPABLE) {
 		cd->set_dut_generation = true;
@@ -17417,6 +17748,7 @@ skip_enum:
 #elif defined(CONFIG_DRM)
 	pt_debug(dev, DL_ERROR, "%s: Probe: Setup drm notifier\n", __func__);
 	pt_setup_drm_notifier(cd);
+	INIT_WORK(&cd->resume_offload_work, pt_resume_offload_work);
 #elif defined(CONFIG_FB)
 	pt_setup_fb_notifier(cd);
 #endif

+ 5 - 4
pt/pt_mt_common.c

@@ -470,13 +470,13 @@ static void pt_mt_send_dummy_event(struct pt_core_data *cd,
 
 	switch (cd->gesture_id) {
 	case GESTURE_DOUBLE_TAP:
-		key_value = KEY_F1;
+		key_value = KEY_WAKEUP;
 		break;
 	case GESTURE_TWO_FINGERS_SLIDE:
-		key_value = KEY_F2;
+		key_value = KEY_WAKEUP;
 		break;
 	case GESTURE_TOUCH_DETECTED:
-		key_value = KEY_F3;
+		key_value = KEY_WAKEUP;
 		break;
 	case GESTURE_PUSH_BUTTON:
 		key_value = KEY_F4;
@@ -499,7 +499,7 @@ static void pt_mt_send_dummy_event(struct pt_core_data *cd,
 
 	if (key_value > 0) {
 		input_report_key(md->input, key_value, 1);
-		mdelay(10);
+		input_sync(md->input);
 		input_report_key(md->input, key_value, 0);
 		input_sync(md->input);
 	}
@@ -837,6 +837,7 @@ static int pt_setup_input_device(struct device *dev)
 	input_set_capability(md->input, EV_KEY, KEY_F6);
 	input_set_capability(md->input, EV_KEY, KEY_F7);
 	input_set_capability(md->input, EV_KEY, KEY_F8);
+	input_set_capability(md->input, EV_KEY, KEY_WAKEUP);
 #endif
 	return rc;
 }

+ 12 - 2
pt/pt_regs.h

@@ -143,6 +143,8 @@
 #define TT7XXX_EXAMPLE
 #endif
 
+#define TOUCH_TO_WAKE_POWER_FEATURE_WORK_AROUND
+
 /*
  * The largest PIP message is the PIP2 FILE_WRITE which has:
  *     2 byte register
@@ -175,7 +177,7 @@ enum PT_DEBUG_LEVEL {
 	DL_DEBUG	= 4,
 	DL_MAX
 };
-#define PT_INITIAL_DEBUG_LEVEL DL_WARN
+#define PT_INITIAL_DEBUG_LEVEL DL_MAX
 
 /* Startup DUT enum status bitmask */
 enum PT_STARTUP_STATUS {
@@ -1103,13 +1105,17 @@ enum pt_atten_type {
 };
 
 enum pt_sleep_state {
+	SS_SLEEP_NONE,
 	SS_SLEEP_OFF,
 	SS_SLEEP_ON,
 	SS_SLEEPING,
 	SS_WAKING,
+	SS_EASY_WAKING_ON,
+	SS_EASY_WAKING_OFF,
 };
 
 enum pt_fb_state {
+	FB_NONE,
 	FB_ON,
 	FB_OFF,
 };
@@ -1440,6 +1446,11 @@ struct pt_core_data {
 	struct list_head module_list; /* List of probed modules */
 	char core_id[20];
 	struct device *dev;
+	struct workqueue_struct *pt_workqueue;
+	struct work_struct	resume_offload_work;
+	struct work_struct	suspend_work;
+	struct work_struct	resume_work;
+
 	struct list_head atten_list[PT_ATTEN_NUM_ATTEN];
 	struct list_head param_list;
 	struct mutex module_list_lock;
@@ -1467,7 +1478,6 @@ struct pt_core_data {
 	bool irq_wake;
 	bool irq_disabled;
 	bool hw_detected;
-	bool runtime;
 	u8 easy_wakeup_gesture;
 #ifdef EASYWAKE_TSG6
 	u8 gesture_id;