Loading drivers/usb/dwc3/core.h +2 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading drivers/usb/dwc3/gadget.c +21 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading @@ -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. Loading @@ -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); Loading Loading
drivers/usb/dwc3/core.h +2 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading
drivers/usb/dwc3/gadget.c +21 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading @@ -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. Loading @@ -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); Loading