Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fc37523c authored by qctecmdr Service's avatar qctecmdr Service Committed by Gerrit - the friendly Code Review server
Browse files

Merge "USB: dwc3-msm: Perform DBM config/unconfig under spinlock protection"

parents f6c5d0dd 3ae9f41c
Loading
Loading
Loading
Loading
+14 −13
Original line number Diff line number Diff line
@@ -342,7 +342,7 @@ static void dwc3_free_event_buffers(struct dwc3 *dwc)
		dwc3_free_one_event_buffer(dwc, evt);

	/* free GSI related event buffers */
	dwc3_notify_event(dwc, DWC3_GSI_EVT_BUF_FREE);
	dwc3_notify_event(dwc, DWC3_GSI_EVT_BUF_FREE, 0);
}

/**
@@ -365,7 +365,7 @@ static int dwc3_alloc_event_buffers(struct dwc3 *dwc, unsigned length)
	dwc->ev_buf = evt;

	/* alloc GSI related event buffers */
	dwc3_notify_event(dwc, DWC3_GSI_EVT_BUF_ALLOC);
	dwc3_notify_event(dwc, DWC3_GSI_EVT_BUF_ALLOC, 0);
	return 0;
}

@@ -390,7 +390,7 @@ int dwc3_event_buffers_setup(struct dwc3 *dwc)
	dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), 0);

	/* setup GSI related event buffers */
	dwc3_notify_event(dwc, DWC3_GSI_EVT_BUF_SETUP);
	dwc3_notify_event(dwc, DWC3_GSI_EVT_BUF_SETUP, 0);
	return 0;
}

@@ -409,7 +409,7 @@ static void dwc3_event_buffers_cleanup(struct dwc3 *dwc)
	dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), 0);

	/* cleanup GSI related event buffers */
	dwc3_notify_event(dwc, DWC3_GSI_EVT_BUF_CLEANUP);
	dwc3_notify_event(dwc, DWC3_GSI_EVT_BUF_CLEANUP, 0);
}

static int dwc3_alloc_scratch_buffers(struct dwc3 *dwc)
@@ -879,7 +879,7 @@ int dwc3_core_init(struct dwc3 *dwc)
		dwc3_writel(dwc->regs, DWC3_GUCTL3, reg);
	}

	dwc3_notify_event(dwc, DWC3_CONTROLLER_POST_RESET_EVENT);
	dwc3_notify_event(dwc, DWC3_CONTROLLER_POST_RESET_EVENT, 0);

	/*
	 * Workaround for STAR 9001198391 which affects dwc3 core
@@ -1014,19 +1014,20 @@ static void __maybe_unused dwc3_core_exit_mode(struct dwc3 *dwc)
	}
}

static void (*notify_event)(struct dwc3 *, unsigned int);
void dwc3_set_notifier(void (*notify)(struct dwc3 *, unsigned int))
static void (*notify_event)(struct dwc3 *, unsigned int, unsigned int);
void dwc3_set_notifier(void (*notify)(struct dwc3 *, unsigned int,
							unsigned int))
{
	notify_event = notify;
}
EXPORT_SYMBOL(dwc3_set_notifier);

int dwc3_notify_event(struct dwc3 *dwc, unsigned int event)
int dwc3_notify_event(struct dwc3 *dwc, unsigned int event, unsigned int value)
{
	int ret = 0;

	if (notify_event)
		notify_event(dwc, event);
		notify_event(dwc, event, value);
	else
		ret = -ENODEV;

@@ -1440,7 +1441,7 @@ static int dwc3_runtime_suspend(struct device *dev)
	int		ret;

	/* Check if platform glue driver handling PM, if not then handle here */
	if (!dwc3_notify_event(dwc, DWC3_CORE_PM_SUSPEND_EVENT))
	if (!dwc3_notify_event(dwc, DWC3_CORE_PM_SUSPEND_EVENT, 0))
		return 0;

	if (dwc3_runtime_checks(dwc))
@@ -1461,7 +1462,7 @@ static int dwc3_runtime_resume(struct device *dev)
	int		ret;

	/* Check if platform glue driver handling PM, if not then handle here */
	if (!dwc3_notify_event(dwc, DWC3_CORE_PM_RESUME_EVENT))
	if (!dwc3_notify_event(dwc, DWC3_CORE_PM_RESUME_EVENT, 0))
		return 0;

	device_init_wakeup(dev, false);
@@ -1517,7 +1518,7 @@ static int dwc3_suspend(struct device *dev)
	int		ret;

	/* Check if platform glue driver handling PM, if not then handle here */
	if (!dwc3_notify_event(dwc, DWC3_CORE_PM_SUSPEND_EVENT))
	if (!dwc3_notify_event(dwc, DWC3_CORE_PM_SUSPEND_EVENT, 0))
		return 0;

	ret = dwc3_suspend_common(dwc);
@@ -1535,7 +1536,7 @@ static int dwc3_resume(struct device *dev)
	int		ret;

	/* Check if platform glue driver handling PM, if not then handle here */
	if (!dwc3_notify_event(dwc, DWC3_CORE_PM_RESUME_EVENT))
	if (!dwc3_notify_event(dwc, DWC3_CORE_PM_RESUME_EVENT, 0))
		return 0;

	pinctrl_pm_select_default_state(dev);
+18 −15
Original line number Diff line number Diff line
@@ -843,12 +843,13 @@ struct dwc3_scratchpad_array {
#define DWC3_CONTROLLER_NOTIFY_OTG_EVENT		6
#define DWC3_CONTROLLER_SET_CURRENT_DRAW_EVENT		7
#define DWC3_CONTROLLER_RESTART_USB_SESSION		8
#define DWC3_CONTROLLER_NOTIFY_DISABLE_UPDXFER		9

/* USB GSI event buffer related notification */
#define DWC3_GSI_EVT_BUF_ALLOC			9
#define DWC3_GSI_EVT_BUF_SETUP			10
#define DWC3_GSI_EVT_BUF_CLEANUP		11
#define DWC3_GSI_EVT_BUF_FREE			12
#define DWC3_GSI_EVT_BUF_ALLOC			10
#define DWC3_GSI_EVT_BUF_SETUP			11
#define DWC3_GSI_EVT_BUF_CLEANUP		12
#define DWC3_GSI_EVT_BUF_FREE			13

#define MAX_INTR_STATS				10

@@ -1457,7 +1458,9 @@ static inline void dwc3_ulpi_exit(struct dwc3 *dwc)
#endif

extern void dwc3_set_notifier(
		void (*notify)(struct dwc3 *dwc3, unsigned int event));
extern int dwc3_notify_event(struct dwc3 *dwc3, unsigned int event);
		void (*notify)(struct dwc3 *dwc3, unsigned int event,
						unsigned int value));
extern int dwc3_notify_event(struct dwc3 *dwc3, unsigned int event,
						unsigned int value);
void dwc3_usb3_phy_suspend(struct dwc3 *dwc, int suspend);
#endif /* __DRIVERS_USB_DWC3_CORE_H */
+40 −20
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@ enum dbm_reg {
	DBM_HW_TRB2_EP,
	DBM_HW_TRB3_EP,
	DBM_PIPE_CFG,
	DBM_DISABLE_UPDXFER,
	DBM_SOFT_RESET,
	DBM_GEN_CFG,
	DBM_GEVNTADR_LSB,
@@ -101,6 +102,7 @@ static const struct dbm_reg_data dbm_1_5_regtable[] = {
	[DBM_HW_TRB2_EP]	= { 0x0240, 0x4 },
	[DBM_HW_TRB3_EP]	= { 0x0250, 0x4 },
	[DBM_PIPE_CFG]		= { 0x0274, 0x0 },
	[DBM_DISABLE_UPDXFER]	= { 0x0298, 0x0 },
	[DBM_SOFT_RESET]	= { 0x020C, 0x0 },
	[DBM_GEN_CFG]		= { 0x0210, 0x0 },
	[DBM_GEVNTADR_LSB]	= { 0x0260, 0x0 },
@@ -188,7 +190,7 @@ static int find_matching_dbm_ep(struct dbm *dbm, u8 usb_ep)
		if (dbm->ep_num_mapping[i] == usb_ep)
			return i;

	pr_err("%s: No DBM EP matches USB EP %d", __func__, usb_ep);
	pr_debug("%s: No DBM EP matches USB EP %d", __func__, usb_ep);
	return -ENODEV; /* Not found */
}

@@ -287,6 +289,7 @@ int dbm_ep_config(struct dbm *dbm, u8 usb_ep, u8 bam_pipe, bool producer,
{
	int dbm_ep;
	u32 ep_cfg;
	u32 data;

	if (!dbm) {
		pr_err("%s: dbm pointer is NULL!\n", __func__);
@@ -308,9 +311,6 @@ int dbm_ep_config(struct dbm *dbm, u8 usb_ep, u8 bam_pipe, bool producer,
		return -ENODEV;
	}

	/* First, reset the dbm endpoint */
	ep_soft_reset(dbm, dbm_ep, 0);

	/* Set ioc bit for dbm_ep if needed */
	msm_dbm_write_reg_field(dbm, DBM_DBG_CNFG,
		DBM_ENABLE_IOC_MASK & 1 << dbm_ep, ioc ? 1 : 0);
@@ -333,6 +333,10 @@ int dbm_ep_config(struct dbm *dbm, u8 usb_ep, u8 bam_pipe, bool producer,

	msm_dbm_write_ep_reg_field(dbm, DBM_EP_CFG, dbm_ep, DBM_EN_EP, 1);

	data = msm_dbm_read_reg(dbm, DBM_DISABLE_UPDXFER);
	data &= ~(0x1 << dbm_ep);
	msm_dbm_write_reg(dbm, DBM_DISABLE_UPDXFER, data);

	return dbm_ep;
}

@@ -377,7 +381,7 @@ int dbm_ep_unconfig(struct dbm *dbm, u8 usb_ep)
	dbm_ep = find_matching_dbm_ep(dbm, usb_ep);

	if (dbm_ep < 0) {
		pr_err("usb ep index %d has no corresponding dbm ep\n", usb_ep);
		pr_debug("usb ep index %d has no corespondng dbm ep\n", usb_ep);
		return -ENODEV;
	}

@@ -387,23 +391,10 @@ int dbm_ep_unconfig(struct dbm *dbm, u8 usb_ep)
	data &= (~0x1);
	msm_dbm_write_ep_reg(dbm, DBM_EP_CFG, dbm_ep, data);

	/* Reset the dbm endpoint */
	ep_soft_reset(dbm, dbm_ep, true);
	/*
	 * The necessary delay between asserting and deasserting the dbm ep
	 * reset is based on the number of active endpoints. If there is more
	 * than one endpoint, a 1 msec delay is required. Otherwise, a shorter
	 * delay will suffice.
	 *
	 * As this function can be called in atomic context, sleeping variants
	 * for delay are not possible - albeit a 1ms delay.
	 * ep_soft_reset is not required during disconnect as pipe reset on
	 * next connect will take care of the same.
	 */
	if (dbm_get_num_of_eps_configured(dbm) > 1)
		udelay(1000);
	else
		udelay(10);
	ep_soft_reset(dbm, dbm_ep, false);

	return 0;
}

@@ -445,6 +436,35 @@ int dbm_event_buffer_config(struct dbm *dbm, u32 addr_lo, u32 addr_hi, int size)
	return 0;
}

/**
 * Disable update xfer before queueing stop xfer command to USB3 core.
 *
 * @usb_ep - USB physical EP number.
 *
 */
int dwc3_dbm_disable_update_xfer(struct dbm *dbm, u8 usb_ep)
{
	u32 data;
	int dbm_ep;

	if (!dbm) {
		pr_err("%s: dbm pointer is NULL!\n", __func__);
		return -EPERM;
	}

	dbm_ep = find_matching_dbm_ep(dbm, usb_ep);

	if (dbm_ep < 0) {
		pr_err("usb ep index %d has no corresponding dbm ep\n", usb_ep);
		return -ENODEV;
	}

	data = msm_dbm_read_reg(dbm, DBM_DISABLE_UPDXFER);
	data |= (0x1 << dbm_ep);
	msm_dbm_write_reg(dbm, DBM_DISABLE_UPDXFER, data);

	return 0;
}

int dbm_data_fifo_config(struct dbm *dbm, u8 dep_num, unsigned long addr,
				u32 size, u8 dst_pipe_idx)
+1 −0
Original line number Diff line number Diff line
@@ -65,6 +65,7 @@ int dbm_event_buffer_config(struct dbm *dbm, u32 addr_lo, u32 addr_hi,
				int size);
int dbm_data_fifo_config(struct dbm *dbm, u8 dep_num, unsigned long addr,
				u32 size, u8 dst_pipe_idx);
int dwc3_dbm_disable_update_xfer(struct dbm *dbm, u8 usb_ep);
void dbm_set_speed(struct dbm *dbm, bool speed);
void dbm_enable(struct dbm *dbm);
int dbm_ep_soft_reset(struct dbm *dbm, u8 usb_ep, bool enter_reset);
+140 −73
Original line number Diff line number Diff line
@@ -286,7 +286,8 @@ struct dwc3_msm {

static void dwc3_pwr_event_handler(struct dwc3_msm *mdwc);
static int dwc3_msm_gadget_vbus_draw(struct dwc3_msm *mdwc, unsigned int mA);
static void dwc3_msm_notify_event(struct dwc3 *dwc, unsigned int event);
static void dwc3_msm_notify_event(struct dwc3 *dwc, unsigned int event,
						unsigned int value);
static int dwc3_restart_usb_host_mode(struct notifier_block *nb,
					unsigned long event, void *ptr);

@@ -442,6 +443,16 @@ static inline bool dwc3_msm_is_superspeed(struct dwc3_msm *mdwc)
	return dwc3_msm_is_dev_superspeed(mdwc);
}

static int dwc3_msm_dbm_disable_updxfer(struct dwc3 *dwc, u8 usb_ep)
{
	struct dwc3_msm *mdwc = dev_get_drvdata(dwc->dev->parent);

	dev_dbg(mdwc->dev, "%s\n", __func__);
	dwc3_dbm_disable_update_xfer(mdwc->dbm, usb_ep);

	return 0;
}

#if IS_ENABLED(CONFIG_USB_DWC3_GADGET) || IS_ENABLED(CONFIG_USB_DWC3_DUAL_ROLE)
/**
 * Configure the DBM with the BAM's data fifo.
@@ -697,59 +708,89 @@ static int dwc3_msm_ep_queue(struct usb_ep *ep,
	struct dwc3_msm_req_complete *req_complete;
	unsigned long flags;
	int ret = 0, size;
	u8 bam_pipe;
	bool producer;
	bool disable_wb;
	bool internal_mem;
	bool ioc;
	bool superspeed;

	/*
	 * We must obtain the lock of the dwc3 core driver,
	 * including disabling interrupts, so we will be sure
	 * that we are the only ones that configure the HW device
	 * core and ensure that we queuing the request will finish
	 * as soon as possible so we will release back the lock.
	 */
	spin_lock_irqsave(&dwc->lock, flags);
	if (!dep->endpoint.desc) {
		dev_err(mdwc->dev,
			"%s: trying to queue request %pK to disabled ep %s\n",
			__func__, request, ep->name);
		spin_unlock_irqrestore(&dwc->lock, flags);
		return -EPERM;
	}

	if (!mdwc->original_ep_ops[dep->number]) {
		dev_err(mdwc->dev,
			"ep [%s,%d] was unconfigured as msm endpoint\n",
			ep->name, dep->number);
		spin_unlock_irqrestore(&dwc->lock, flags);
		return -EINVAL;
	}

	if (!request) {
		dev_err(mdwc->dev, "%s: request is NULL\n", __func__);
		spin_unlock_irqrestore(&dwc->lock, flags);
		return -EINVAL;
	}

	if (!(request->udc_priv & MSM_SPS_MODE)) {
		/* Not SPS mode, call original queue */
		dev_vdbg(mdwc->dev, "%s: not sps mode, use regular queue\n",
		dev_err(mdwc->dev, "%s: sps mode is not set\n",
					__func__);

		return (mdwc->original_ep_ops[dep->number])->queue(ep,
								request,
								gfp_flags);
		spin_unlock_irqrestore(&dwc->lock, flags);
		return -EINVAL;
	}

	/* HW restriction regarding TRB size (8KB) */
	if (req->request.length < 0x2000) {
		dev_err(mdwc->dev, "%s: Min TRB size is 8KB\n", __func__);
		spin_unlock_irqrestore(&dwc->lock, flags);
		return -EINVAL;
	}

	if (dep->number == 0 || dep->number == 1) {
		dev_err(mdwc->dev,
			"%s: trying to queue dbm request %pK to ep %s\n",
			__func__, request, ep->name);
		spin_unlock_irqrestore(&dwc->lock, flags);
		return -EPERM;
	}

	if (dep->trb_dequeue != dep->trb_enqueue
					|| !list_empty(&dep->pending_list)
					|| !list_empty(&dep->started_list)) {
		dev_err(mdwc->dev,
			"%s: trying to queue dbm request %pK tp ep %s\n",
			__func__, request, ep->name);
		spin_unlock_irqrestore(&dwc->lock, flags);
		return -EPERM;
	}
	dep->trb_dequeue = 0;
	dep->trb_enqueue = 0;

	/*
	 * Override req->complete function, but before doing that,
	 * store it's original pointer in the req_complete_list.
	 */
	req_complete = kzalloc(sizeof(*req_complete), gfp_flags);
	if (!req_complete)

	if (!req_complete) {
		dev_err(mdwc->dev, "%s: not enough memory\n", __func__);
		spin_unlock_irqrestore(&dwc->lock, flags);
		return -ENOMEM;
	}

	req_complete->req = request;
	req_complete->orig_complete = request->complete;
	list_add_tail(&req_complete->list_item, &mdwc->req_complete_list);
	request->complete = dwc3_msm_req_complete_func;

	/*
	 * Configure the DBM endpoint
	 */
	bam_pipe = request->udc_priv & MSM_PIPE_ID_MASK;
	producer = ((request->udc_priv & MSM_PRODUCER) ? true : false);
	disable_wb = ((request->udc_priv & MSM_DISABLE_WB) ? true : false);
	internal_mem = ((request->udc_priv & MSM_INTERNAL_MEM) ? true : false);
	ioc = ((request->udc_priv & MSM_ETD_IOC) ? true : false);

	ret = dbm_ep_config(mdwc->dbm, dep->number, bam_pipe, producer,
				disable_wb, internal_mem, ioc);
	if (ret < 0) {
		dev_err(mdwc->dev,
			"error %d after calling dbm_ep_config\n", ret);
		return ret;
	}

	dev_vdbg(dwc->dev, "%s: queing request %p to ep %s length %d\n",
			__func__, request, ep->name, request->length);
	size = dwc3_msm_read_reg(mdwc->base, DWC3_GEVNTSIZ(0));
@@ -758,44 +799,6 @@ static int dwc3_msm_ep_queue(struct usb_ep *ep,
		dwc3_msm_read_reg(mdwc->base, DWC3_GEVNTADRHI(0)),
		DWC3_GEVNTSIZ_SIZE(size));

	/*
	 * We must obtain the lock of the dwc3 core driver,
	 * including disabling interrupts, so we will be sure
	 * that we are the only ones that configure the HW device
	 * core and ensure that we queuing the request will finish
	 * as soon as possible so we will release back the lock.
	 */
	spin_lock_irqsave(&dwc->lock, flags);
	if (!dep->endpoint.desc) {
		dev_err(mdwc->dev,
			"%s: trying to queue request %p to disabled ep %s\n",
			__func__, request, ep->name);
		ret = -EPERM;
		goto err;
	}

	if (dep->number == 0 || dep->number == 1) {
		dev_err(mdwc->dev,
			"%s: trying to queue dbm request %p to control ep %s\n",
			__func__, request, ep->name);
		ret = -EPERM;
		goto err;
	}


	if (dep->trb_dequeue != dep->trb_enqueue ||
			!list_empty(&dep->pending_list)
			|| !list_empty(&dep->started_list)) {
		dev_err(mdwc->dev,
			"%s: trying to queue dbm request %p tp ep %s\n",
			__func__, request, ep->name);
		ret = -EPERM;
		goto err;
	} else {
		dep->trb_dequeue = 0;
		dep->trb_enqueue = 0;
	}

	ret = __dwc3_msm_ep_queue(dep, req);
	if (ret < 0) {
		dev_err(mdwc->dev,
@@ -1471,37 +1474,68 @@ static int dwc3_msm_gsi_ep_op(struct usb_ep *ep,
 *
 * @return int - 0 on success, negetive on error.
 */
int msm_ep_config(struct usb_ep *ep)
int msm_ep_config(struct usb_ep *ep, struct usb_request *request)
{
	struct dwc3_ep *dep = to_dwc3_ep(ep);
	struct dwc3 *dwc = dep->dwc;
	struct dwc3_msm *mdwc = dev_get_drvdata(dwc->dev->parent);
	struct usb_ep_ops *new_ep_ops;
	int ret = 0;
	u8 bam_pipe;
	bool producer;
	bool disable_wb;
	bool internal_mem;
	bool ioc;
	unsigned long flags;


	spin_lock_irqsave(&dwc->lock, flags);
	/* Save original ep ops for future restore*/
	if (mdwc->original_ep_ops[dep->number]) {
		dev_err(mdwc->dev,
			"ep [%s,%d] already configured as msm endpoint\n",
			ep->name, dep->number);
		spin_unlock_irqrestore(&dwc->lock, flags);
		return -EPERM;
	}
	mdwc->original_ep_ops[dep->number] = ep->ops;

	/* Set new usb ops as we like */
	new_ep_ops = kzalloc(sizeof(struct usb_ep_ops), GFP_ATOMIC);
	if (!new_ep_ops)
	if (!new_ep_ops) {
		spin_unlock_irqrestore(&dwc->lock, flags);
		return -ENOMEM;
	}

	(*new_ep_ops) = (*ep->ops);
	new_ep_ops->queue = dwc3_msm_ep_queue;
	new_ep_ops->gsi_ep_op = dwc3_msm_gsi_ep_op;
	ep->ops = new_ep_ops;

	if (!mdwc->dbm || !request || (dep->endpoint.ep_type == EP_TYPE_GSI)) {
		spin_unlock_irqrestore(&dwc->lock, flags);
		return 0;
	}

	/*
	 * Do HERE more usb endpoint configurations
	 * which are specific to MSM.
	 * Configure the DBM endpoint if required.
	 */
	bam_pipe = request->udc_priv & MSM_PIPE_ID_MASK;
	producer = ((request->udc_priv & MSM_PRODUCER) ? true : false);
	disable_wb = ((request->udc_priv & MSM_DISABLE_WB) ? true : false);
	internal_mem = ((request->udc_priv & MSM_INTERNAL_MEM) ? true : false);
	ioc = ((request->udc_priv & MSM_ETD_IOC) ? true : false);

	ret = dbm_ep_config(mdwc->dbm, dep->number, bam_pipe, producer,
					disable_wb, internal_mem, ioc);
	if (ret < 0) {
		dev_err(mdwc->dev,
			"error %d after calling dbm_ep_config\n", ret);
		spin_unlock_irqrestore(&dwc->lock, flags);
		return ret;
	}

	spin_unlock_irqrestore(&dwc->lock, flags);

	return 0;
}
@@ -1522,12 +1556,15 @@ int msm_ep_unconfig(struct usb_ep *ep)
	struct dwc3 *dwc = dep->dwc;
	struct dwc3_msm *mdwc = dev_get_drvdata(dwc->dev->parent);
	struct usb_ep_ops *old_ep_ops;
	unsigned long flags;

	spin_lock_irqsave(&dwc->lock, flags);
	/* Restore original ep ops */
	if (!mdwc->original_ep_ops[dep->number]) {
		dev_err(mdwc->dev,
			"ep [%s,%d] was not configured as msm endpoint\n",
			ep->name, dep->number);
		spin_unlock_irqrestore(&dwc->lock, flags);
		return -EINVAL;
	}
	old_ep_ops = (struct usb_ep_ops	*)ep->ops;
@@ -1539,6 +1576,32 @@ int msm_ep_unconfig(struct usb_ep *ep)
	 * Do HERE more usb endpoint un-configurations
	 * which are specific to MSM.
	 */
	if (!mdwc->dbm || (dep->endpoint.ep_type == EP_TYPE_GSI)) {
		spin_unlock_irqrestore(&dwc->lock, flags);
		return 0;
	}

	if (dep->trb_dequeue == dep->trb_enqueue
					&& list_empty(&dep->pending_list)
					&& list_empty(&dep->started_list)) {
		dev_dbg(mdwc->dev,
			"%s: request is not queued, disable DBM ep for ep %s\n",
			__func__, ep->name);
		/* Unconfigure dbm ep */
		dbm_ep_unconfig(mdwc->dbm, dep->number);

		/*
		 * If this is the last endpoint we unconfigured, than reset also
		 * the event buffers; unless unconfiguring the ep due to lpm,
		 * in which case the event buffer only gets reset during the
		 * block reset.
		 */
		if (dbm_get_num_of_eps_configured(mdwc->dbm) == 0 &&
				!dbm_reset_ep_after_lpm(mdwc->dbm))
			dbm_event_buffer_config(mdwc->dbm, 0, 0, 0);
	}

	spin_unlock_irqrestore(&dwc->lock, flags);

	return 0;
}
@@ -1722,7 +1785,8 @@ static void dwc3_msm_vbus_draw_work(struct work_struct *w)
	dwc3_msm_gadget_vbus_draw(mdwc, dwc->vbus_draw);
}

static void dwc3_msm_notify_event(struct dwc3 *dwc, unsigned int event)
static void dwc3_msm_notify_event(struct dwc3 *dwc, unsigned int event,
							unsigned int value)
{
	struct dwc3_msm *mdwc = dev_get_drvdata(dwc->dev->parent);
	struct dwc3_event_buffer *evt;
@@ -1908,6 +1972,9 @@ static void dwc3_msm_notify_event(struct dwc3 *dwc, unsigned int event)
							evt->buf, evt->dma);
		}
		break;
	case DWC3_CONTROLLER_NOTIFY_DISABLE_UPDXFER:
		dwc3_msm_dbm_disable_updxfer(dwc, value);
		break;
	default:
		dev_dbg(mdwc->dev, "unknown dwc3 event\n");
		break;
Loading