From b3295b2c12bd83c71a38b08b9e27b8b3f40cf8e0 Mon Sep 17 00:00:00 2001 From: Hemant Kumar Date: Wed, 13 Feb 2019 12:42:29 -0800 Subject: [PATCH] usb: gadget: f_gsi: Handle IPA remote wakeup notification properly Upon bus suspend when IPA requests for usb remote wake up, it is not allowing enough time for the host to wakeup from U3. IPA is continuously trying to wakeup the host and eventually resets the bus. Fix this issue by adding a flag to check the status of usb remote wakeup and ignores the request from IPA if it is in progress. Change-Id: Id55928b7f5d3ae7f282a3b8db44949d396db0ddd Signed-off-by: Hemant Kumar Signed-off-by: Mayank Rana --- drivers/usb/gadget/function/f_gsi.c | 12 ++++++++++-- drivers/usb/gadget/function/f_gsi.h | 4 +++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/drivers/usb/gadget/function/f_gsi.c b/drivers/usb/gadget/function/f_gsi.c index 10922485475e..84790d968bd1 100644 --- a/drivers/usb/gadget/function/f_gsi.c +++ b/drivers/usb/gadget/function/f_gsi.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. */ #include @@ -149,6 +149,8 @@ static int gsi_wakeup_host(struct f_gsi *gsi) return -ENODEV; } + gsi->rwake_inprogress = true; + /* * In Super-Speed mode, remote wakeup is not allowed for suspended * functions which have been disallowed by the host to issue Function @@ -171,6 +173,9 @@ static int gsi_wakeup_host(struct f_gsi *gsi) else if (ret) log_event_err("wakeup failed. ret=%d.", ret); + if (ret) + gsi->rwake_inprogress = false; + return ret; } @@ -455,7 +460,8 @@ static int ipa_usb_notify_cb(enum ipa_usb_notify_event event, break; case IPA_USB_REMOTE_WAKEUP: - gsi_wakeup_host(gsi); + if (!gsi->rwake_inprogress) + gsi_wakeup_host(gsi); break; case IPA_USB_SUSPEND_COMPLETED: @@ -2662,6 +2668,8 @@ static void gsi_resume(struct usb_function *f) gsi->params->state = RNDIS_DATA_INITIALIZED; } + gsi->rwake_inprogress = false; + post_event(&gsi->d_port, EVT_RESUMED); queue_delayed_work(gsi->d_port.ipa_usb_wq, &gsi->d_port.usb_ipa_w, 0); diff --git a/drivers/usb/gadget/function/f_gsi.h b/drivers/usb/gadget/function/f_gsi.h index ccb536e18088..45f636fcbf4e 100644 --- a/drivers/usb/gadget/function/f_gsi.h +++ b/drivers/usb/gadget/function/f_gsi.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. */ #ifndef _F_GSI_H @@ -283,6 +283,8 @@ struct f_gsi { void *ipc_log_ctxt; bool rmnet_dtr_status; + bool rwake_inprogress; + /* To test remote wakeup using debugfs */ struct timer_list gsi_rw_timer; u8 debugfs_rw_timer_enable;