Skip to content

Commit

Permalink
usb: dwc2: Disable all EP's on disconnect
Browse files Browse the repository at this point in the history
Disabling all EP's allow to reset EP's to initial state.
On disconnect disable all EP's instead of just killing
all requests. Because of some platform didn't catch
disconnect event, same stuff added to
dwc2_hsotg_core_init_disconnected() function when USB
reset detected on the bus.

Changed from version 1:
Changed lock acquire flow in dwc2_hsotg_ep_disable()
function.

Signed-off-by: Minas Harutyunyan <hminas@synopsys.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
  • Loading branch information
Minas Harutyunyan authored and Felipe Balbi committed Oct 2, 2018
1 parent 4c19cc1 commit dccf1ba
Showing 1 changed file with 23 additions and 7 deletions.
30 changes: 23 additions & 7 deletions drivers/usb/dwc2/gadget.c
Original file line number Diff line number Diff line change
Expand Up @@ -3109,6 +3109,8 @@ static void kill_all_requests(struct dwc2_hsotg *hsotg,
dwc2_hsotg_txfifo_flush(hsotg, ep->fifo_index);
}

static int dwc2_hsotg_ep_disable(struct usb_ep *ep);

/**
* dwc2_hsotg_disconnect - disconnect service
* @hsotg: The device state.
Expand All @@ -3127,13 +3129,12 @@ void dwc2_hsotg_disconnect(struct dwc2_hsotg *hsotg)
hsotg->connected = 0;
hsotg->test_mode = 0;

/* all endpoints should be shutdown */
for (ep = 0; ep < hsotg->num_of_eps; ep++) {
if (hsotg->eps_in[ep])
kill_all_requests(hsotg, hsotg->eps_in[ep],
-ESHUTDOWN);
dwc2_hsotg_ep_disable(&hsotg->eps_in[ep]->ep);
if (hsotg->eps_out[ep])
kill_all_requests(hsotg, hsotg->eps_out[ep],
-ESHUTDOWN);
dwc2_hsotg_ep_disable(&hsotg->eps_out[ep]->ep);
}

call_gadget(hsotg, disconnect);
Expand Down Expand Up @@ -3191,13 +3192,23 @@ void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg,
u32 val;
u32 usbcfg;
u32 dcfg = 0;
int ep;

/* Kill any ep0 requests as controller will be reinitialized */
kill_all_requests(hsotg, hsotg->eps_out[0], -ECONNRESET);

if (!is_usb_reset)
if (!is_usb_reset) {
if (dwc2_core_reset(hsotg, true))
return;
} else {
/* all endpoints should be shutdown */
for (ep = 1; ep < hsotg->num_of_eps; ep++) {
if (hsotg->eps_in[ep])
dwc2_hsotg_ep_disable(&hsotg->eps_in[ep]->ep);
if (hsotg->eps_out[ep])
dwc2_hsotg_ep_disable(&hsotg->eps_out[ep]->ep);
}
}

/*
* we must now enable ep0 ready for host detection and then
Expand Down Expand Up @@ -3993,6 +4004,7 @@ static int dwc2_hsotg_ep_disable(struct usb_ep *ep)
unsigned long flags;
u32 epctrl_reg;
u32 ctrl;
int locked;

dev_dbg(hsotg->dev, "%s(ep %p)\n", __func__, ep);

Expand All @@ -4008,7 +4020,9 @@ static int dwc2_hsotg_ep_disable(struct usb_ep *ep)

epctrl_reg = dir_in ? DIEPCTL(index) : DOEPCTL(index);

spin_lock_irqsave(&hsotg->lock, flags);
locked = spin_is_locked(&hsotg->lock);
if (!locked)
spin_lock_irqsave(&hsotg->lock, flags);

ctrl = dwc2_readl(hsotg, epctrl_reg);

Expand All @@ -4032,7 +4046,9 @@ static int dwc2_hsotg_ep_disable(struct usb_ep *ep)
hs_ep->fifo_index = 0;
hs_ep->fifo_size = 0;

spin_unlock_irqrestore(&hsotg->lock, flags);
if (!locked)
spin_unlock_irqrestore(&hsotg->lock, flags);

return 0;
}

Expand Down

0 comments on commit dccf1ba

Please sign in to comment.