aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/whci/asl.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/whci/asl.c')
-rw-r--r--drivers/usb/host/whci/asl.c46
1 files changed, 18 insertions, 28 deletions
diff --git a/drivers/usb/host/whci/asl.c b/drivers/usb/host/whci/asl.c
index 4d7078e50572..577c0d29849d 100644
--- a/drivers/usb/host/whci/asl.c
+++ b/drivers/usb/host/whci/asl.c
@@ -19,32 +19,11 @@
19#include <linux/dma-mapping.h> 19#include <linux/dma-mapping.h>
20#include <linux/uwb/umc.h> 20#include <linux/uwb/umc.h>
21#include <linux/usb.h> 21#include <linux/usb.h>
22#define D_LOCAL 0
23#include <linux/uwb/debug.h>
24 22
25#include "../../wusbcore/wusbhc.h" 23#include "../../wusbcore/wusbhc.h"
26 24
27#include "whcd.h" 25#include "whcd.h"
28 26
29#if D_LOCAL >= 4
30static void dump_asl(struct whc *whc, const char *tag)
31{
32 struct device *dev = &whc->umc->dev;
33 struct whc_qset *qset;
34
35 d_printf(4, dev, "ASL %s\n", tag);
36
37 list_for_each_entry(qset, &whc->async_list, list_node) {
38 dump_qset(qset, dev);
39 }
40}
41#else
42static inline void dump_asl(struct whc *whc, const char *tag)
43{
44}
45#endif
46
47
48static void qset_get_next_prev(struct whc *whc, struct whc_qset *qset, 27static void qset_get_next_prev(struct whc *whc, struct whc_qset *qset,
49 struct whc_qset **next, struct whc_qset **prev) 28 struct whc_qset **next, struct whc_qset **prev)
50{ 29{
@@ -179,11 +158,26 @@ void asl_stop(struct whc *whc)
179 1000, "stop ASL"); 158 1000, "stop ASL");
180} 159}
181 160
161/**
162 * asl_update - request an ASL update and wait for the hardware to be synced
163 * @whc: the WHCI HC
164 * @wusbcmd: WUSBCMD value to start the update.
165 *
166 * If the WUSB HC is inactive (i.e., the ASL is stopped) then the
167 * update must be skipped as the hardware may not respond to update
168 * requests.
169 */
182void asl_update(struct whc *whc, uint32_t wusbcmd) 170void asl_update(struct whc *whc, uint32_t wusbcmd)
183{ 171{
184 whc_write_wusbcmd(whc, wusbcmd, wusbcmd); 172 struct wusbhc *wusbhc = &whc->wusbhc;
185 wait_event(whc->async_list_wq, 173
186 (le_readl(whc->base + WUSBCMD) & WUSBCMD_ASYNC_UPDATED) == 0); 174 mutex_lock(&wusbhc->mutex);
175 if (wusbhc->active) {
176 whc_write_wusbcmd(whc, wusbcmd, wusbcmd);
177 wait_event(whc->async_list_wq,
178 (le_readl(whc->base + WUSBCMD) & WUSBCMD_ASYNC_UPDATED) == 0);
179 }
180 mutex_unlock(&wusbhc->mutex);
187} 181}
188 182
189/** 183/**
@@ -202,8 +196,6 @@ void scan_async_work(struct work_struct *work)
202 196
203 spin_lock_irq(&whc->lock); 197 spin_lock_irq(&whc->lock);
204 198
205 dump_asl(whc, "before processing");
206
207 /* 199 /*
208 * Transerve the software list backwards so new qsets can be 200 * Transerve the software list backwards so new qsets can be
209 * safely inserted into the ASL without making it non-circular. 201 * safely inserted into the ASL without making it non-circular.
@@ -217,8 +209,6 @@ void scan_async_work(struct work_struct *work)
217 update |= process_qset(whc, qset); 209 update |= process_qset(whc, qset);
218 } 210 }
219 211
220 dump_asl(whc, "after processing");
221
222 spin_unlock_irq(&whc->lock); 212 spin_unlock_irq(&whc->lock);
223 213
224 if (update) { 214 if (update) {