aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/ehci-timer.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/ehci-timer.c')
-rw-r--r--drivers/usb/host/ehci-timer.c61
1 files changed, 29 insertions, 32 deletions
diff --git a/drivers/usb/host/ehci-timer.c b/drivers/usb/host/ehci-timer.c
index c3fa1305f830..e7363332887e 100644
--- a/drivers/usb/host/ehci-timer.c
+++ b/drivers/usb/host/ehci-timer.c
@@ -113,8 +113,8 @@ static void ehci_poll_ASS(struct ehci_hcd *ehci)
113 113
114 if (want != actual) { 114 if (want != actual) {
115 115
116 /* Poll again later, but give up after about 20 ms */ 116 /* Poll again later, but give up after about 2-4 ms */
117 if (ehci->ASS_poll_count++ < 20) { 117 if (ehci->ASS_poll_count++ < 2) {
118 ehci_enable_event(ehci, EHCI_HRTIMER_POLL_ASS, true); 118 ehci_enable_event(ehci, EHCI_HRTIMER_POLL_ASS, true);
119 return; 119 return;
120 } 120 }
@@ -159,8 +159,8 @@ static void ehci_poll_PSS(struct ehci_hcd *ehci)
159 159
160 if (want != actual) { 160 if (want != actual) {
161 161
162 /* Poll again later, but give up after about 20 ms */ 162 /* Poll again later, but give up after about 2-4 ms */
163 if (ehci->PSS_poll_count++ < 20) { 163 if (ehci->PSS_poll_count++ < 2) {
164 ehci_enable_event(ehci, EHCI_HRTIMER_POLL_PSS, true); 164 ehci_enable_event(ehci, EHCI_HRTIMER_POLL_PSS, true);
165 return; 165 return;
166 } 166 }
@@ -295,8 +295,7 @@ static void end_free_itds(struct ehci_hcd *ehci)
295/* Handle lost (or very late) IAA interrupts */ 295/* Handle lost (or very late) IAA interrupts */
296static void ehci_iaa_watchdog(struct ehci_hcd *ehci) 296static void ehci_iaa_watchdog(struct ehci_hcd *ehci)
297{ 297{
298 if (ehci->rh_state != EHCI_RH_RUNNING) 298 u32 cmd, status;
299 return;
300 299
301 /* 300 /*
302 * Lost IAA irqs wedge things badly; seen first with a vt8235. 301 * Lost IAA irqs wedge things badly; seen first with a vt8235.
@@ -304,34 +303,32 @@ static void ehci_iaa_watchdog(struct ehci_hcd *ehci)
304 * (a) SMP races against real IAA firing and retriggering, and 303 * (a) SMP races against real IAA firing and retriggering, and
305 * (b) clean HC shutdown, when IAA watchdog was pending. 304 * (b) clean HC shutdown, when IAA watchdog was pending.
306 */ 305 */
307 if (1) { 306 if (ehci->rh_state != EHCI_RH_RUNNING)
308 u32 cmd, status; 307 return;
309
310 /* If we get here, IAA is *REALLY* late. It's barely
311 * conceivable that the system is so busy that CMD_IAAD
312 * is still legitimately set, so let's be sure it's
313 * clear before we read STS_IAA. (The HC should clear
314 * CMD_IAAD when it sets STS_IAA.)
315 */
316 cmd = ehci_readl(ehci, &ehci->regs->command);
317
318 /*
319 * If IAA is set here it either legitimately triggered
320 * after the watchdog timer expired (_way_ late, so we'll
321 * still count it as lost) ... or a silicon erratum:
322 * - VIA seems to set IAA without triggering the IRQ;
323 * - IAAD potentially cleared without setting IAA.
324 */
325 status = ehci_readl(ehci, &ehci->regs->status);
326 if ((status & STS_IAA) || !(cmd & CMD_IAAD)) {
327 COUNT(ehci->stats.lost_iaa);
328 ehci_writel(ehci, STS_IAA, &ehci->regs->status);
329 }
330 308
331 ehci_vdbg(ehci, "IAA watchdog: status %x cmd %x\n", 309 /* If we get here, IAA is *REALLY* late. It's barely
332 status, cmd); 310 * conceivable that the system is so busy that CMD_IAAD
333 end_unlink_async(ehci); 311 * is still legitimately set, so let's be sure it's
312 * clear before we read STS_IAA. (The HC should clear
313 * CMD_IAAD when it sets STS_IAA.)
314 */
315 cmd = ehci_readl(ehci, &ehci->regs->command);
316
317 /*
318 * If IAA is set here it either legitimately triggered
319 * after the watchdog timer expired (_way_ late, so we'll
320 * still count it as lost) ... or a silicon erratum:
321 * - VIA seems to set IAA without triggering the IRQ;
322 * - IAAD potentially cleared without setting IAA.
323 */
324 status = ehci_readl(ehci, &ehci->regs->status);
325 if ((status & STS_IAA) || !(cmd & CMD_IAAD)) {
326 COUNT(ehci->stats.lost_iaa);
327 ehci_writel(ehci, STS_IAA, &ehci->regs->status);
334 } 328 }
329
330 ehci_dbg(ehci, "IAA watchdog: status %x cmd %x\n", status, cmd);
331 end_unlink_async(ehci);
335} 332}
336 333
337 334