summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorli feng <li1.feng@intel.com>2021-02-19 22:40:11 -0800
committerCommit Bot <commit-bot@chromium.org>2021-02-26 18:08:34 +0000
commit55d7292a1ccfe85cf20d3dc483cdff4093bdcbae (patch)
tree89f9f4bb88207b6c92c43d3ddab9201918ae1f17
parentaabb2eaae226e915eeac8158c60f4c83f621f6ac (diff)
downloadchrome-ec-55d7292a1ccfe85cf20d3dc483cdff4093bdcbae.tar.gz
retimer: Fix issues in suspending PD task during retimer scan
When AP scans retimer for firmware update, it requests EC to suspend PD task of NDA (no device attached) PD ports. Then pd_set_suspend() sets suspend flag TC_FLAGS_REQUEST_SUSPEND, and wakes up PD task to check new flag. However in this case, the flow exits early to avoid deadlock when running from task which is going to be suspended. We expect next time PD task runs (after 5ms), it can detect this flag and suspend itself. This is found to be working only when the PD task does not enter low power mode immediately after this flag is set. In cases, where the PD task enters low power mode, PD is not suspended and so AP could not scan the retimer successfully. Move to hook_call to suspend PD task, so pd_set_suspend() can execute all the way to wake up PD task, and process the suspend flag. BUG=b:180573726 BRANCH=none TEST=Tested Voxel DVT, together with coreboot and kernel changes, make sure retimers of NDA ports are in sysfs entries. Coreboot changes are merged. Kernel patches list is: https://chromium-review.googlesource.com/c/chromiumos/ third_party/kernel/+/2670719 Signed-off-by: li feng <li1.feng@intel.com> Change-Id: I98bf2a028ee8fe3623f2e465a02a6edeff1b6e3f Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2709560 Reviewed-by: Rajmohan Mani <rajmohan.mani@intel.com> Reviewed-by: Keith Short <keithshort@chromium.org>
-rw-r--r--common/usbc/usb_retimer_fw_update.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/common/usbc/usb_retimer_fw_update.c b/common/usbc/usb_retimer_fw_update.c
index f85a197c40..5d420ad991 100644
--- a/common/usbc/usb_retimer_fw_update.c
+++ b/common/usbc/usb_retimer_fw_update.c
@@ -46,6 +46,9 @@
*
*/
+#define SUSPEND 1
+#define RESUME 0
+
/* Track current port AP requested to update retimer firmware */
static int cur_port;
static int last_op; /* Operation received from AP via ACPI_WRITE */
@@ -78,14 +81,27 @@ int usb_retimer_fw_update_get_result(void)
return result;
}
+static void deferred_pd_suspend(void)
+{
+ pd_set_suspend(cur_port, SUSPEND);
+}
+DECLARE_DEFERRED(deferred_pd_suspend);
+
void usb_retimer_fw_update_process_op_cb(int port)
{
switch (last_op) {
case USB_RETIMER_FW_UPDATE_SUSPEND_PD:
- pd_set_suspend(port, 1);
+ /*
+ * If the port has entered low power mode, the PD task
+ * is paused and will not complete processing of
+ * pd_set_suspend(). Move pd_set_suspend() into a deferred
+ * call so that it runs from the HOOKS task and can generate
+ * a wake event to the PD task and enter suspended mode.
+ */
+ hook_call_deferred(&deferred_pd_suspend_data, 0);
break;
case USB_RETIMER_FW_UPDATE_RESUME_PD:
- pd_set_suspend(port, 0);
+ pd_set_suspend(port, RESUME);
break;
case USB_RETIMER_FW_UPDATE_GET_MUX:
last_mux_result = usb_mux_get(port);