mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-07 12:25:00 -04:00
Merge "usb: dwc3: Issue core soft reset upon controller halt failure"
This commit is contained in:
commit
e64d784137
1 changed files with 70 additions and 21 deletions
|
|
@ -811,25 +811,6 @@ static void dwc3_remove_requests(struct dwc3 *dwc, struct dwc3_ep *dep)
|
|||
|
||||
dwc3_stop_active_transfer(dep, true, false);
|
||||
|
||||
/* - giveback all requests to gadget driver */
|
||||
while (!list_empty(&dep->started_list)) {
|
||||
req = next_request(&dep->started_list);
|
||||
|
||||
dwc3_gadget_giveback(dep, req, -ESHUTDOWN);
|
||||
}
|
||||
|
||||
while (!list_empty(&dep->pending_list)) {
|
||||
req = next_request(&dep->pending_list);
|
||||
|
||||
dwc3_gadget_giveback(dep, req, -ESHUTDOWN);
|
||||
}
|
||||
|
||||
while (!list_empty(&dep->cancelled_list)) {
|
||||
req = next_request(&dep->cancelled_list);
|
||||
|
||||
dwc3_gadget_giveback(dep, req, -ESHUTDOWN);
|
||||
}
|
||||
|
||||
if (dep->number == 1 && dwc->ep0state != EP0_SETUP_PHASE) {
|
||||
unsigned int dir;
|
||||
|
||||
|
|
@ -844,6 +825,25 @@ static void dwc3_remove_requests(struct dwc3 *dwc, struct dwc3_ep *dep)
|
|||
dwc->eps[1]->trb_enqueue = 0;
|
||||
}
|
||||
|
||||
/* - giveback all requests to gadget driver */
|
||||
while (!list_empty(&dep->started_list)) {
|
||||
req = next_request(&dep->started_list);
|
||||
if (req)
|
||||
dwc3_gadget_giveback(dep, req, -ESHUTDOWN);
|
||||
}
|
||||
|
||||
while (!list_empty(&dep->pending_list)) {
|
||||
req = next_request(&dep->pending_list);
|
||||
if (req)
|
||||
dwc3_gadget_giveback(dep, req, -ESHUTDOWN);
|
||||
}
|
||||
|
||||
while (!list_empty(&dep->cancelled_list)) {
|
||||
req = next_request(&dep->cancelled_list);
|
||||
if (req)
|
||||
dwc3_gadget_giveback(dep, req, -ESHUTDOWN);
|
||||
}
|
||||
|
||||
dbg_log_string("DONE for %s(%d)", dep->name, dep->number);
|
||||
}
|
||||
|
||||
|
|
@ -1980,6 +1980,38 @@ static void dwc3_stop_active_transfers(struct dwc3 *dwc)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* dwc3_device_core_soft_reset - Issues device core soft reset
|
||||
* @dwc: pointer to our context structure
|
||||
*/
|
||||
static int dwc3_device_core_soft_reset(struct dwc3 *dwc)
|
||||
{
|
||||
u32 reg;
|
||||
int retries = 10;
|
||||
|
||||
reg = dwc3_readl(dwc->regs, DWC3_DCTL);
|
||||
reg |= DWC3_DCTL_CSFTRST;
|
||||
dwc3_writel(dwc->regs, DWC3_DCTL, reg);
|
||||
|
||||
do {
|
||||
reg = dwc3_readl(dwc->regs, DWC3_DCTL);
|
||||
if (!(reg & DWC3_DCTL_CSFTRST))
|
||||
goto done;
|
||||
|
||||
usleep_range(1000, 1100);
|
||||
} while (--retries);
|
||||
|
||||
dev_err(dwc->dev, "%s timedout\n", __func__);
|
||||
|
||||
return -ETIMEDOUT;
|
||||
|
||||
done:
|
||||
/* phy sync delay as per data book */
|
||||
msleep(50);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on, int suspend)
|
||||
{
|
||||
u32 reg, reg1;
|
||||
|
|
@ -2142,6 +2174,10 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on)
|
|||
|
||||
ret = dwc3_gadget_run_stop(dwc, is_on, false);
|
||||
spin_unlock_irqrestore(&dwc->lock, flags);
|
||||
if (!is_on && ret == -ETIMEDOUT) {
|
||||
dev_err(dwc->dev, "%s: Core soft reset...\n", __func__);
|
||||
dwc3_device_core_soft_reset(dwc);
|
||||
}
|
||||
enable_irq(dwc->irq);
|
||||
|
||||
pm_runtime_mark_last_busy(dwc->dev);
|
||||
|
|
@ -2226,6 +2262,7 @@ static int dwc3_gadget_vbus_session(struct usb_gadget *_gadget, int is_active)
|
|||
{
|
||||
struct dwc3 *dwc = gadget_to_dwc(_gadget);
|
||||
unsigned long flags;
|
||||
int ret = 0;
|
||||
|
||||
if (dwc->dr_mode != USB_DR_MODE_OTG)
|
||||
return -EPERM;
|
||||
|
|
@ -2233,6 +2270,11 @@ static int dwc3_gadget_vbus_session(struct usb_gadget *_gadget, int is_active)
|
|||
is_active = !!is_active;
|
||||
|
||||
dbg_event(0xFF, "VbusSess", is_active);
|
||||
|
||||
disable_irq(dwc->irq);
|
||||
|
||||
flush_work(&dwc->bh_work);
|
||||
|
||||
spin_lock_irqsave(&dwc->lock, flags);
|
||||
|
||||
/* Mark that the vbus was powered */
|
||||
|
|
@ -2248,9 +2290,9 @@ static int dwc3_gadget_vbus_session(struct usb_gadget *_gadget, int is_active)
|
|||
* Both vbus was activated by otg and pullup was
|
||||
* signaled by the gadget driver.
|
||||
*/
|
||||
dwc3_gadget_run_stop(dwc, 1, false);
|
||||
ret = dwc3_gadget_run_stop(dwc, 1, false);
|
||||
} else {
|
||||
dwc3_gadget_run_stop(dwc, 0, false);
|
||||
ret = dwc3_gadget_run_stop(dwc, 0, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2264,6 +2306,13 @@ static int dwc3_gadget_vbus_session(struct usb_gadget *_gadget, int is_active)
|
|||
}
|
||||
|
||||
spin_unlock_irqrestore(&dwc->lock, flags);
|
||||
if (!is_active && ret == -ETIMEDOUT) {
|
||||
dev_err(dwc->dev, "%s: Core soft reset...\n", __func__);
|
||||
dwc3_device_core_soft_reset(dwc);
|
||||
}
|
||||
|
||||
enable_irq(dwc->irq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue