aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/whci/pzl.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2009-01-06 03:53:05 -0500
committerIngo Molnar <mingo@elte.hu>2009-01-06 03:53:05 -0500
commit3d7a96f5a485b7d06c2379f343d7312af89ec9e2 (patch)
tree5f097f68eb0f9fd3fa4a10f38672e300e9127b10 /drivers/usb/host/whci/pzl.c
parent723cbe0775514853c22dc45005af59c360916af1 (diff)
parent238c6d54830c624f34ac9cf123ac04aebfca5013 (diff)
Merge branch 'linus' into tracing/kmemtrace2
Diffstat (limited to 'drivers/usb/host/whci/pzl.c')
-rw-r--r--drivers/usb/host/whci/pzl.c49
1 files changed, 18 insertions, 31 deletions
diff --git a/drivers/usb/host/whci/pzl.c b/drivers/usb/host/whci/pzl.c
index 8d62df0c330b..2ae5abf69a6a 100644
--- a/drivers/usb/host/whci/pzl.c
+++ b/drivers/usb/host/whci/pzl.c
@@ -19,35 +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_pzl(struct whc *whc, const char *tag)
31{
32 struct device *dev = &whc->umc->dev;
33 struct whc_qset *qset;
34 int period = 0;
35
36 d_printf(4, dev, "PZL %s\n", tag);
37
38 for (period = 0; period < 5; period++) {
39 d_printf(4, dev, "Period %d\n", period);
40 list_for_each_entry(qset, &whc->periodic_list[period], list_node) {
41 dump_qset(qset, dev);
42 }
43 }
44}
45#else
46static inline void dump_pzl(struct whc *whc, const char *tag)
47{
48}
49#endif
50
51static void update_pzl_pointers(struct whc *whc, int period, u64 addr) 27static void update_pzl_pointers(struct whc *whc, int period, u64 addr)
52{ 28{
53 switch (period) { 29 switch (period) {
@@ -195,11 +171,26 @@ void pzl_stop(struct whc *whc)
195 1000, "stop PZL"); 171 1000, "stop PZL");
196} 172}
197 173
174/**
175 * pzl_update - request a PZL update and wait for the hardware to be synced
176 * @whc: the WHCI HC
177 * @wusbcmd: WUSBCMD value to start the update.
178 *
179 * If the WUSB HC is inactive (i.e., the PZL is stopped) then the
180 * update must be skipped as the hardware may not respond to update
181 * requests.
182 */
198void pzl_update(struct whc *whc, uint32_t wusbcmd) 183void pzl_update(struct whc *whc, uint32_t wusbcmd)
199{ 184{
200 whc_write_wusbcmd(whc, wusbcmd, wusbcmd); 185 struct wusbhc *wusbhc = &whc->wusbhc;
201 wait_event(whc->periodic_list_wq, 186
202 (le_readl(whc->base + WUSBCMD) & WUSBCMD_PERIODIC_UPDATED) == 0); 187 mutex_lock(&wusbhc->mutex);
188 if (wusbhc->active) {
189 whc_write_wusbcmd(whc, wusbcmd, wusbcmd);
190 wait_event(whc->periodic_list_wq,
191 (le_readl(whc->base + WUSBCMD) & WUSBCMD_PERIODIC_UPDATED) == 0);
192 }
193 mutex_unlock(&wusbhc->mutex);
203} 194}
204 195
205static void update_pzl_hw_view(struct whc *whc) 196static void update_pzl_hw_view(struct whc *whc)
@@ -235,8 +226,6 @@ void scan_periodic_work(struct work_struct *work)
235 226
236 spin_lock_irq(&whc->lock); 227 spin_lock_irq(&whc->lock);
237 228
238 dump_pzl(whc, "before processing");
239
240 for (period = 4; period >= 0; period--) { 229 for (period = 4; period >= 0; period--) {
241 list_for_each_entry_safe(qset, t, &whc->periodic_list[period], list_node) { 230 list_for_each_entry_safe(qset, t, &whc->periodic_list[period], list_node) {
242 if (!qset->in_hw_list) 231 if (!qset->in_hw_list)
@@ -248,8 +237,6 @@ void scan_periodic_work(struct work_struct *work)
248 if (update & (WHC_UPDATE_ADDED | WHC_UPDATE_REMOVED)) 237 if (update & (WHC_UPDATE_ADDED | WHC_UPDATE_REMOVED))
249 update_pzl_hw_view(whc); 238 update_pzl_hw_view(whc);
250 239
251 dump_pzl(whc, "after processing");
252
253 spin_unlock_irq(&whc->lock); 240 spin_unlock_irq(&whc->lock);
254 241
255 if (update) { 242 if (update) {