From 3e007f7d8717ea2ffd9240415f0a1144270ffb34 Mon Sep 17 00:00:00 2001 From: Pratham Pratap Date: Fri, 10 Jan 2020 18:39:47 +0530 Subject: [PATCH] usb: dwc3: Avoid CLR block DB if run/stop is cleared It is required to SET block doorbell to GSI to avoid USB wrapper from ringing doorbell before queuing stop xfer command to GSI endpoint as part of stopping controller and CLR block doorbell to GSI after queuing start xfer command to GSI endpoint. Since ipa_work_handler runs in workqueue context there is a possiblity that CLR block doorbell will happen even after run/stop is cleared which may lead to SMMU fault. Avoid this by adding a check for pullups_connected before clearing block doorbell. Change-Id: Iedb8a96da197834169bdabae6381c974d50c95de Signed-off-by: Pratham Pratap --- drivers/usb/dwc3/dwc3-msm.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c index 488f081c54ea..4e6dba2230be 100644 --- a/drivers/usb/dwc3/dwc3-msm.c +++ b/drivers/usb/dwc3/dwc3-msm.c @@ -1664,6 +1664,7 @@ static void gsi_set_clear_dbell(struct usb_ep *ep, struct dwc3 *dwc = dep->dwc; struct dwc3_msm *mdwc = dev_get_drvdata(dwc->dev->parent); + dbg_log_string("block_db(%d)", block_db); dwc3_msm_write_reg_field(mdwc->base, GSI_GENERAL_CFG_REG(mdwc->gsi_reg), BLOCK_GSI_WR_GO_MASK, block_db); } @@ -1798,6 +1799,14 @@ int usb_gsi_ep_op(struct usb_ep *ep, void *op_data, enum gsi_ep_op op) break; case GSI_EP_OP_SET_CLR_BLOCK_DBL: block_db = *((bool *)op_data); + spin_lock_irqsave(&dwc->lock, flags); + if (!dwc->pullups_connected && !block_db) { + dbg_log_string("No Pullup\n"); + spin_unlock_irqrestore(&dwc->lock, flags); + return -ESHUTDOWN; + } + + spin_unlock_irqrestore(&dwc->lock, flags); gsi_set_clear_dbell(ep, block_db); break; case GSI_EP_OP_CHECK_FOR_SUSPEND: