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.c129
1 files changed, 129 insertions, 0 deletions
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
index 7b5ae7111f23..500aebbaa741 100644
--- a/drivers/usb/host/ehci-sched.c
+++ b/drivers/usb/host/ehci-sched.c
@@ -473,6 +473,111 @@ static int disable_periodic (struct ehci_hcd *ehci)
473} 473}
474 474
475/*-------------------------------------------------------------------------*/ 475/*-------------------------------------------------------------------------*/
476#ifdef CONFIG_CPU_FREQ
477
478/* ignore/inactivate bit in QH hw_info1 */
479#define INACTIVATE_BIT __constant_cpu_to_le32(QH_INACTIVATE)
480
481#define HALT_BIT __constant_cpu_to_le32(QTD_STS_HALT)
482#define ACTIVE_BIT __constant_cpu_to_le32(QTD_STS_ACTIVE)
483#define STATUS_BIT __constant_cpu_to_le32(QTD_STS_STS)
484
485static int safe_to_modify_i (struct ehci_hcd *ehci, struct ehci_qh *qh)
486{
487 int now; /* current (frame * 8) + uframe */
488 int prev_start, next_start; /* uframes from/to split start */
489 int start_uframe = ffs(le32_to_cpup (&qh->hw_info2) & QH_SMASK);
490 int end_uframe = fls((le32_to_cpup (&qh->hw_info2) & QH_CMASK) >> 8);
491 int split_duration = end_uframe - start_uframe;
492
493 now = readl(&ehci->regs->frame_index) % (ehci->periodic_size << 3);
494
495 next_start = ((1024 << 3) + (qh->start << 3) + start_uframe - now) %
496 (qh->period << 3);
497 prev_start = (qh->period << 3) - next_start;
498
499 /*
500 * Make sure there will be at least one uframe when qh is safe.
501 */
502 if ((qh->period << 3) <= (ehci->i_thresh + 2 + split_duration))
503 /* never safe */
504 return -EINVAL;
505
506 /*
507 * Wait 1 uframe after transaction should have started, to make
508 * sure controller has time to write back overlay, so we can
509 * check QTD_STS_STS to see if transaction is in progress.
510 */
511 if ((next_start > ehci->i_thresh) && (prev_start > 1))
512 /* safe to set "i" bit if split isn't in progress */
513 return (qh->hw_token & STATUS_BIT) ? 0 : 1;
514 else
515 return 0;
516}
517
518/* Set inactivate bit for all the split interrupt QHs. */
519static void qh_inactivate_split_intr_qhs (struct ehci_hcd *ehci)
520{
521 struct ehci_qh *qh;
522 int not_done, safe;
523
524 do {
525 not_done = 0;
526 list_for_each_entry(qh, &ehci->split_intr_qhs,
527 split_intr_qhs) {
528 if (qh->hw_info1 & INACTIVATE_BIT)
529 /* already off */
530 continue;
531 /*
532 * To avoid setting "I" after the start split happens,
533 * don't set it if the QH might be cached in the
534 * controller. Some HCs (Broadcom/ServerWorks HT1000)
535 * will stop in the middle of a split transaction when
536 * the "I" bit is set.
537 */
538 safe = safe_to_modify_i(ehci, qh);
539 if (safe == 0) {
540 not_done = 1;
541 } else if (safe > 0) {
542 qh->was_active = qh->hw_token & ACTIVE_BIT;
543 qh->hw_info1 |= INACTIVATE_BIT;
544 }
545 }
546 } while (not_done);
547 wmb();
548}
549
550static void qh_reactivate_split_intr_qhs (struct ehci_hcd *ehci)
551{
552 struct ehci_qh *qh;
553 u32 token;
554 int not_done, safe;
555
556 do {
557 not_done = 0;
558 list_for_each_entry(qh, &ehci->split_intr_qhs, split_intr_qhs) {
559 if (!(qh->hw_info1 & INACTIVATE_BIT)) /* already on */
560 continue;
561 /*
562 * Don't reactivate if cached, or controller might
563 * overwrite overlay after we modify it!
564 */
565 safe = safe_to_modify_i(ehci, qh);
566 if (safe == 0) {
567 not_done = 1;
568 } else if (safe > 0) {
569 /* See EHCI 1.0 section 4.15.2.4. */
570 token = qh->hw_token;
571 qh->hw_token = (token | HALT_BIT) & ~ACTIVE_BIT;
572 wmb();
573 qh->hw_info1 &= ~INACTIVATE_BIT;
574 wmb();
575 qh->hw_token = (token & ~HALT_BIT) | qh->was_active;
576 }
577 }
578 } while (not_done);
579}
580#endif
476 581
477/* periodic schedule slots have iso tds (normal or split) first, then a 582/* periodic schedule slots have iso tds (normal or split) first, then a
478 * sparse tree for active interrupt transfers. 583 * sparse tree for active interrupt transfers.
@@ -490,6 +595,17 @@ static int qh_link_periodic (struct ehci_hcd *ehci, struct ehci_qh *qh)
490 period, le32_to_cpup (&qh->hw_info2) & (QH_CMASK | QH_SMASK), 595 period, le32_to_cpup (&qh->hw_info2) & (QH_CMASK | QH_SMASK),
491 qh, qh->start, qh->usecs, qh->c_usecs); 596 qh, qh->start, qh->usecs, qh->c_usecs);
492 597
598#ifdef CONFIG_CPU_FREQ
599 /*
600 * If low/full speed interrupt QHs are inactive (because of
601 * cpufreq changing processor speeds), start QH with I flag set--
602 * it will automatically be cleared when cpufreq is done.
603 */
604 if (ehci->cpufreq_changing)
605 if (!(qh->hw_info1 & (cpu_to_le32(1 << 13))))
606 qh->hw_info1 |= INACTIVATE_BIT;
607#endif
608
493 /* high bandwidth, or otherwise every microframe */ 609 /* high bandwidth, or otherwise every microframe */
494 if (period == 0) 610 if (period == 0)
495 period = 1; 611 period = 1;
@@ -538,6 +654,12 @@ static int qh_link_periodic (struct ehci_hcd *ehci, struct ehci_qh *qh)
538 ? ((qh->usecs + qh->c_usecs) / qh->period) 654 ? ((qh->usecs + qh->c_usecs) / qh->period)
539 : (qh->usecs * 8); 655 : (qh->usecs * 8);
540 656
657#ifdef CONFIG_CPU_FREQ
658 /* add qh to list of low/full speed interrupt QHs, if applicable */
659 if (!(qh->hw_info1 & (cpu_to_le32(1 << 13)))) {
660 list_add(&qh->split_intr_qhs, &ehci->split_intr_qhs);
661 }
662#endif
541 /* maybe enable periodic schedule processing */ 663 /* maybe enable periodic schedule processing */
542 if (!ehci->periodic_sched++) 664 if (!ehci->periodic_sched++)
543 return enable_periodic (ehci); 665 return enable_periodic (ehci);
@@ -557,6 +679,13 @@ static void qh_unlink_periodic (struct ehci_hcd *ehci, struct ehci_qh *qh)
557 // THEN 679 // THEN
558 // qh->hw_info1 |= __constant_cpu_to_le32 (1 << 7 /* "ignore" */); 680 // qh->hw_info1 |= __constant_cpu_to_le32 (1 << 7 /* "ignore" */);
559 681
682#ifdef CONFIG_CPU_FREQ
683 /* remove qh from list of low/full speed interrupt QHs */
684 if (!(qh->hw_info1 & (cpu_to_le32(1 << 13)))) {
685 list_del_init(&qh->split_intr_qhs);
686 }
687#endif
688
560 /* high bandwidth, or otherwise part of every microframe */ 689 /* high bandwidth, or otherwise part of every microframe */
561 if ((period = qh->period) == 0) 690 if ((period = qh->period) == 0)
562 period = 1; 691 period = 1;