USB: EHCI: use hrtimer for the I/O watchdog

This patch (as1586) replaces the kernel timer used by ehci-hcd as an
I/O watchdog with an hrtimer event.

Unlike in the current code, the watchdog event is now always enabled
whenever any isochronous URBs are active.  This will prevent bugs
caused by the periodic schedule wrapping around with no completion
interrupts; the watchdog handler is guaranteed to scan the isochronous
transfers at least once during each iteration of the schedule.  The
extra overhead will be negligible: one timer interrupt every 100 ms.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index c13dad8..9f26080 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -93,8 +93,6 @@
  */
 #define	EHCI_TUNE_FLS		1	/* (medium) 512-frame schedule */
 
-#define EHCI_IO_JIFFIES		(HZ/10)		/* io watchdog > irq_thresh */
-
 /* Initial IRQ latency:  faster than hw default */
 static int log2_irq_thresh = 0;		// 0 to 6
 module_param (log2_irq_thresh, int, S_IRUGO);
@@ -125,25 +123,6 @@
 
 /*-------------------------------------------------------------------------*/
 
-static void
-timer_action(struct ehci_hcd *ehci, enum ehci_timer_action action)
-{
-	if (!test_and_set_bit(action, &ehci->actions)) {
-		unsigned long t;
-
-		switch (action) {
-		case TIMER_IO_WATCHDOG:
-			if (!ehci->need_io_watchdog)
-				return;
-			t = EHCI_IO_JIFFIES;
-			break;
-		}
-		mod_timer(&ehci->watchdog, t + jiffies);
-	}
-}
-
-/*-------------------------------------------------------------------------*/
-
 /*
  * handshake - spin reading hc until handshake completes or fails
  * @ptr: address of hc register to be read
@@ -307,19 +286,6 @@
 
 /*-------------------------------------------------------------------------*/
 
-static void ehci_watchdog(unsigned long param)
-{
-	struct ehci_hcd		*ehci = (struct ehci_hcd *) param;
-	unsigned long		flags;
-
-	spin_lock_irqsave(&ehci->lock, flags);
-
-	/* ehci could run by timer, without IRQs ... */
-	ehci_work (ehci);
-
-	spin_unlock_irqrestore (&ehci->lock, flags);
-}
-
 /* On some systems, leaving remote wakeup enabled prevents system shutdown.
  * The firmware seems to think that powering off is a wakeup event!
  * This routine turns off remote wakeup and everything else, on all ports.
@@ -357,8 +323,6 @@
 {
 	struct ehci_hcd	*ehci = hcd_to_ehci(hcd);
 
-	del_timer_sync(&ehci->watchdog);
-
 	spin_lock_irq(&ehci->lock);
 	ehci->rh_state = EHCI_RH_STOPPING;
 	ehci_silence_controller(ehci);
@@ -394,8 +358,6 @@
  */
 static void ehci_work (struct ehci_hcd *ehci)
 {
-	timer_action_done (ehci, TIMER_IO_WATCHDOG);
-
 	/* another CPU may drop ehci->lock during a schedule scan while
 	 * it reports urb completions.  this flag guards against bogus
 	 * attempts at re-entrant schedule scanning.
@@ -422,10 +384,7 @@
 	 * misplace IRQs, and should let us run completely without IRQs.
 	 * such lossage has been observed on both VT6202 and VT8235.
 	 */
-	if (ehci->rh_state == EHCI_RH_RUNNING &&
-			(ehci->async->qh_next.ptr != NULL ||
-			 ehci->periodic_count != 0))
-		timer_action (ehci, TIMER_IO_WATCHDOG);
+	turn_on_io_watchdog(ehci);
 }
 
 /*
@@ -438,7 +397,6 @@
 	ehci_dbg (ehci, "stop\n");
 
 	/* no more interrupts ... */
-	del_timer_sync (&ehci->watchdog);
 
 	spin_lock_irq(&ehci->lock);
 	ehci->enabled_hrtimer_events = 0;
@@ -490,9 +448,6 @@
 	 * keep io watchdog by default, those good HCDs could turn off it later
 	 */
 	ehci->need_io_watchdog = 1;
-	init_timer(&ehci->watchdog);
-	ehci->watchdog.function = ehci_watchdog;
-	ehci->watchdog.data = (unsigned long) ehci;
 
 	hrtimer_init(&ehci->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
 	ehci->hrtimer.function = ehci_hrtimer_func;