aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/pci-quirks.c
diff options
context:
space:
mode:
authorAndy Ross <andy.ross@windriver.com>2011-05-11 18:15:51 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2011-05-12 12:42:00 -0400
commit5c853013dcdadb60724268bf860d372fba71694c (patch)
tree052c771044e05670b1cf1d25714ce64ee7e3e8ee /drivers/usb/host/pci-quirks.c
parentaf5c5805013d3c97d7f0bc27a56c49baa34b1f8a (diff)
ehci: pci quirk cleanup
Factor the handoff code out from quirk_usb_disable_ehci Signed-off-by: Andy Ross <andy.ross@windriver.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/host/pci-quirks.c')
-rw-r--r--drivers/usb/host/pci-quirks.c136
1 files changed, 66 insertions, 70 deletions
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c
index 9b166d70ae91..e300509faa61 100644
--- a/drivers/usb/host/pci-quirks.c
+++ b/drivers/usb/host/pci-quirks.c
@@ -503,14 +503,70 @@ static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev)
503 iounmap(base); 503 iounmap(base);
504} 504}
505 505
506static void __devinit ehci_bios_handoff(struct pci_dev *pdev,
507 void __iomem *op_reg_base,
508 u32 cap, u8 offset)
509{
510 int msec, tried_handoff = 0;
511
512 if (cap & EHCI_USBLEGSUP_BIOS) {
513 dev_dbg(&pdev->dev, "EHCI: BIOS handoff\n");
514
515#if 0
516/* aleksey_gorelov@phoenix.com reports that some systems need SMI forced on,
517 * but that seems dubious in general (the BIOS left it off intentionally)
518 * and is known to prevent some systems from booting. so we won't do this
519 * unless maybe we can determine when we're on a system that needs SMI forced.
520 */
521 /* BIOS workaround (?): be sure the pre-Linux code
522 * receives the SMI
523 */
524 pci_read_config_dword(pdev, offset + EHCI_USBLEGCTLSTS, &val);
525 pci_write_config_dword(pdev, offset + EHCI_USBLEGCTLSTS,
526 val | EHCI_USBLEGCTLSTS_SOOE);
527#endif
528
529 /* some systems get upset if this semaphore is
530 * set for any other reason than forcing a BIOS
531 * handoff..
532 */
533 pci_write_config_byte(pdev, offset + 3, 1);
534 }
535
536 /* if boot firmware now owns EHCI, spin till it hands it over. */
537 msec = 1000;
538 while ((cap & EHCI_USBLEGSUP_BIOS) && (msec > 0)) {
539 tried_handoff = 1;
540 msleep(10);
541 msec -= 10;
542 pci_read_config_dword(pdev, offset, &cap);
543 }
544
545 if (cap & EHCI_USBLEGSUP_BIOS) {
546 /* well, possibly buggy BIOS... try to shut it down,
547 * and hope nothing goes too wrong
548 */
549 dev_warn(&pdev->dev, "EHCI: BIOS handoff failed"
550 " (BIOS bug?) %08x\n", cap);
551 pci_write_config_byte(pdev, offset + 2, 0);
552 }
553
554 /* just in case, always disable EHCI SMIs */
555 pci_write_config_dword(pdev, offset + EHCI_USBLEGCTLSTS, 0);
556
557 /* If the BIOS ever owned the controller then we can't expect
558 * any power sessions to remain intact.
559 */
560 if (tried_handoff)
561 writel(0, op_reg_base + EHCI_CONFIGFLAG);
562}
563
506static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev) 564static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev)
507{ 565{
508 int wait_time, delta;
509 void __iomem *base, *op_reg_base; 566 void __iomem *base, *op_reg_base;
510 u32 hcc_params, val; 567 u32 hcc_params, cap, val;
511 u8 offset, cap_length; 568 u8 offset, cap_length;
512 int count = 256/4; 569 int wait_time, delta, count = 256/4;
513 int tried_handoff = 0;
514 570
515 if (!mmio_resource_enabled(pdev, 0)) 571 if (!mmio_resource_enabled(pdev, 0))
516 return; 572 return;
@@ -529,77 +585,17 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev)
529 hcc_params = readl(base + EHCI_HCC_PARAMS); 585 hcc_params = readl(base + EHCI_HCC_PARAMS);
530 offset = (hcc_params >> 8) & 0xff; 586 offset = (hcc_params >> 8) & 0xff;
531 while (offset && --count) { 587 while (offset && --count) {
532 u32 cap;
533 int msec;
534
535 pci_read_config_dword(pdev, offset, &cap); 588 pci_read_config_dword(pdev, offset, &cap);
536 switch (cap & 0xff) {
537 case 1: /* BIOS/SMM/... handoff support */
538 if ((cap & EHCI_USBLEGSUP_BIOS)) {
539 dev_dbg(&pdev->dev, "EHCI: BIOS handoff\n");
540
541#if 0
542/* aleksey_gorelov@phoenix.com reports that some systems need SMI forced on,
543 * but that seems dubious in general (the BIOS left it off intentionally)
544 * and is known to prevent some systems from booting. so we won't do this
545 * unless maybe we can determine when we're on a system that needs SMI forced.
546 */
547 /* BIOS workaround (?): be sure the
548 * pre-Linux code receives the SMI
549 */
550 pci_read_config_dword(pdev,
551 offset + EHCI_USBLEGCTLSTS,
552 &val);
553 pci_write_config_dword(pdev,
554 offset + EHCI_USBLEGCTLSTS,
555 val | EHCI_USBLEGCTLSTS_SOOE);
556#endif
557
558 /* some systems get upset if this semaphore is
559 * set for any other reason than forcing a BIOS
560 * handoff..
561 */
562 pci_write_config_byte(pdev, offset + 3, 1);
563 }
564
565 /* if boot firmware now owns EHCI, spin till
566 * it hands it over.
567 */
568 msec = 1000;
569 while ((cap & EHCI_USBLEGSUP_BIOS) && (msec > 0)) {
570 tried_handoff = 1;
571 msleep(10);
572 msec -= 10;
573 pci_read_config_dword(pdev, offset, &cap);
574 }
575 589
576 if (cap & EHCI_USBLEGSUP_BIOS) { 590 switch (cap & 0xff) {
577 /* well, possibly buggy BIOS... try to shut 591 case 1:
578 * it down, and hope nothing goes too wrong 592 ehci_bios_handoff(pdev, op_reg_base, cap, offset);
579 */
580 dev_warn(&pdev->dev, "EHCI: BIOS handoff failed"
581 " (BIOS bug?) %08x\n", cap);
582 pci_write_config_byte(pdev, offset + 2, 0);
583 }
584
585 /* just in case, always disable EHCI SMIs */
586 pci_write_config_dword(pdev,
587 offset + EHCI_USBLEGCTLSTS,
588 0);
589
590 /* If the BIOS ever owned the controller then we
591 * can't expect any power sessions to remain intact.
592 */
593 if (tried_handoff)
594 writel(0, op_reg_base + EHCI_CONFIGFLAG);
595 break; 593 break;
596 case 0: /* illegal reserved capability */ 594 case 0: /* Illegal reserved cap, set cap=0 so we exit */
597 cap = 0; 595 cap = 0; /* then fallthrough... */
598 /* FALLTHROUGH */
599 default: 596 default:
600 dev_warn(&pdev->dev, "EHCI: unrecognized capability " 597 dev_warn(&pdev->dev, "EHCI: unrecognized capability "
601 "%02x\n", cap & 0xff); 598 "%02x\n", cap & 0xff);
602 break;
603 } 599 }
604 offset = (cap >> 8) & 0xff; 600 offset = (cap >> 8) & 0xff;
605 } 601 }