diff options
author | David Vrabel <david.vrabel@csr.com> | 2008-10-27 15:42:31 +0000 |
---|---|---|
committer | David Vrabel <david.vrabel@csr.com> | 2008-10-28 12:08:46 +0000 |
commit | 4d2bea4ca0adb4cebfbf89d34869c74081c42577 (patch) | |
tree | 3ed316eca5ab3228e2e01fc4a83c04297becd105 /drivers/usb/host/whci/wusb.c | |
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/wusb.c')
-rw-r--r-- | drivers/usb/host/whci/wusb.c | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/drivers/usb/host/whci/wusb.c b/drivers/usb/host/whci/wusb.c index 66e4ddcd961..2befd475def 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) } /* - * WHCI starts and stops MMCs based on there being a valid GTK so - * these need only start/stop the asynchronous and periodic schedules. + * WHCI starts MMCs based on there being a valid GTK so these need + * only start/stop the asynchronous and periodic schedules and send a + * channel stop command. */ int whc_wusbhc_start(struct wusbhc *wusbhc) @@ -78,12 +79,20 @@ int whc_wusbhc_start(struct wusbhc *wusbhc) return 0; } -void whc_wusbhc_stop(struct wusbhc *wusbhc) +void whc_wusbhc_stop(struct wusbhc *wusbhc, int delay) { struct whc *whc = wusbhc_to_whc(wusbhc); + u32 stop_time, now_time; + int ret; pzl_stop(whc); asl_stop(whc); + + now_time = le_readl(whc->base + WUSBTIME) & WUSBTIME_CHANNEL_TIME_MASK; + stop_time = (now_time + ((delay * 8) << 7)) & 0x00ffffff; + ret = whc_do_gencmd(whc, WUSBGENCMDSTS_CHAN_STOP, stop_time, NULL, 0); + if (ret == 0) + msleep(delay); } int whc_mmcie_add(struct wusbhc *wusbhc, u8 interval, u8 repeat_cnt, |