ehci->periodic_size = DEFAULT_I_TDPS;
        INIT_LIST_HEAD(&ehci->async_unlink);
        INIT_LIST_HEAD(&ehci->async_idle);
+       INIT_LIST_HEAD(&ehci->intr_unlink_wait);
        INIT_LIST_HEAD(&ehci->intr_unlink);
        INIT_LIST_HEAD(&ehci->intr_qh_list);
        INIT_LIST_HEAD(&ehci->cached_itd_list);
 
 
        end_unlink_async(ehci);
        unlink_empty_async_suspended(ehci);
+       ehci_handle_start_intr_unlinks(ehci);
        ehci_handle_intr_unlinks(ehci);
        end_free_itds(ehci);
 
 
        qh->qh_dma = dma;
        // INIT_LIST_HEAD (&qh->qh_list);
        INIT_LIST_HEAD (&qh->qtd_list);
+       INIT_LIST_HEAD(&qh->unlink_node);
 
        /* dummy td enables safe urb queuing */
        qh->dummy = ehci_qtd_alloc (ehci, flags);
 
        list_del(&qh->intr_node);
 }
 
+static void cancel_unlink_wait_intr(struct ehci_hcd *ehci, struct ehci_qh *qh)
+{
+       if (qh->qh_state != QH_STATE_LINKED ||
+                       list_empty(&qh->unlink_node))
+               return;
+
+       list_del_init(&qh->unlink_node);
+
+       /*
+        * TODO: disable the event of EHCI_HRTIMER_START_UNLINK_INTR for
+        * avoiding unnecessary CPU wakeup
+        */
+}
+
 static void start_unlink_intr(struct ehci_hcd *ehci, struct ehci_qh *qh)
 {
        /* If the QH isn't linked then there's nothing we can do. */
        if (qh->qh_state != QH_STATE_LINKED)
                return;
 
+       /* if the qh is waiting for unlink, cancel it now */
+       cancel_unlink_wait_intr(ehci, qh);
+
        qh_unlink_periodic (ehci, qh);
 
        /* Make sure the unlinks are visible before starting the timer */
        }
 }
 
+/*
+ * It is common only one intr URB is scheduled on one qh, and
+ * given complete() is run in tasklet context, introduce a bit
+ * delay to avoid unlink qh too early.
+ */
+static void start_unlink_intr_wait(struct ehci_hcd *ehci,
+                                  struct ehci_qh *qh)
+{
+       qh->unlink_cycle = ehci->intr_unlink_wait_cycle;
+
+       /* New entries go at the end of the intr_unlink_wait list */
+       list_add_tail(&qh->unlink_node, &ehci->intr_unlink_wait);
+
+       if (ehci->rh_state < EHCI_RH_RUNNING)
+               ehci_handle_start_intr_unlinks(ehci);
+       else if (ehci->intr_unlink_wait.next == &qh->unlink_node) {
+               ehci_enable_event(ehci, EHCI_HRTIMER_START_UNLINK_INTR, true);
+               ++ehci->intr_unlink_wait_cycle;
+       }
+}
+
 static void end_unlink_intr(struct ehci_hcd *ehci, struct ehci_qh *qh)
 {
        struct ehci_qh_hw       *hw = qh->hw;
        if (qh->qh_state == QH_STATE_IDLE) {
                qh_refresh(ehci, qh);
                qh_link_periodic(ehci, qh);
+       } else {
+               /* cancel unlink wait for the qh */
+               cancel_unlink_wait_intr(ehci, qh);
        }
 
        /* ... update usbfs periodic stats */
                         * in qh_unlink_periodic().
                         */
                        temp = qh_completions(ehci, qh);
-                       if (unlikely(temp || (list_empty(&qh->qtd_list) &&
-                                       qh->qh_state == QH_STATE_LINKED)))
+                       if (unlikely(temp))
                                start_unlink_intr(ehci, qh);
+                       else if (unlikely(list_empty(&qh->qtd_list) &&
+                                       qh->qh_state == QH_STATE_LINKED))
+                               start_unlink_intr_wait(ehci, qh);
                }
        }
 }
 
        1 * NSEC_PER_MSEC,      /* EHCI_HRTIMER_POLL_DEAD */
        1125 * NSEC_PER_USEC,   /* EHCI_HRTIMER_UNLINK_INTR */
        2 * NSEC_PER_MSEC,      /* EHCI_HRTIMER_FREE_ITDS */
+       5 * NSEC_PER_MSEC,      /* EHCI_HRTIMER_START_UNLINK_INTR */
        6 * NSEC_PER_MSEC,      /* EHCI_HRTIMER_ASYNC_UNLINKS */
        10 * NSEC_PER_MSEC,     /* EHCI_HRTIMER_IAA_WATCHDOG */
        10 * NSEC_PER_MSEC,     /* EHCI_HRTIMER_DISABLE_PERIODIC */
        /* Not in process context, so don't try to reset the controller */
 }
 
+/* start to unlink interrupt QHs  */
+static void ehci_handle_start_intr_unlinks(struct ehci_hcd *ehci)
+{
+       bool            stopped = (ehci->rh_state < EHCI_RH_RUNNING);
+
+       /*
+        * Process all the QHs on the intr_unlink list that were added
+        * before the current unlink cycle began.  The list is in
+        * temporal order, so stop when we reach the first entry in the
+        * current cycle.  But if the root hub isn't running then
+        * process all the QHs on the list.
+        */
+       while (!list_empty(&ehci->intr_unlink_wait)) {
+               struct ehci_qh  *qh;
+
+               qh = list_first_entry(&ehci->intr_unlink_wait,
+                               struct ehci_qh, unlink_node);
+               if (!stopped && (qh->unlink_cycle ==
+                               ehci->intr_unlink_wait_cycle))
+                       break;
+               list_del_init(&qh->unlink_node);
+               start_unlink_intr(ehci, qh);
+       }
+
+       /* Handle remaining entries later */
+       if (!list_empty(&ehci->intr_unlink_wait)) {
+               ehci_enable_event(ehci, EHCI_HRTIMER_START_UNLINK_INTR, true);
+               ++ehci->intr_unlink_wait_cycle;
+       }
+}
 
 /* Handle unlinked interrupt QHs once they are gone from the hardware */
 static void ehci_handle_intr_unlinks(struct ehci_hcd *ehci)
                                unlink_node);
                if (!stopped && qh->unlink_cycle == ehci->intr_unlink_cycle)
                        break;
-               list_del(&qh->unlink_node);
+               list_del_init(&qh->unlink_node);
                end_unlink_intr(ehci, qh);
        }
 
        ehci_handle_controller_death,   /* EHCI_HRTIMER_POLL_DEAD */
        ehci_handle_intr_unlinks,       /* EHCI_HRTIMER_UNLINK_INTR */
        end_free_itds,                  /* EHCI_HRTIMER_FREE_ITDS */
+       ehci_handle_start_intr_unlinks, /* EHCI_HRTIMER_START_UNLINK_INTR */
        unlink_empty_async,             /* EHCI_HRTIMER_ASYNC_UNLINKS */
        ehci_iaa_watchdog,              /* EHCI_HRTIMER_IAA_WATCHDOG */
        ehci_disable_PSE,               /* EHCI_HRTIMER_DISABLE_PERIODIC */
 
        EHCI_HRTIMER_POLL_DEAD,         /* Wait for dead controller to stop */
        EHCI_HRTIMER_UNLINK_INTR,       /* Wait for interrupt QH unlink */
        EHCI_HRTIMER_FREE_ITDS,         /* Wait for unused iTDs and siTDs */
+       EHCI_HRTIMER_START_UNLINK_INTR, /* Unlink empty interrupt QHs */
        EHCI_HRTIMER_ASYNC_UNLINKS,     /* Unlink empty async QHs */
        EHCI_HRTIMER_IAA_WATCHDOG,      /* Handle lost IAA interrupts */
        EHCI_HRTIMER_DISABLE_PERIODIC,  /* Wait to disable periodic sched */
        unsigned                i_thresh;       /* uframes HC might cache */
 
        union ehci_shadow       *pshadow;       /* mirror hw periodic table */
+       struct list_head        intr_unlink_wait;
        struct list_head        intr_unlink;
+       unsigned                intr_unlink_wait_cycle;
        unsigned                intr_unlink_cycle;
        unsigned                now_frame;      /* frame from HC hardware */
        unsigned                last_iso_frame; /* last frame scanned for iso */