usb: dwc3: gadget: re-factor Link state change to a function
Most link changes will, of course, happen with the help of a matching host HW, but in some cases we might want to debug very low level details about the link and exposing this to debugfs sounds like a good plan. This is a preparation for such setup. Signed-off-by: Felipe Balbi <balbi@ti.com>
This commit is contained in:
parent
080d921fe7
commit
8598bde7fa
@ -89,6 +89,42 @@ int dwc3_gadget_set_test_mode(struct dwc3 *dwc, int mode)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dwc3_gadget_set_link_state - Sets USB Link to a particular State
|
||||||
|
* @dwc: pointer to our context structure
|
||||||
|
* @state: the state to put link into
|
||||||
|
*
|
||||||
|
* Caller should take care of locking. This function will
|
||||||
|
* return 0 on success or -EINVAL.
|
||||||
|
*/
|
||||||
|
int dwc3_gadget_set_link_state(struct dwc3 *dwc, enum dwc3_link_state state)
|
||||||
|
{
|
||||||
|
int retries = 100;
|
||||||
|
u32 reg;
|
||||||
|
|
||||||
|
reg = dwc3_readl(dwc->regs, DWC3_DCTL);
|
||||||
|
reg &= ~DWC3_DCTL_ULSTCHNGREQ_MASK;
|
||||||
|
|
||||||
|
/* set requested state */
|
||||||
|
reg |= DWC3_DCTL_ULSTCHNGREQ(state);
|
||||||
|
dwc3_writel(dwc->regs, DWC3_DCTL, reg);
|
||||||
|
|
||||||
|
/* wait for a change in DSTS */
|
||||||
|
while (--retries) {
|
||||||
|
reg = dwc3_readl(dwc->regs, DWC3_DSTS);
|
||||||
|
|
||||||
|
/* in HS, means ON */
|
||||||
|
if (DWC3_DSTS_USBLNKST(reg) == state)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
usleep_range(500, 1500);
|
||||||
|
}
|
||||||
|
|
||||||
|
dev_vdbg(dwc->dev, "link state change request timed out\n");
|
||||||
|
|
||||||
|
return -ETIMEDOUT;
|
||||||
|
}
|
||||||
|
|
||||||
void dwc3_map_buffer_to_dma(struct dwc3_request *req)
|
void dwc3_map_buffer_to_dma(struct dwc3_request *req)
|
||||||
{
|
{
|
||||||
struct dwc3 *dwc = req->dep->dwc;
|
struct dwc3 *dwc = req->dep->dwc;
|
||||||
@ -1155,17 +1191,11 @@ static int dwc3_gadget_wakeup(struct usb_gadget *g)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
reg = dwc3_readl(dwc->regs, DWC3_DCTL);
|
ret = dwc3_gadget_set_link_state(dwc, DWC3_LINK_STATE_RECOV);
|
||||||
|
if (ret < 0) {
|
||||||
/*
|
dev_err(dwc->dev, "failed to put link in Recovery\n");
|
||||||
* Switch link state to Recovery. In HS/FS/LS this means
|
goto out;
|
||||||
* RemoteWakeup Request
|
}
|
||||||
*/
|
|
||||||
reg |= DWC3_DCTL_ULSTCHNG_RECOVERY;
|
|
||||||
dwc3_writel(dwc->regs, DWC3_DCTL, reg);
|
|
||||||
|
|
||||||
/* wait for at least 2000us */
|
|
||||||
usleep_range(2000, 2500);
|
|
||||||
|
|
||||||
/* write zeroes to Link Change Request */
|
/* write zeroes to Link Change Request */
|
||||||
reg &= ~DWC3_DCTL_ULSTCHNGREQ_MASK;
|
reg &= ~DWC3_DCTL_ULSTCHNGREQ_MASK;
|
||||||
|
@ -101,6 +101,7 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
|
|||||||
int status);
|
int status);
|
||||||
|
|
||||||
int dwc3_gadget_set_test_mode(struct dwc3 *dwc, int mode);
|
int dwc3_gadget_set_test_mode(struct dwc3 *dwc, int mode);
|
||||||
|
int dwc3_gadget_set_link_state(struct dwc3 *dwc, enum dwc3_link_state state);
|
||||||
|
|
||||||
void dwc3_ep0_interrupt(struct dwc3 *dwc,
|
void dwc3_ep0_interrupt(struct dwc3 *dwc,
|
||||||
const struct dwc3_event_depevt *event);
|
const struct dwc3_event_depevt *event);
|
||||||
|
Loading…
Reference in New Issue
Block a user