diff options
author | David Vrabel <david.vrabel@csr.com> | 2008-10-27 11:42:31 -0400 |
---|---|---|
committer | David Vrabel <david.vrabel@csr.com> | 2008-10-28 08:08:46 -0400 |
commit | 4d2bea4ca0adb4cebfbf89d34869c74081c42577 (patch) | |
tree | 3ed316eca5ab3228e2e01fc4a83c04297becd105 /drivers/usb/host/whci | |
parent | d409f3bf47c5e5ae10601d079204e263bc176bcf (diff) |
wusb: do a proper channel stop
When stopping the WUSB channel the host should send Channel Stop IEs giving
the WUSB Channel Time of the last MMC. Both WHCI and HWA hosts provide a
channel stop command for this.
Signed-off-by: David Vrabel <david.vrabel@csr.com>
Diffstat (limited to 'drivers/usb/host/whci')
-rw-r--r-- | drivers/usb/host/whci/whcd.h | 2 | ||||
-rw-r--r-- | drivers/usb/host/whci/whci-hc.h | 2 | ||||
-rw-r--r-- | drivers/usb/host/whci/wusb.c | 15 |
3 files changed, 15 insertions, 4 deletions
diff --git a/drivers/usb/host/whci/whcd.h b/drivers/usb/host/whci/whcd.h index 1d2a53bd39fd..1bbb8cb6bf80 100644 --- a/drivers/usb/host/whci/whcd.h +++ b/drivers/usb/host/whci/whcd.h | |||
@@ -136,7 +136,7 @@ int whc_do_gencmd(struct whc *whc, u32 cmd, u32 params, void *addr, size_t len); | |||
136 | 136 | ||
137 | /* wusb.c */ | 137 | /* wusb.c */ |
138 | int whc_wusbhc_start(struct wusbhc *wusbhc); | 138 | int whc_wusbhc_start(struct wusbhc *wusbhc); |
139 | void whc_wusbhc_stop(struct wusbhc *wusbhc); | 139 | void whc_wusbhc_stop(struct wusbhc *wusbhc, int delay); |
140 | int whc_mmcie_add(struct wusbhc *wusbhc, u8 interval, u8 repeat_cnt, | 140 | int whc_mmcie_add(struct wusbhc *wusbhc, u8 interval, u8 repeat_cnt, |
141 | u8 handle, struct wuie_hdr *wuie); | 141 | u8 handle, struct wuie_hdr *wuie); |
142 | int whc_mmcie_rm(struct wusbhc *wusbhc, u8 handle); | 142 | int whc_mmcie_rm(struct wusbhc *wusbhc, u8 handle); |
diff --git a/drivers/usb/host/whci/whci-hc.h b/drivers/usb/host/whci/whci-hc.h index bff1eb7a35cf..51df7e313b38 100644 --- a/drivers/usb/host/whci/whci-hc.h +++ b/drivers/usb/host/whci/whci-hc.h | |||
@@ -410,6 +410,8 @@ struct dn_buf_entry { | |||
410 | # define WUSBDNTSCTRL_SLOTS(s) ((s) << 0) | 410 | # define WUSBDNTSCTRL_SLOTS(s) ((s) << 0) |
411 | 411 | ||
412 | #define WUSBTIME 0x68 | 412 | #define WUSBTIME 0x68 |
413 | # define WUSBTIME_CHANNEL_TIME_MASK 0x00ffffff | ||
414 | |||
413 | #define WUSBBPST 0x6c | 415 | #define WUSBBPST 0x6c |
414 | #define WUSBDIBUPDATED 0x70 | 416 | #define WUSBDIBUPDATED 0x70 |
415 | 417 | ||
diff --git a/drivers/usb/host/whci/wusb.c b/drivers/usb/host/whci/wusb.c index 66e4ddcd961d..2befd475def4 100644 --- a/drivers/usb/host/whci/wusb.c +++ b/drivers/usb/host/whci/wusb.c | |||
@@ -64,8 +64,9 @@ static int whc_update_di(struct whc *whc, int idx) | |||
64 | } | 64 | } |
65 | 65 | ||
66 | /* | 66 | /* |
67 | * WHCI starts and stops MMCs based on there being a valid GTK so | 67 | * WHCI starts MMCs based on there being a valid GTK so these need |
68 | * these need only start/stop the asynchronous and periodic schedules. | 68 | * only start/stop the asynchronous and periodic schedules and send a |
69 | * channel stop command. | ||
69 | */ | 70 | */ |
70 | 71 | ||
71 | int whc_wusbhc_start(struct wusbhc *wusbhc) | 72 | int whc_wusbhc_start(struct wusbhc *wusbhc) |
@@ -78,12 +79,20 @@ int whc_wusbhc_start(struct wusbhc *wusbhc) | |||
78 | return 0; | 79 | return 0; |
79 | } | 80 | } |
80 | 81 | ||
81 | void whc_wusbhc_stop(struct wusbhc *wusbhc) | 82 | void whc_wusbhc_stop(struct wusbhc *wusbhc, int delay) |
82 | { | 83 | { |
83 | struct whc *whc = wusbhc_to_whc(wusbhc); | 84 | struct whc *whc = wusbhc_to_whc(wusbhc); |
85 | u32 stop_time, now_time; | ||
86 | int ret; | ||
84 | 87 | ||
85 | pzl_stop(whc); | 88 | pzl_stop(whc); |
86 | asl_stop(whc); | 89 | asl_stop(whc); |
90 | |||
91 | now_time = le_readl(whc->base + WUSBTIME) & WUSBTIME_CHANNEL_TIME_MASK; | ||
92 | stop_time = (now_time + ((delay * 8) << 7)) & 0x00ffffff; | ||
93 | ret = whc_do_gencmd(whc, WUSBGENCMDSTS_CHAN_STOP, stop_time, NULL, 0); | ||
94 | if (ret == 0) | ||
95 | msleep(delay); | ||
87 | } | 96 | } |
88 | 97 | ||
89 | int whc_mmcie_add(struct wusbhc *wusbhc, u8 interval, u8 repeat_cnt, | 98 | int whc_mmcie_add(struct wusbhc *wusbhc, u8 interval, u8 repeat_cnt, |