aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/host/ehci-hcd.c47
-rw-r--r--drivers/usb/host/ehci-hub.c5
-rw-r--r--drivers/usb/host/ehci-q.c1
-rw-r--r--drivers/usb/host/ehci-sched.c3
-rw-r--r--drivers/usb/host/ehci-timer.c21
-rw-r--r--drivers/usb/host/ehci.h13
6 files changed, 25 insertions, 65 deletions
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index c13dad8a8503..9f26080889f5 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -93,8 +93,6 @@ static const char hcd_name [] = "ehci_hcd";
93 */ 93 */
94#define EHCI_TUNE_FLS 1 /* (medium) 512-frame schedule */ 94#define EHCI_TUNE_FLS 1 /* (medium) 512-frame schedule */
95 95
96#define EHCI_IO_JIFFIES (HZ/10) /* io watchdog > irq_thresh */
97
98/* Initial IRQ latency: faster than hw default */ 96/* Initial IRQ latency: faster than hw default */
99static int log2_irq_thresh = 0; // 0 to 6 97static int log2_irq_thresh = 0; // 0 to 6
100module_param (log2_irq_thresh, int, S_IRUGO); 98module_param (log2_irq_thresh, int, S_IRUGO);
@@ -125,25 +123,6 @@ MODULE_PARM_DESC(hird, "host initiated resume duration, +1 for each 75us");
125 123
126/*-------------------------------------------------------------------------*/ 124/*-------------------------------------------------------------------------*/
127 125
128static void
129timer_action(struct ehci_hcd *ehci, enum ehci_timer_action action)
130{
131 if (!test_and_set_bit(action, &ehci->actions)) {
132 unsigned long t;
133
134 switch (action) {
135 case TIMER_IO_WATCHDOG:
136 if (!ehci->need_io_watchdog)
137 return;
138 t = EHCI_IO_JIFFIES;
139 break;
140 }
141 mod_timer(&ehci->watchdog, t + jiffies);
142 }
143}
144
145/*-------------------------------------------------------------------------*/
146
147/* 126/*
148 * handshake - spin reading hc until handshake completes or fails 127 * handshake - spin reading hc until handshake completes or fails
149 * @ptr: address of hc register to be read 128 * @ptr: address of hc register to be read
@@ -307,19 +286,6 @@ static void end_unlink_intr(struct ehci_hcd *ehci, struct ehci_qh *qh);
307 286
308/*-------------------------------------------------------------------------*/ 287/*-------------------------------------------------------------------------*/
309 288
310static void ehci_watchdog(unsigned long param)
311{
312 struct ehci_hcd *ehci = (struct ehci_hcd *) param;
313 unsigned long flags;
314
315 spin_lock_irqsave(&ehci->lock, flags);
316
317 /* ehci could run by timer, without IRQs ... */
318 ehci_work (ehci);
319
320 spin_unlock_irqrestore (&ehci->lock, flags);
321}
322
323/* On some systems, leaving remote wakeup enabled prevents system shutdown. 289/* On some systems, leaving remote wakeup enabled prevents system shutdown.
324 * The firmware seems to think that powering off is a wakeup event! 290 * The firmware seems to think that powering off is a wakeup event!
325 * This routine turns off remote wakeup and everything else, on all ports. 291 * This routine turns off remote wakeup and everything else, on all ports.
@@ -357,8 +323,6 @@ static void ehci_shutdown(struct usb_hcd *hcd)
357{ 323{
358 struct ehci_hcd *ehci = hcd_to_ehci(hcd); 324 struct ehci_hcd *ehci = hcd_to_ehci(hcd);
359 325
360 del_timer_sync(&ehci->watchdog);
361
362 spin_lock_irq(&ehci->lock); 326 spin_lock_irq(&ehci->lock);
363 ehci->rh_state = EHCI_RH_STOPPING; 327 ehci->rh_state = EHCI_RH_STOPPING;
364 ehci_silence_controller(ehci); 328 ehci_silence_controller(ehci);
@@ -394,8 +358,6 @@ static void ehci_port_power (struct ehci_hcd *ehci, int is_on)
394 */ 358 */
395static void ehci_work (struct ehci_hcd *ehci) 359static void ehci_work (struct ehci_hcd *ehci)
396{ 360{
397 timer_action_done (ehci, TIMER_IO_WATCHDOG);
398
399 /* another CPU may drop ehci->lock during a schedule scan while 361 /* another CPU may drop ehci->lock during a schedule scan while
400 * it reports urb completions. this flag guards against bogus 362 * it reports urb completions. this flag guards against bogus
401 * attempts at re-entrant schedule scanning. 363 * attempts at re-entrant schedule scanning.
@@ -422,10 +384,7 @@ static void ehci_work (struct ehci_hcd *ehci)
422 * misplace IRQs, and should let us run completely without IRQs. 384 * misplace IRQs, and should let us run completely without IRQs.
423 * such lossage has been observed on both VT6202 and VT8235. 385 * such lossage has been observed on both VT6202 and VT8235.
424 */ 386 */
425 if (ehci->rh_state == EHCI_RH_RUNNING && 387 turn_on_io_watchdog(ehci);
426 (ehci->async->qh_next.ptr != NULL ||
427 ehci->periodic_count != 0))
428 timer_action (ehci, TIMER_IO_WATCHDOG);
429} 388}
430 389
431/* 390/*
@@ -438,7 +397,6 @@ static void ehci_stop (struct usb_hcd *hcd)
438 ehci_dbg (ehci, "stop\n"); 397 ehci_dbg (ehci, "stop\n");
439 398
440 /* no more interrupts ... */ 399 /* no more interrupts ... */
441 del_timer_sync (&ehci->watchdog);
442 400
443 spin_lock_irq(&ehci->lock); 401 spin_lock_irq(&ehci->lock);
444 ehci->enabled_hrtimer_events = 0; 402 ehci->enabled_hrtimer_events = 0;
@@ -490,9 +448,6 @@ static int ehci_init(struct usb_hcd *hcd)
490 * keep io watchdog by default, those good HCDs could turn off it later 448 * keep io watchdog by default, those good HCDs could turn off it later
491 */ 449 */
492 ehci->need_io_watchdog = 1; 450 ehci->need_io_watchdog = 1;
493 init_timer(&ehci->watchdog);
494 ehci->watchdog.function = ehci_watchdog;
495 ehci->watchdog.data = (unsigned long) ehci;
496 451
497 hrtimer_init(&ehci->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS); 452 hrtimer_init(&ehci->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
498 ehci->hrtimer.function = ehci_hrtimer_func; 453 ehci->hrtimer.function = ehci_hrtimer_func;
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
index 5d84562e2716..05490d387fd2 100644
--- a/drivers/usb/host/ehci-hub.c
+++ b/drivers/usb/host/ehci-hub.c
@@ -208,7 +208,6 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
208 208
209 if (time_before (jiffies, ehci->next_statechange)) 209 if (time_before (jiffies, ehci->next_statechange))
210 msleep(5); 210 msleep(5);
211 del_timer_sync(&ehci->watchdog);
212 211
213 spin_lock_irq (&ehci->lock); 212 spin_lock_irq (&ehci->lock);
214 213
@@ -316,10 +315,6 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
316 ehci->next_hrtimer_event = EHCI_HRTIMER_NO_EVENT; 315 ehci->next_hrtimer_event = EHCI_HRTIMER_NO_EVENT;
317 spin_unlock_irq (&ehci->lock); 316 spin_unlock_irq (&ehci->lock);
318 317
319 /* ehci_work() may have re-enabled the watchdog timer, which we do not
320 * want, and so we must delete any pending watchdog timer events.
321 */
322 del_timer_sync(&ehci->watchdog);
323 hrtimer_cancel(&ehci->hrtimer); 318 hrtimer_cancel(&ehci->hrtimer);
324 return 0; 319 return 0;
325} 320}
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
index c9c7f7b3b7db..9bc39ca460c8 100644
--- a/drivers/usb/host/ehci-q.c
+++ b/drivers/usb/host/ehci-q.c
@@ -970,6 +970,7 @@ static void enable_async(struct ehci_hcd *ehci)
970 970
971 /* Don't start the schedule until ASS is 0 */ 971 /* Don't start the schedule until ASS is 0 */
972 ehci_poll_ASS(ehci); 972 ehci_poll_ASS(ehci);
973 turn_on_io_watchdog(ehci);
973} 974}
974 975
975static void disable_async(struct ehci_hcd *ehci) 976static void disable_async(struct ehci_hcd *ehci)
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
index 263b542985c0..26ce8fef0e5b 100644
--- a/drivers/usb/host/ehci-sched.c
+++ b/drivers/usb/host/ehci-sched.c
@@ -489,6 +489,7 @@ static void enable_periodic(struct ehci_hcd *ehci)
489 489
490 /* Don't start the schedule until PSS is 0 */ 490 /* Don't start the schedule until PSS is 0 */
491 ehci_poll_PSS(ehci); 491 ehci_poll_PSS(ehci);
492 turn_on_io_watchdog(ehci);
492} 493}
493 494
494static void disable_periodic(struct ehci_hcd *ehci) 495static void disable_periodic(struct ehci_hcd *ehci)
@@ -1649,7 +1650,6 @@ static void itd_link_urb(
1649 iso_sched_free (stream, iso_sched); 1650 iso_sched_free (stream, iso_sched);
1650 urb->hcpriv = NULL; 1651 urb->hcpriv = NULL;
1651 1652
1652 timer_action (ehci, TIMER_IO_WATCHDOG);
1653 ++ehci->isoc_count; 1653 ++ehci->isoc_count;
1654 enable_periodic(ehci); 1654 enable_periodic(ehci);
1655} 1655}
@@ -2052,7 +2052,6 @@ static void sitd_link_urb(
2052 iso_sched_free (stream, sched); 2052 iso_sched_free (stream, sched);
2053 urb->hcpriv = NULL; 2053 urb->hcpriv = NULL;
2054 2054
2055 timer_action (ehci, TIMER_IO_WATCHDOG);
2056 ++ehci->isoc_count; 2055 ++ehci->isoc_count;
2057 enable_periodic(ehci); 2056 enable_periodic(ehci);
2058} 2057}
diff --git a/drivers/usb/host/ehci-timer.c b/drivers/usb/host/ehci-timer.c
index 0e28bae78d18..eb896a2c8f2e 100644
--- a/drivers/usb/host/ehci-timer.c
+++ b/drivers/usb/host/ehci-timer.c
@@ -76,6 +76,7 @@ static unsigned event_delays_ns[] = {
76 10 * NSEC_PER_MSEC, /* EHCI_HRTIMER_IAA_WATCHDOG */ 76 10 * NSEC_PER_MSEC, /* EHCI_HRTIMER_IAA_WATCHDOG */
77 10 * NSEC_PER_MSEC, /* EHCI_HRTIMER_DISABLE_PERIODIC */ 77 10 * NSEC_PER_MSEC, /* EHCI_HRTIMER_DISABLE_PERIODIC */
78 15 * NSEC_PER_MSEC, /* EHCI_HRTIMER_DISABLE_ASYNC */ 78 15 * NSEC_PER_MSEC, /* EHCI_HRTIMER_DISABLE_ASYNC */
79 100 * NSEC_PER_MSEC, /* EHCI_HRTIMER_IO_WATCHDOG */
79}; 80};
80 81
81/* Enable a pending hrtimer event */ 82/* Enable a pending hrtimer event */
@@ -332,6 +333,25 @@ static void ehci_iaa_watchdog(struct ehci_hcd *ehci)
332} 333}
333 334
334 335
336/* Enable the I/O watchdog, if appropriate */
337static void turn_on_io_watchdog(struct ehci_hcd *ehci)
338{
339 /* Not needed if the controller isn't running or it's already enabled */
340 if (ehci->rh_state != EHCI_RH_RUNNING ||
341 (ehci->enabled_hrtimer_events &
342 BIT(EHCI_HRTIMER_IO_WATCHDOG)))
343 return;
344
345 /*
346 * Isochronous transfers always need the watchdog.
347 * For other sorts we use it only if the flag is set.
348 */
349 if (ehci->isoc_count > 0 || (ehci->need_io_watchdog &&
350 ehci->async_count + ehci->intr_count > 0))
351 ehci_enable_event(ehci, EHCI_HRTIMER_IO_WATCHDOG, true);
352}
353
354
335/* 355/*
336 * Handler functions for the hrtimer event types. 356 * Handler functions for the hrtimer event types.
337 * Keep this array in the same order as the event types indexed by 357 * Keep this array in the same order as the event types indexed by
@@ -347,6 +367,7 @@ static void (*event_handlers[])(struct ehci_hcd *) = {
347 ehci_iaa_watchdog, /* EHCI_HRTIMER_IAA_WATCHDOG */ 367 ehci_iaa_watchdog, /* EHCI_HRTIMER_IAA_WATCHDOG */
348 ehci_disable_PSE, /* EHCI_HRTIMER_DISABLE_PERIODIC */ 368 ehci_disable_PSE, /* EHCI_HRTIMER_DISABLE_PERIODIC */
349 ehci_disable_ASE, /* EHCI_HRTIMER_DISABLE_ASYNC */ 369 ehci_disable_ASE, /* EHCI_HRTIMER_DISABLE_ASYNC */
370 ehci_work, /* EHCI_HRTIMER_IO_WATCHDOG */
350}; 371};
351 372
352static enum hrtimer_restart ehci_hrtimer_func(struct hrtimer *t) 373static enum hrtimer_restart ehci_hrtimer_func(struct hrtimer *t)
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index 08637183aad0..254f414bd0bd 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -88,6 +88,7 @@ enum ehci_hrtimer_event {
88 EHCI_HRTIMER_IAA_WATCHDOG, /* Handle lost IAA interrupts */ 88 EHCI_HRTIMER_IAA_WATCHDOG, /* Handle lost IAA interrupts */
89 EHCI_HRTIMER_DISABLE_PERIODIC, /* Wait to disable periodic sched */ 89 EHCI_HRTIMER_DISABLE_PERIODIC, /* Wait to disable periodic sched */
90 EHCI_HRTIMER_DISABLE_ASYNC, /* Wait to disable async sched */ 90 EHCI_HRTIMER_DISABLE_ASYNC, /* Wait to disable async sched */
91 EHCI_HRTIMER_IO_WATCHDOG, /* Check for missing IRQs */
91 EHCI_HRTIMER_NUM_EVENTS /* Must come last */ 92 EHCI_HRTIMER_NUM_EVENTS /* Must come last */
92}; 93};
93#define EHCI_HRTIMER_NO_EVENT 99 94#define EHCI_HRTIMER_NO_EVENT 99
@@ -177,8 +178,6 @@ struct ehci_hcd { /* one per controller */
177 struct dma_pool *itd_pool; /* itd per iso urb */ 178 struct dma_pool *itd_pool; /* itd per iso urb */
178 struct dma_pool *sitd_pool; /* sitd per split iso urb */ 179 struct dma_pool *sitd_pool; /* sitd per split iso urb */
179 180
180 struct timer_list watchdog;
181 unsigned long actions;
182 unsigned random_frame; 181 unsigned random_frame;
183 unsigned long next_statechange; 182 unsigned long next_statechange;
184 ktime_t last_periodic_enable; 183 ktime_t last_periodic_enable;
@@ -235,16 +234,6 @@ static inline struct usb_hcd *ehci_to_hcd (struct ehci_hcd *ehci)
235 return container_of ((void *) ehci, struct usb_hcd, hcd_priv); 234 return container_of ((void *) ehci, struct usb_hcd, hcd_priv);
236} 235}
237 236
238enum ehci_timer_action {
239 TIMER_IO_WATCHDOG,
240};
241
242static inline void
243timer_action_done (struct ehci_hcd *ehci, enum ehci_timer_action action)
244{
245 clear_bit (action, &ehci->actions);
246}
247
248/*-------------------------------------------------------------------------*/ 237/*-------------------------------------------------------------------------*/
249 238
250#include <linux/usb/ehci_def.h> 239#include <linux/usb/ehci_def.h>