diff options
author | Felipe Balbi <balbi@ti.com> | 2012-01-02 11:55:57 -0500 |
---|---|---|
committer | Felipe Balbi <balbi@ti.com> | 2012-02-06 04:48:24 -0500 |
commit | 8598bde7fa125e85bc97decd6513d37dcf1e7bd9 (patch) | |
tree | f33eab7bb8bc5e0197165215703dd0308c862d69 /drivers/usb/dwc3 | |
parent | 080d921fe7a8d27c07eba7723fe53a3bea100327 (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.c | 52 | ||||
-rw-r--r-- | drivers/usb/dwc3/gadget.h | 1 |
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 | */ | ||
100 | int 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 | |||
92 | void dwc3_map_buffer_to_dma(struct dwc3_request *req) | 128 | void 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 | ||
103 | int dwc3_gadget_set_test_mode(struct dwc3 *dwc, int mode); | 103 | int dwc3_gadget_set_test_mode(struct dwc3 *dwc, int mode); |
104 | int dwc3_gadget_set_link_state(struct dwc3 *dwc, enum dwc3_link_state state); | ||
104 | 105 | ||
105 | void dwc3_ep0_interrupt(struct dwc3 *dwc, | 106 | void dwc3_ep0_interrupt(struct dwc3 *dwc, |
106 | const struct dwc3_event_depevt *event); | 107 | const struct dwc3_event_depevt *event); |