usb: gsi: Allow suspend upon previous suspend failure in gsi_suspend
Driver marks func_is_suspended flag to true and queue suspend work in
gsi_suspend. suspend_work may fail the suspend if the LINK is not in U3.
During host hibernation testing gsi_suspend failing as LINK is not in U3
and next time when bus suspend initiated driver checking for
func_is_suspended flag and bailout the suspend with out queuing suspend
work. This causes a mismatch of usage count and usb not entering to
low power mode.
To fix this issue, Check for the state in gsi_suspend. If the state is
!= suspended or != suspend_in_progress then don't bail out the suspend.
Change-Id: Iade9ba330b232261e205cd821ef42053297befbb
Signed-off-by: Chandana Kishori Chiluveru <cchiluve@codeaurora.org>
diff --git a/drivers/usb/gadget/function/f_gsi.c b/drivers/usb/gadget/function/f_gsi.c
index f3ad669..89f1ba2 100644
--- a/drivers/usb/gadget/function/f_gsi.c
+++ b/drivers/usb/gadget/function/f_gsi.c
@@ -2480,8 +2480,12 @@
bool block_db;
struct f_gsi *gsi = func_to_gsi(f);
- /* Check if function is already suspended in gsi_func_suspend() */
- if (f->func_is_suspended) {
+ /* Check if function is already suspended in gsi_func_suspend()
+ * Or func_suspend would have bailed out earlier if func_remote_wakeup
+ * wasn't enabled.
+ */
+ if (f->func_is_suspended && (gsi->d_port.sm_state == STATE_SUSPENDED ||
+ gsi->d_port.sm_state == STATE_SUSPEND_IN_PROGRESS)) {
log_event_dbg("%s: func already suspended, return\n", __func__);
return;
}