aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/ehci-sched.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/ehci-sched.c')
-rw-r--r--drivers/usb/host/ehci-sched.c22
1 files changed, 16 insertions, 6 deletions
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
index 1543c838b3d1..6c9fbe352f73 100644
--- a/drivers/usb/host/ehci-sched.c
+++ b/drivers/usb/host/ehci-sched.c
@@ -471,8 +471,10 @@ static int enable_periodic (struct ehci_hcd *ehci)
471 */ 471 */
472 status = handshake_on_error_set_halt(ehci, &ehci->regs->status, 472 status = handshake_on_error_set_halt(ehci, &ehci->regs->status,
473 STS_PSS, 0, 9 * 125); 473 STS_PSS, 0, 9 * 125);
474 if (status) 474 if (status) {
475 usb_hc_died(ehci_to_hcd(ehci));
475 return status; 476 return status;
477 }
476 478
477 cmd = ehci_readl(ehci, &ehci->regs->command) | CMD_PSE; 479 cmd = ehci_readl(ehci, &ehci->regs->command) | CMD_PSE;
478 ehci_writel(ehci, cmd, &ehci->regs->command); 480 ehci_writel(ehci, cmd, &ehci->regs->command);
@@ -510,8 +512,10 @@ static int disable_periodic (struct ehci_hcd *ehci)
510 */ 512 */
511 status = handshake_on_error_set_halt(ehci, &ehci->regs->status, 513 status = handshake_on_error_set_halt(ehci, &ehci->regs->status,
512 STS_PSS, STS_PSS, 9 * 125); 514 STS_PSS, STS_PSS, 9 * 125);
513 if (status) 515 if (status) {
516 usb_hc_died(ehci_to_hcd(ehci));
514 return status; 517 return status;
518 }
515 519
516 cmd = ehci_readl(ehci, &ehci->regs->command) & ~CMD_PSE; 520 cmd = ehci_readl(ehci, &ehci->regs->command) & ~CMD_PSE;
517 ehci_writel(ehci, cmd, &ehci->regs->command); 521 ehci_writel(ehci, cmd, &ehci->regs->command);
@@ -2287,6 +2291,7 @@ scan_periodic (struct ehci_hcd *ehci)
2287 } 2291 }
2288 clock &= mod - 1; 2292 clock &= mod - 1;
2289 clock_frame = clock >> 3; 2293 clock_frame = clock >> 3;
2294 ++ehci->periodic_stamp;
2290 2295
2291 for (;;) { 2296 for (;;) {
2292 union ehci_shadow q, *q_p; 2297 union ehci_shadow q, *q_p;
@@ -2315,10 +2320,14 @@ restart:
2315 temp.qh = qh_get (q.qh); 2320 temp.qh = qh_get (q.qh);
2316 type = Q_NEXT_TYPE(ehci, q.qh->hw->hw_next); 2321 type = Q_NEXT_TYPE(ehci, q.qh->hw->hw_next);
2317 q = q.qh->qh_next; 2322 q = q.qh->qh_next;
2318 modified = qh_completions (ehci, temp.qh); 2323 if (temp.qh->stamp != ehci->periodic_stamp) {
2319 if (unlikely(list_empty(&temp.qh->qtd_list) || 2324 modified = qh_completions(ehci, temp.qh);
2320 temp.qh->needs_rescan)) 2325 if (!modified)
2321 intr_deschedule (ehci, temp.qh); 2326 temp.qh->stamp = ehci->periodic_stamp;
2327 if (unlikely(list_empty(&temp.qh->qtd_list) ||
2328 temp.qh->needs_rescan))
2329 intr_deschedule(ehci, temp.qh);
2330 }
2322 qh_put (temp.qh); 2331 qh_put (temp.qh);
2323 break; 2332 break;
2324 case Q_TYPE_FSTN: 2333 case Q_TYPE_FSTN:
@@ -2460,6 +2469,7 @@ restart:
2460 if (ehci->clock_frame != clock_frame) { 2469 if (ehci->clock_frame != clock_frame) {
2461 free_cached_lists(ehci); 2470 free_cached_lists(ehci);
2462 ehci->clock_frame = clock_frame; 2471 ehci->clock_frame = clock_frame;
2472 ++ehci->periodic_stamp;
2463 } 2473 }
2464 } else { 2474 } else {
2465 now_uframe++; 2475 now_uframe++;