aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/host/whci/asl.c21
-rw-r--r--drivers/usb/host/whci/pzl.c21
-rw-r--r--drivers/usb/wusbcore/devconnect.c24
-rw-r--r--drivers/usb/wusbcore/mmc.c37
4 files changed, 72 insertions, 31 deletions
diff --git a/drivers/usb/host/whci/asl.c b/drivers/usb/host/whci/asl.c
index 4d7078e5057..ba99a7a3f81 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 */
182void asl_update(struct whc *whc, uint32_t wusbcmd) 191void 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 8d62df0c330..34d3a0aeab2 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 */
198void pzl_update(struct whc *whc, uint32_t wusbcmd) 207void 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
205static void update_pzl_hw_view(struct whc *whc) 220static void update_pzl_hw_view(struct whc *whc)
diff --git a/drivers/usb/wusbcore/devconnect.c b/drivers/usb/wusbcore/devconnect.c
index 08a1ec90386..26cbc89ea28 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 */
485static void wusbhc_keep_alive_run(struct work_struct *ws) 485static 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 5463ecebafd..3b52161e6e9 100644
--- a/drivers/usb/wusbcore/mmc.c
+++ b/drivers/usb/wusbcore/mmc.c
@@ -159,6 +159,27 @@ found:
159} 159}
160EXPORT_SYMBOL_GPL(wusbhc_mmcie_rm); 160EXPORT_SYMBOL_GPL(wusbhc_mmcie_rm);
161 161
162static 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
175static 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
209error_wusbhc_start: 230error_wusbhc_start:
@@ -225,15 +246,11 @@ error_rsv_establish:
225 */ 246 */
226void wusbhc_stop(struct wusbhc *wusbhc) 247void 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}
236EXPORT_SYMBOL_GPL(wusbhc_stop);
237 254
238/* 255/*
239 * Set/reset/update a new CHID 256 * Set/reset/update a new CHID