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 |
