diff options
Diffstat (limited to 'drivers/usb/host/whci/pzl.c')
-rw-r--r-- | drivers/usb/host/whci/pzl.c | 21 |
1 files changed, 18 insertions, 3 deletions
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) |