diff options
Diffstat (limited to 'drivers/usb/host')
-rw-r--r-- | drivers/usb/host/ehci-hcd.c | 67 | ||||
-rw-r--r-- | drivers/usb/host/ehci-mem.c | 3 | ||||
-rw-r--r-- | drivers/usb/host/ehci-q.c | 4 | ||||
-rw-r--r-- | drivers/usb/host/ehci-sched.c | 129 | ||||
-rw-r--r-- | drivers/usb/host/ehci.h | 11 |
5 files changed, 214 insertions, 0 deletions
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 099aff64f536..566badb05b34 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c | |||
@@ -273,6 +273,58 @@ static void ehci_work(struct ehci_hcd *ehci); | |||
273 | 273 | ||
274 | /*-------------------------------------------------------------------------*/ | 274 | /*-------------------------------------------------------------------------*/ |
275 | 275 | ||
276 | #ifdef CONFIG_CPU_FREQ | ||
277 | |||
278 | #include <linux/cpufreq.h> | ||
279 | |||
280 | static void ehci_cpufreq_pause (struct ehci_hcd *ehci) | ||
281 | { | ||
282 | unsigned long flags; | ||
283 | |||
284 | spin_lock_irqsave(&ehci->lock, flags); | ||
285 | if (!ehci->cpufreq_changing++) | ||
286 | qh_inactivate_split_intr_qhs(ehci); | ||
287 | spin_unlock_irqrestore(&ehci->lock, flags); | ||
288 | } | ||
289 | |||
290 | static void ehci_cpufreq_unpause (struct ehci_hcd *ehci) | ||
291 | { | ||
292 | unsigned long flags; | ||
293 | |||
294 | spin_lock_irqsave(&ehci->lock, flags); | ||
295 | if (!--ehci->cpufreq_changing) | ||
296 | qh_reactivate_split_intr_qhs(ehci); | ||
297 | spin_unlock_irqrestore(&ehci->lock, flags); | ||
298 | } | ||
299 | |||
300 | /* | ||
301 | * ehci_cpufreq_notifier is needed to avoid MMF errors that occur when | ||
302 | * EHCI controllers that don't cache many uframes get delayed trying to | ||
303 | * read main memory during CPU frequency transitions. This can cause | ||
304 | * split interrupt transactions to not be completed in the required uframe. | ||
305 | * This has been observed on the Broadcom/ServerWorks HT1000 controller. | ||
306 | */ | ||
307 | static int ehci_cpufreq_notifier(struct notifier_block *nb, unsigned long val, | ||
308 | void *data) | ||
309 | { | ||
310 | struct ehci_hcd *ehci = container_of(nb, struct ehci_hcd, | ||
311 | cpufreq_transition); | ||
312 | |||
313 | switch (val) { | ||
314 | case CPUFREQ_PRECHANGE: | ||
315 | ehci_cpufreq_pause(ehci); | ||
316 | break; | ||
317 | case CPUFREQ_POSTCHANGE: | ||
318 | ehci_cpufreq_unpause(ehci); | ||
319 | break; | ||
320 | } | ||
321 | return 0; | ||
322 | } | ||
323 | |||
324 | #endif | ||
325 | |||
326 | /*-------------------------------------------------------------------------*/ | ||
327 | |||
276 | static void ehci_watchdog (unsigned long param) | 328 | static void ehci_watchdog (unsigned long param) |
277 | { | 329 | { |
278 | struct ehci_hcd *ehci = (struct ehci_hcd *) param; | 330 | struct ehci_hcd *ehci = (struct ehci_hcd *) param; |
@@ -404,6 +456,10 @@ static void ehci_stop (struct usb_hcd *hcd) | |||
404 | ehci_writel(ehci, 0, &ehci->regs->intr_enable); | 456 | ehci_writel(ehci, 0, &ehci->regs->intr_enable); |
405 | spin_unlock_irq(&ehci->lock); | 457 | spin_unlock_irq(&ehci->lock); |
406 | 458 | ||
459 | #ifdef CONFIG_CPU_FREQ | ||
460 | cpufreq_unregister_notifier(&ehci->cpufreq_transition, | ||
461 | CPUFREQ_TRANSITION_NOTIFIER); | ||
462 | #endif | ||
407 | /* let companion controllers work when we aren't */ | 463 | /* let companion controllers work when we aren't */ |
408 | ehci_writel(ehci, 0, &ehci->regs->configured_flag); | 464 | ehci_writel(ehci, 0, &ehci->regs->configured_flag); |
409 | 465 | ||
@@ -509,6 +565,17 @@ static int ehci_init(struct usb_hcd *hcd) | |||
509 | } | 565 | } |
510 | ehci->command = temp; | 566 | ehci->command = temp; |
511 | 567 | ||
568 | #ifdef CONFIG_CPU_FREQ | ||
569 | INIT_LIST_HEAD(&ehci->split_intr_qhs); | ||
570 | /* | ||
571 | * If the EHCI controller caches enough uframes, this probably | ||
572 | * isn't needed unless there are so many low/full speed devices | ||
573 | * that the controller's can't cache it all. | ||
574 | */ | ||
575 | ehci->cpufreq_transition.notifier_call = ehci_cpufreq_notifier; | ||
576 | cpufreq_register_notifier(&ehci->cpufreq_transition, | ||
577 | CPUFREQ_TRANSITION_NOTIFIER); | ||
578 | #endif | ||
512 | return 0; | 579 | return 0; |
513 | } | 580 | } |
514 | 581 | ||
diff --git a/drivers/usb/host/ehci-mem.c b/drivers/usb/host/ehci-mem.c index a8ba2e1497a4..5cff6bace5e5 100644 --- a/drivers/usb/host/ehci-mem.c +++ b/drivers/usb/host/ehci-mem.c | |||
@@ -94,6 +94,9 @@ static struct ehci_qh *ehci_qh_alloc (struct ehci_hcd *ehci, gfp_t flags) | |||
94 | qh->qh_dma = dma; | 94 | qh->qh_dma = dma; |
95 | // INIT_LIST_HEAD (&qh->qh_list); | 95 | // INIT_LIST_HEAD (&qh->qh_list); |
96 | INIT_LIST_HEAD (&qh->qtd_list); | 96 | INIT_LIST_HEAD (&qh->qtd_list); |
97 | #ifdef CONFIG_CPU_FREQ | ||
98 | INIT_LIST_HEAD (&qh->split_intr_qhs); | ||
99 | #endif | ||
97 | 100 | ||
98 | /* dummy td enables safe urb queuing */ | 101 | /* dummy td enables safe urb queuing */ |
99 | qh->dummy = ehci_qtd_alloc (ehci, flags); | 102 | qh->dummy = ehci_qtd_alloc (ehci, flags); |
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index e7fbbd00e7cd..903510beb299 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c | |||
@@ -311,6 +311,10 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
311 | struct urb *urb; | 311 | struct urb *urb; |
312 | u32 token = 0; | 312 | u32 token = 0; |
313 | 313 | ||
314 | /* ignore QHs that are currently inactive */ | ||
315 | if (qh->hw_info1 & __constant_cpu_to_le32(QH_INACTIVATE)) | ||
316 | break; | ||
317 | |||
314 | qtd = list_entry (entry, struct ehci_qtd, qtd_list); | 318 | qtd = list_entry (entry, struct ehci_qtd, qtd_list); |
315 | urb = qtd->urb; | 319 | urb = qtd->urb; |
316 | 320 | ||
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 | |||
485 | static 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. */ | ||
519 | static 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 | |||
550 | static 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; |
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 46fa57a520d0..a9ba5d28cdc2 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h | |||
@@ -55,6 +55,12 @@ struct ehci_hcd { /* one per controller */ | |||
55 | __u32 hcs_params; /* cached register copy */ | 55 | __u32 hcs_params; /* cached register copy */ |
56 | spinlock_t lock; | 56 | spinlock_t lock; |
57 | 57 | ||
58 | #ifdef CONFIG_CPU_FREQ | ||
59 | struct notifier_block cpufreq_transition; | ||
60 | int cpufreq_changing; | ||
61 | struct list_head split_intr_qhs; | ||
62 | #endif | ||
63 | |||
58 | /* async schedule support */ | 64 | /* async schedule support */ |
59 | struct ehci_qh *async; | 65 | struct ehci_qh *async; |
60 | struct ehci_qh *reclaim; | 66 | struct ehci_qh *reclaim; |
@@ -395,6 +401,7 @@ struct ehci_qh { | |||
395 | __le32 hw_next; /* see EHCI 3.6.1 */ | 401 | __le32 hw_next; /* see EHCI 3.6.1 */ |
396 | __le32 hw_info1; /* see EHCI 3.6.2 */ | 402 | __le32 hw_info1; /* see EHCI 3.6.2 */ |
397 | #define QH_HEAD 0x00008000 | 403 | #define QH_HEAD 0x00008000 |
404 | #define QH_INACTIVATE 0x00000080 | ||
398 | __le32 hw_info2; /* see EHCI 3.6.2 */ | 405 | __le32 hw_info2; /* see EHCI 3.6.2 */ |
399 | #define QH_SMASK 0x000000ff | 406 | #define QH_SMASK 0x000000ff |
400 | #define QH_CMASK 0x0000ff00 | 407 | #define QH_CMASK 0x0000ff00 |
@@ -437,6 +444,10 @@ struct ehci_qh { | |||
437 | unsigned short start; /* where polling starts */ | 444 | unsigned short start; /* where polling starts */ |
438 | #define NO_FRAME ((unsigned short)~0) /* pick new start */ | 445 | #define NO_FRAME ((unsigned short)~0) /* pick new start */ |
439 | struct usb_device *dev; /* access to TT */ | 446 | struct usb_device *dev; /* access to TT */ |
447 | #ifdef CONFIG_CPU_FREQ | ||
448 | struct list_head split_intr_qhs; /* list of split qhs */ | ||
449 | __le32 was_active; /* active bit before "i" set */ | ||
450 | #endif | ||
440 | } __attribute__ ((aligned (32))); | 451 | } __attribute__ ((aligned (32))); |
441 | 452 | ||
442 | /*-------------------------------------------------------------------------*/ | 453 | /*-------------------------------------------------------------------------*/ |