if (result < 0)
                goto error_set_cluster_id;
 
-       result = wa_nep_arm(&hwahc->wa, GFP_KERNEL);
-       if (result < 0) {
-               dev_err(dev, "cannot listen to notifications: %d\n", result);
-               goto error_stop;
-       }
        usb_hcd->uses_new_polling = 1;
        usb_hcd->poll_rh = 1;
        usb_hcd->state = HC_STATE_RUNNING;
        d_fnend(4, dev, "(hwahc %p) = %d\n", hwahc, result);
        return result;
 
-error_stop:
-       __wa_stop(&hwahc->wa);
 error_set_cluster_id:
        wusb_cluster_id_put(wusbhc->cluster_id);
 error_cluster_id_get:
 
 }
 
-/*
- * FIXME: break this function up
- */
-static int __hwahc_op_wusbhc_start(struct wusbhc *wusbhc)
-{
-       int result;
-       struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);
-       struct device *dev = &hwahc->wa.usb_iface->dev;
-
-       /* Set up a Host Info WUSB Information Element */
-       d_fnstart(4, dev, "(hwahc %p)\n", hwahc);
-       result = -ENOSPC;
-
-       result = __wa_set_feature(&hwahc->wa, WA_ENABLE);
-       if (result < 0) {
-               dev_err(dev, "error commanding HC to start: %d\n", result);
-               goto error_stop;
-       }
-       result = __wa_wait_status(&hwahc->wa, WA_ENABLE, WA_ENABLE);
-       if (result < 0) {
-               dev_err(dev, "error waiting for HC to start: %d\n", result);
-               goto error_stop;
-       }
-       result = 0;
-out:
-       d_fnend(4, dev, "(hwahc %p) = %d\n", hwahc, result);
-       return result;
-
-error_stop:
-       result = __wa_clear_feature(&hwahc->wa, WA_ENABLE);
-       goto out;
-}
-
 static int hwahc_op_suspend(struct usb_hcd *usb_hcd, pm_message_t msg)
 {
        struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);
        return -ENOSYS;
 }
 
-static void __hwahc_op_wusbhc_stop(struct wusbhc *wusbhc)
-{
-       int result;
-       struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);
-       struct device *dev = &hwahc->wa.usb_iface->dev;
-
-       d_fnstart(4, dev, "(hwahc %p)\n", hwahc);
-       /* Nothing for now */
-       d_fnend(4, dev, "(hwahc %p) = %d\n", hwahc, result);
-       return;
-}
-
 /*
  * No need to abort pipes, as when this is called, all the children
  * has been disconnected and that has done it [through
        d_fnstart(4, dev, "(hwahc %p)\n", hwahc);
        mutex_lock(&wusbhc->mutex);
        wusbhc_stop(wusbhc);
-       wa_nep_disarm(&hwahc->wa);
-       result = __wa_stop(&hwahc->wa);
        wusb_cluster_id_put(wusbhc->cluster_id);
        mutex_unlock(&wusbhc->mutex);
        d_fnend(4, dev, "(hwahc %p) = %d\n", hwahc, result);
        rpipe_ep_disable(&hwahc->wa, ep);
 }
 
+static int __hwahc_op_wusbhc_start(struct wusbhc *wusbhc)
+{
+       int result;
+       struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);
+       struct device *dev = &hwahc->wa.usb_iface->dev;
+
+       result = __wa_set_feature(&hwahc->wa, WA_ENABLE);
+       if (result < 0) {
+               dev_err(dev, "error commanding HC to start: %d\n", result);
+               goto error_stop;
+       }
+       result = __wa_wait_status(&hwahc->wa, WA_ENABLE, WA_ENABLE);
+       if (result < 0) {
+               dev_err(dev, "error waiting for HC to start: %d\n", result);
+               goto error_stop;
+       }
+       result = wa_nep_arm(&hwahc->wa, GFP_KERNEL);
+       if (result < 0) {
+               dev_err(dev, "cannot listen to notifications: %d\n", result);
+               goto error_stop;
+       }
+       return result;
+
+error_stop:
+       __wa_clear_feature(&hwahc->wa, WA_ENABLE);
+       return result;
+}
+
+static void __hwahc_op_wusbhc_stop(struct wusbhc *wusbhc, int delay)
+{
+       struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);
+       struct wahc *wa = &hwahc->wa;
+       u8 iface_no = wa->usb_iface->cur_altsetting->desc.bInterfaceNumber;
+       int ret;
+
+       ret = usb_control_msg(wa->usb_dev, usb_sndctrlpipe(wa->usb_dev, 0),
+                             WUSB_REQ_CHAN_STOP,
+                             USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+                             delay * 1000,
+                             iface_no,
+                             NULL, 0, 1000 /* FIXME: arbitrary */);
+       if (ret == 0)
+               msleep(delay);
+
+       wa_nep_disarm(&hwahc->wa);
+       __wa_stop(&hwahc->wa);
+}
+
 /*
  * Set the UWB MAS allocation for the WUSB cluster
  *
 
 }
 
 /*
- * 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)
        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,
 
 #include <linux/uwb.h>
 #include <linux/usb/wusb.h>
 
+/*
+ * Time from a WUSB channel stop request to the last transmitted MMC.
+ *
+ * This needs to be > 4.096 ms in case no MMCs can be transmitted in
+ * zone 0.
+ */
+#define WUSB_CHANNEL_STOP_DELAY_MS 8
 
 /**
  * Wireless USB device
  * @mmcies_max    Max number of Information Elements this HC can send
  *                 in its MMC. Read-only.
  *
+ * @start          Start the WUSB channel.
+ *
+ * @stop           Stop the WUSB channel after the specified number of
+ *                 milliseconds.  Channel Stop IEs should be transmitted
+ *                 as required by [WUSB] 4.16.2.1.
+ *
  * @mmcie_add     HC specific operation (WHCI or HWA) for adding an
  *                 MMCIE.
  *
  * @mmcie_rm      HC specific operation (WHCI or HWA) for removing an
  *                 MMCIE.
  *
- * @enc_types     Array which describes the encryptions methods
- *                 supported by the host as described in WUSB1.0 --
- *                 one entry per supported method. As of WUSB1.0 there
- *                 is only four methods, we make space for eight just in
- *                 case they decide to add some more (and pray they do
- *                 it in sequential order). if 'enc_types[enc_method]
- *                 != 0', then it is supported by the host. enc_method
- *                 is USB_ENC_TYPE*.
- *
  * @set_ptk:       Set the PTK and enable encryption for a device. Or, if
  *                 the supplied key is NULL, disable encryption for that
  *                 device.
        u8 mmcies_max;
        /* FIXME: make wusbhc_ops? */
        int (*start)(struct wusbhc *wusbhc);
-       void (*stop)(struct wusbhc *wusbhc);
+       void (*stop)(struct wusbhc *wusbhc, int delay);
        int (*mmcie_add)(struct wusbhc *wusbhc, u8 interval, u8 repeat_cnt,
                         u8 handle, struct wuie_hdr *wuie);
        int (*mmcie_rm)(struct wusbhc *wusbhc, u8 handle);