mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-13 00:00:00 -04:00
usb: dwc3: gadget: Ensure minimum delay between run/stop
Some controller hardware, such as DWC3, need a minimum delay between removing and re-applying the pullups in order for the host to properly detect a soft disconnect and for subsequent re-enumeration to succeed. Keep track of the last time run_stop was updated and delay if necessary so that enough time will have elapsed before calling run_stop clear/set again. Change-Id: I8ca13304edf4c9fcc3093a063a6004bd8b76ed44 Signed-off-by: Ajay Agarwal <ajaya@codeaurora.org> Signed-off-by: Sriharsha Allenki <sallenki@codeaurora.org>
This commit is contained in:
parent
0e13e74f0c
commit
2e6a2a5f93
2 changed files with 14 additions and 0 deletions
|
|
@ -1149,6 +1149,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;
|
||||
|
|
@ -1393,6 +1394,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
|
||||
|
|
|
|||
|
|
@ -2047,6 +2047,8 @@ done:
|
|||
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;
|
||||
|
|
@ -2156,6 +2158,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;
|
||||
|
|
@ -2174,6 +2177,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…
Reference in a new issue