diff options
-rw-r--r-- | drivers/usb/host/whci/asl.c | 21 | ||||
-rw-r--r-- | drivers/usb/host/whci/pzl.c | 21 | ||||
-rw-r--r-- | drivers/usb/wusbcore/devconnect.c | 24 | ||||
-rw-r--r-- | drivers/usb/wusbcore/mmc.c | 37 |
4 files changed, 72 insertions, 31 deletions
diff --git a/drivers/usb/host/whci/asl.c b/drivers/usb/host/whci/asl.c index 4d7078e50572..ba99a7a3f81a 100644 --- a/drivers/usb/host/whci/asl.c +++ b/drivers/usb/host/whci/asl.c | |||
@@ -179,11 +179,26 @@ void asl_stop(struct whc *whc) | |||
179 | 1000, "stop ASL"); | 179 | 1000, "stop ASL"); |
180 | } | 180 | } |
181 | 181 | ||
182 | /** | ||
183 | * asl_update - request an ASL update and wait for the hardware to be synced | ||
184 | * @whc: the WHCI HC | ||
185 | * @wusbcmd: WUSBCMD value to start the update. | ||
186 | * | ||
187 | * If the WUSB HC is inactive (i.e., the ASL is stopped) then the | ||
188 | * update must be skipped as the hardware may not respond to update | ||
189 | * requests. | ||
190 | */ | ||
182 | void asl_update(struct whc *whc, uint32_t wusbcmd) | 191 | void asl_update(struct whc *whc, uint32_t wusbcmd) |
183 | { | 192 | { |
184 | whc_write_wusbcmd(whc, wusbcmd, wusbcmd); | 193 | struct wusbhc *wusbhc = &whc->wusbhc; |
185 | wait_event(whc->async_list_wq, | 194 | |
186 | (le_readl(whc->base + WUSBCMD) & WUSBCMD_ASYNC_UPDATED) == 0); | 195 | mutex_lock(&wusbhc->mutex); |
196 | if (wusbhc->active) { | ||
197 | whc_write_wusbcmd(whc, wusbcmd, wusbcmd); | ||
198 | wait_event(whc->async_list_wq, | ||
199 | (le_readl(whc->base + WUSBCMD) & WUSBCMD_ASYNC_UPDATED) == 0); | ||
200 | } | ||
201 | mutex_unlock(&wusbhc->mutex); | ||
187 | } | 202 | } |
188 | 203 | ||
189 | /** | 204 | /** |
diff --git a/drivers/usb/host/whci/pzl.c b/drivers/usb/host/whci/pzl.c index 8d62df0c330b..34d3a0aeab2b 100644 --- a/drivers/usb/host/whci/pzl.c +++ b/drivers/usb/host/whci/pzl.c | |||
@@ -195,11 +195,26 @@ void pzl_stop(struct whc *whc) | |||
195 | 1000, "stop PZL"); | 195 | 1000, "stop PZL"); |
196 | } | 196 | } |
197 | 197 | ||
198 | /** | ||
199 | * pzl_update - request a PZL update and wait for the hardware to be synced | ||
200 | * @whc: the WHCI HC | ||
201 | * @wusbcmd: WUSBCMD value to start the update. | ||
202 | * | ||
203 | * If the WUSB HC is inactive (i.e., the PZL is stopped) then the | ||
204 | * update must be skipped as the hardware may not respond to update | ||
205 | * requests. | ||
206 | */ | ||
198 | void pzl_update(struct whc *whc, uint32_t wusbcmd) | 207 | void pzl_update(struct whc *whc, uint32_t wusbcmd) |
199 | { | 208 | { |
200 | whc_write_wusbcmd(whc, wusbcmd, wusbcmd); | 209 | struct wusbhc *wusbhc = &whc->wusbhc; |
201 | wait_event(whc->periodic_list_wq, | 210 | |
202 | (le_readl(whc->base + WUSBCMD) & WUSBCMD_PERIODIC_UPDATED) == 0); | 211 | mutex_lock(&wusbhc->mutex); |
212 | if (wusbhc->active) { | ||
213 | whc_write_wusbcmd(whc, wusbcmd, wusbcmd); | ||
214 | wait_event(whc->periodic_list_wq, | ||
215 | (le_readl(whc->base + WUSBCMD) & WUSBCMD_PERIODIC_UPDATED) == 0); | ||
216 | } | ||
217 | mutex_unlock(&wusbhc->mutex); | ||
203 | } | 218 | } |
204 | 219 | ||
205 | static void update_pzl_hw_view(struct whc *whc) | 220 | static void update_pzl_hw_view(struct whc *whc) |
diff --git a/drivers/usb/wusbcore/devconnect.c b/drivers/usb/wusbcore/devconnect.c index 08a1ec903867..26cbc89ea281 100644 --- a/drivers/usb/wusbcore/devconnect.c +++ b/drivers/usb/wusbcore/devconnect.c | |||
@@ -484,21 +484,15 @@ static void __wusbhc_keep_alive(struct wusbhc *wusbhc) | |||
484 | */ | 484 | */ |
485 | static void wusbhc_keep_alive_run(struct work_struct *ws) | 485 | static void wusbhc_keep_alive_run(struct work_struct *ws) |
486 | { | 486 | { |
487 | struct delayed_work *dw = | 487 | struct delayed_work *dw = container_of(ws, struct delayed_work, work); |
488 | container_of(ws, struct delayed_work, work); | 488 | struct wusbhc *wusbhc = container_of(dw, struct wusbhc, keep_alive_timer); |
489 | struct wusbhc *wusbhc = | 489 | |
490 | container_of(dw, struct wusbhc, keep_alive_timer); | 490 | mutex_lock(&wusbhc->mutex); |
491 | 491 | __wusbhc_keep_alive(wusbhc); | |
492 | d_fnstart(5, wusbhc->dev, "(wusbhc %p)\n", wusbhc); | 492 | mutex_unlock(&wusbhc->mutex); |
493 | if (wusbhc->active) { | 493 | |
494 | mutex_lock(&wusbhc->mutex); | 494 | queue_delayed_work(wusbd, &wusbhc->keep_alive_timer, |
495 | __wusbhc_keep_alive(wusbhc); | 495 | msecs_to_jiffies(wusbhc->trust_timeout / 2)); |
496 | mutex_unlock(&wusbhc->mutex); | ||
497 | queue_delayed_work(wusbd, &wusbhc->keep_alive_timer, | ||
498 | (wusbhc->trust_timeout * CONFIG_HZ)/1000/2); | ||
499 | } | ||
500 | d_fnend(5, wusbhc->dev, "(wusbhc %p) = void\n", wusbhc); | ||
501 | return; | ||
502 | } | 496 | } |
503 | 497 | ||
504 | /* | 498 | /* |
diff --git a/drivers/usb/wusbcore/mmc.c b/drivers/usb/wusbcore/mmc.c index 5463ecebafdf..3b52161e6e9c 100644 --- a/drivers/usb/wusbcore/mmc.c +++ b/drivers/usb/wusbcore/mmc.c | |||
@@ -159,6 +159,27 @@ found: | |||
159 | } | 159 | } |
160 | EXPORT_SYMBOL_GPL(wusbhc_mmcie_rm); | 160 | EXPORT_SYMBOL_GPL(wusbhc_mmcie_rm); |
161 | 161 | ||
162 | static int wusbhc_mmc_start(struct wusbhc *wusbhc) | ||
163 | { | ||
164 | int ret; | ||
165 | |||
166 | mutex_lock(&wusbhc->mutex); | ||
167 | ret = wusbhc->start(wusbhc); | ||
168 | if (ret >= 0) | ||
169 | wusbhc->active = 1; | ||
170 | mutex_unlock(&wusbhc->mutex); | ||
171 | |||
172 | return ret; | ||
173 | } | ||
174 | |||
175 | static void wusbhc_mmc_stop(struct wusbhc *wusbhc) | ||
176 | { | ||
177 | mutex_lock(&wusbhc->mutex); | ||
178 | wusbhc->active = 0; | ||
179 | wusbhc->stop(wusbhc, WUSB_CHANNEL_STOP_DELAY_MS); | ||
180 | mutex_unlock(&wusbhc->mutex); | ||
181 | } | ||
182 | |||
162 | /* | 183 | /* |
163 | * wusbhc_start - start transmitting MMCs and accepting connections | 184 | * wusbhc_start - start transmitting MMCs and accepting connections |
164 | * @wusbhc: the HC to start | 185 | * @wusbhc: the HC to start |
@@ -198,12 +219,12 @@ int wusbhc_start(struct wusbhc *wusbhc) | |||
198 | dev_err(dev, "Cannot set DNTS parameters: %d\n", result); | 219 | dev_err(dev, "Cannot set DNTS parameters: %d\n", result); |
199 | goto error_set_num_dnts; | 220 | goto error_set_num_dnts; |
200 | } | 221 | } |
201 | result = wusbhc->start(wusbhc); | 222 | result = wusbhc_mmc_start(wusbhc); |
202 | if (result < 0) { | 223 | if (result < 0) { |
203 | dev_err(dev, "error starting wusbch: %d\n", result); | 224 | dev_err(dev, "error starting wusbch: %d\n", result); |
204 | goto error_wusbhc_start; | 225 | goto error_wusbhc_start; |
205 | } | 226 | } |
206 | wusbhc->active = 1; | 227 | |
207 | return 0; | 228 | return 0; |
208 | 229 | ||
209 | error_wusbhc_start: | 230 | error_wusbhc_start: |
@@ -225,15 +246,11 @@ error_rsv_establish: | |||
225 | */ | 246 | */ |
226 | void wusbhc_stop(struct wusbhc *wusbhc) | 247 | void wusbhc_stop(struct wusbhc *wusbhc) |
227 | { | 248 | { |
228 | if (wusbhc->active) { | 249 | wusbhc_mmc_stop(wusbhc); |
229 | wusbhc->active = 0; | 250 | wusbhc_sec_stop(wusbhc); |
230 | wusbhc->stop(wusbhc, WUSB_CHANNEL_STOP_DELAY_MS); | 251 | wusbhc_devconnect_stop(wusbhc); |
231 | wusbhc_sec_stop(wusbhc); | 252 | wusbhc_rsv_terminate(wusbhc); |
232 | wusbhc_devconnect_stop(wusbhc); | ||
233 | wusbhc_rsv_terminate(wusbhc); | ||
234 | } | ||
235 | } | 253 | } |
236 | EXPORT_SYMBOL_GPL(wusbhc_stop); | ||
237 | 254 | ||
238 | /* | 255 | /* |
239 | * Set/reset/update a new CHID | 256 | * Set/reset/update a new CHID |