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

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

Merge "usb: dwc3: gadget: Issue soft reset as part of composition switch"

parents 0f59dfeb e7898836
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -1125,6 +1125,7 @@ struct dwc3_scratchpad_array {
 * @bh_completion_time: time taken for taklet completion
 * @bh_handled_evt_cnt: no. of events handled by tasklet per interrupt
 * @bh_dbg_index: index for capturing bh_completion_time and bh_handled_evt_cnt
 * @last_run_stop: timestamp denoting the last run_stop update
 */
struct dwc3 {
	struct work_struct	drd_work;
@@ -1359,6 +1360,7 @@ struct dwc3 {
	u32			gen2_tx_de_emph1;
	u32			gen2_tx_de_emph2;
	u32			gen2_tx_de_emph3;
	ktime_t			last_run_stop;
};

#define INCRX_BURST_MODE 0
+21 −0
Original line number Diff line number Diff line
@@ -2102,9 +2102,17 @@ static int dwc3_device_core_soft_reset(struct dwc3 *dwc)
	/* phy sync delay as per data book */
	msleep(50);

	/*
	 * Soft reset clears the block on the doorbell,
	 * set it back to prevent unwanted writes to the doorbell.
	 */
	dwc3_notify_event(dwc, DWC3_CONTROLLER_NOTIFY_CLEAR_DB, 0);

	return 0;
}

#define MIN_RUN_STOP_DELAY_MS 50

static int dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on, int suspend)
{
	u32			reg, reg1;
@@ -2213,6 +2221,7 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on)
	struct dwc3		*dwc = gadget_to_dwc(g);
	unsigned long		flags;
	int			ret;
	ktime_t			diff;

	is_on = !!is_on;
	dwc->softconnect = is_on;
@@ -2231,6 +2240,15 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on)
	dbg_event(0xFF, "Pullup gsync",
		atomic_read(&dwc->dev->power.usage_count));

	diff = ktime_sub(ktime_get(), dwc->last_run_stop);
	if (ktime_to_ms(diff) < MIN_RUN_STOP_DELAY_MS) {
		dbg_event(0xFF, "waitBefRun_Stop",
			  MIN_RUN_STOP_DELAY_MS - ktime_to_ms(diff));
		msleep(MIN_RUN_STOP_DELAY_MS - ktime_to_ms(diff));
	}

	dwc->last_run_stop = ktime_get();

	/*
	 * Per databook, when we want to stop the gadget, if a control transfer
	 * is still in process, complete it and get the core into setup phase.
@@ -2253,6 +2271,9 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on)
	/* prevent pending bh to run later */
	flush_work(&dwc->bh_work);

	if (is_on)
		dwc3_device_core_soft_reset(dwc);

	spin_lock_irqsave(&dwc->lock, flags);
	if (dwc->ep0state != EP0_SETUP_PHASE)
		dbg_event(0xFF, "EP0 is not in SETUP phase\n", 0);