aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/dwc3
diff options
context:
space:
mode:
authorFelipe Balbi <balbi@ti.com>2012-01-02 11:55:57 -0500
committerFelipe Balbi <balbi@ti.com>2012-02-06 04:48:24 -0500
commit8598bde7fa125e85bc97decd6513d37dcf1e7bd9 (patch)
treef33eab7bb8bc5e0197165215703dd0308c862d69 /drivers/usb/dwc3
parent080d921fe7a8d27c07eba7723fe53a3bea100327 (diff)
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>
Diffstat (limited to 'drivers/usb/dwc3')
-rw-r--r--drivers/usb/dwc3/gadget.c52
-rw-r--r--drivers/usb/dwc3/gadget.h1
2 files changed, 42 insertions, 11 deletions
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 1dee17e7b778..80003952547e 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -89,6 +89,42 @@ int dwc3_gadget_set_test_mode(struct dwc3 *dwc, int mode)
89 return 0; 89 return 0;
90} 90}
91 91
92/**
93 * dwc3_gadget_set_link_state - Sets USB Link to a particular State
94 * @dwc: pointer to our context structure
95 * @state: the state to put link into
96 *
97 * Caller should take care of locking. This function will
98 * return 0 on success or -EINVAL.
99 */
100int dwc3_gadget_set_link_state(struct dwc3 *dwc, enum dwc3_link_state state)
101{
102 int retries = 100;
103 u32 reg;
104
105 reg = dwc3_readl(dwc->regs, DWC3_DCTL);
106 reg &= ~DWC3_DCTL_ULSTCHNGREQ_MASK;
107
108 /* set requested state */
109 reg |= DWC3_DCTL_ULSTCHNGREQ(state);
110 dwc3_writel(dwc->regs, DWC3_DCTL, reg);
111
112 /* wait for a change in DSTS */
113 while (--retries) {
114 reg = dwc3_readl(dwc->regs, DWC3_DSTS);
115
116 /* in HS, means ON */
117 if (DWC3_DSTS_USBLNKST(reg) == state)
118 return 0;
119
120 usleep_range(500, 1500);
121 }
122
123 dev_vdbg(dwc->dev, "link state change request timed out\n");
124
125 return -ETIMEDOUT;
126}
127
92void dwc3_map_buffer_to_dma(struct dwc3_request *req) 128void dwc3_map_buffer_to_dma(struct dwc3_request *req)
93{ 129{
94 struct dwc3 *dwc = req->dep->dwc; 130 struct dwc3 *dwc = req->dep->dwc;
@@ -1155,17 +1191,11 @@ static int dwc3_gadget_wakeup(struct usb_gadget *g)
1155 goto out; 1191 goto out;
1156 } 1192 }
1157 1193
1158 reg = dwc3_readl(dwc->regs, DWC3_DCTL); 1194 ret = dwc3_gadget_set_link_state(dwc, DWC3_LINK_STATE_RECOV);
1159 1195 if (ret < 0) {
1160 /* 1196 dev_err(dwc->dev, "failed to put link in Recovery\n");
1161 * Switch link state to Recovery. In HS/FS/LS this means 1197 goto out;
1162 * RemoteWakeup Request 1198 }
1163 */
1164 reg |= DWC3_DCTL_ULSTCHNG_RECOVERY;
1165 dwc3_writel(dwc->regs, DWC3_DCTL, reg);
1166
1167 /* wait for at least 2000us */
1168 usleep_range(2000, 2500);
1169 1199
1170 /* write zeroes to Link Change Request */ 1200 /* write zeroes to Link Change Request */
1171 reg &= ~DWC3_DCTL_ULSTCHNGREQ_MASK; 1201 reg &= ~DWC3_DCTL_ULSTCHNGREQ_MASK;
diff --git a/drivers/usb/dwc3/gadget.h b/drivers/usb/dwc3/gadget.h
index 2cf6f2989f73..152b6de0649d 100644
--- a/drivers/usb/dwc3/gadget.h
+++ b/drivers/usb/dwc3/gadget.h
@@ -101,6 +101,7 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
101 int status); 101 int status);
102 102
103int dwc3_gadget_set_test_mode(struct dwc3 *dwc, int mode); 103int dwc3_gadget_set_test_mode(struct dwc3 *dwc, int mode);
104int dwc3_gadget_set_link_state(struct dwc3 *dwc, enum dwc3_link_state state);
104 105
105void dwc3_ep0_interrupt(struct dwc3 *dwc, 106void dwc3_ep0_interrupt(struct dwc3 *dwc,
106 const struct dwc3_event_depevt *event); 107 const struct dwc3_event_depevt *event);