diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c index 3583317a3d3f..06af44cc05dd 100644 --- a/drivers/usb/dwc3/dwc3-msm.c +++ b/drivers/usb/dwc3/dwc3-msm.c @@ -1180,7 +1180,7 @@ static void gsi_set_clear_dbell(struct usb_ep *ep, * * @usb_ep - pointer to usb_ep instance to access DWC3 regs */ -static bool gsi_check_ready_to_suspend(struct usb_ep *ep) +static bool gsi_check_ready_to_suspend(struct usb_ep *ep, bool f_suspend) { u32 timeout = 1500; u32 reg = 0; @@ -1196,11 +1196,13 @@ static bool gsi_check_ready_to_suspend(struct usb_ep *ep) return false; } } - - reg = dwc3_readl(dwc->regs, DWC3_DSTS); - if (DWC3_DSTS_USBLNKST(reg) != DWC3_LINK_STATE_U3) { - dev_err(mdwc->dev, "Unable to suspend GSI ch\n"); - return false; + /* Check for U3 only if we are not handling Function Suspend */ + if (!f_suspend) { + reg = dwc3_readl(dwc->regs, DWC3_DSTS); + if (DWC3_DSTS_USBLNKST(reg) != DWC3_LINK_STATE_U3) { + dev_err(mdwc->dev, "Unable to suspend GSI ch\n"); + return false; + } } return true; @@ -1226,7 +1228,7 @@ static int dwc3_msm_gsi_ep_op(struct usb_ep *ep, struct dwc3_msm *mdwc = dev_get_drvdata(dwc->dev->parent); struct usb_gsi_request *request; struct gsi_channel_info *ch_info; - bool block_db; + bool block_db, f_suspend; switch (op) { case GSI_EP_OP_PREPARE_TRBS: @@ -1286,7 +1288,8 @@ static int dwc3_msm_gsi_ep_op(struct usb_ep *ep, break; case GSI_EP_OP_CHECK_FOR_SUSPEND: dev_dbg(mdwc->dev, "EP_OP_CHECK_FOR_SUSPEND\n"); - ret = gsi_check_ready_to_suspend(ep); + f_suspend = *((bool *)op_data); + ret = gsi_check_ready_to_suspend(ep, f_suspend); break; default: dev_err(mdwc->dev, "%s: Invalid opcode GSI EP\n", __func__);