diff options
Diffstat (limited to 'drivers/usb/host/ehci.h')
| -rw-r--r-- | drivers/usb/host/ehci.h | 19 |
1 files changed, 10 insertions, 9 deletions
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 35a03095757e..90245fd8bac4 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h | |||
| @@ -177,6 +177,15 @@ timer_action_done (struct ehci_hcd *ehci, enum ehci_timer_action action) | |||
| 177 | static inline void | 177 | static inline void |
| 178 | timer_action (struct ehci_hcd *ehci, enum ehci_timer_action action) | 178 | timer_action (struct ehci_hcd *ehci, enum ehci_timer_action action) |
| 179 | { | 179 | { |
| 180 | /* Don't override timeouts which shrink or (later) disable | ||
| 181 | * the async ring; just the I/O watchdog. Note that if a | ||
| 182 | * SHRINK were pending, OFF would never be requested. | ||
| 183 | */ | ||
| 184 | if (timer_pending(&ehci->watchdog) | ||
| 185 | && ((BIT(TIMER_ASYNC_SHRINK) | BIT(TIMER_ASYNC_OFF)) | ||
| 186 | & ehci->actions)) | ||
| 187 | return; | ||
| 188 | |||
| 180 | if (!test_and_set_bit (action, &ehci->actions)) { | 189 | if (!test_and_set_bit (action, &ehci->actions)) { |
| 181 | unsigned long t; | 190 | unsigned long t; |
| 182 | 191 | ||
| @@ -192,15 +201,7 @@ timer_action (struct ehci_hcd *ehci, enum ehci_timer_action action) | |||
| 192 | t = EHCI_SHRINK_JIFFIES; | 201 | t = EHCI_SHRINK_JIFFIES; |
| 193 | break; | 202 | break; |
| 194 | } | 203 | } |
| 195 | t += jiffies; | 204 | mod_timer(&ehci->watchdog, t + jiffies); |
| 196 | // all timings except IAA watchdog can be overridden. | ||
| 197 | // async queue SHRINK often precedes IAA. while it's ready | ||
| 198 | // to go OFF neither can matter, and afterwards the IO | ||
| 199 | // watchdog stops unless there's still periodic traffic. | ||
| 200 | if (time_before_eq(t, ehci->watchdog.expires) | ||
| 201 | && timer_pending (&ehci->watchdog)) | ||
| 202 | return; | ||
| 203 | mod_timer (&ehci->watchdog, t); | ||
| 204 | } | 205 | } |
| 205 | } | 206 | } |
| 206 | 207 | ||
