diff options
Diffstat (limited to 'drivers/usb/host')
-rw-r--r-- | drivers/usb/host/ohci-hcd.c | 49 | ||||
-rw-r--r-- | drivers/usb/host/ohci-hub.c | 12 | ||||
-rw-r--r-- | drivers/usb/host/ohci-pci.c | 15 |
3 files changed, 46 insertions, 30 deletions
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 2990be269000..544f7589912f 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c | |||
@@ -443,11 +443,16 @@ ohci_reboot (struct notifier_block *block, unsigned long code, void *null) | |||
443 | static int ohci_init (struct ohci_hcd *ohci) | 443 | static int ohci_init (struct ohci_hcd *ohci) |
444 | { | 444 | { |
445 | int ret; | 445 | int ret; |
446 | struct usb_hcd *hcd = ohci_to_hcd(ohci); | ||
446 | 447 | ||
447 | disable (ohci); | 448 | disable (ohci); |
448 | ohci->regs = ohci_to_hcd(ohci)->regs; | 449 | ohci->regs = hcd->regs; |
449 | ohci->next_statechange = jiffies; | 450 | ohci->next_statechange = jiffies; |
450 | 451 | ||
452 | /* REVISIT this BIOS handshake is now moved into PCI "quirks", and | ||
453 | * was never needed for most non-PCI systems ... remove the code? | ||
454 | */ | ||
455 | |||
451 | #ifndef IR_DISABLE | 456 | #ifndef IR_DISABLE |
452 | /* SMM owns the HC? not for long! */ | 457 | /* SMM owns the HC? not for long! */ |
453 | if (!no_handshake && ohci_readl (ohci, | 458 | if (!no_handshake && ohci_readl (ohci, |
@@ -478,8 +483,10 @@ static int ohci_init (struct ohci_hcd *ohci) | |||
478 | 483 | ||
479 | /* Disable HC interrupts */ | 484 | /* Disable HC interrupts */ |
480 | ohci_writel (ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable); | 485 | ohci_writel (ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable); |
481 | // flush the writes | 486 | |
482 | (void) ohci_readl (ohci, &ohci->regs->control); | 487 | /* flush the writes, and save key bits like RWC */ |
488 | if (ohci_readl (ohci, &ohci->regs->control) & OHCI_CTRL_RWC) | ||
489 | ohci->hc_control |= OHCI_CTRL_RWC; | ||
483 | 490 | ||
484 | /* Read the number of ports unless overridden */ | 491 | /* Read the number of ports unless overridden */ |
485 | if (ohci->num_ports == 0) | 492 | if (ohci->num_ports == 0) |
@@ -488,16 +495,19 @@ static int ohci_init (struct ohci_hcd *ohci) | |||
488 | if (ohci->hcca) | 495 | if (ohci->hcca) |
489 | return 0; | 496 | return 0; |
490 | 497 | ||
491 | ohci->hcca = dma_alloc_coherent (ohci_to_hcd(ohci)->self.controller, | 498 | ohci->hcca = dma_alloc_coherent (hcd->self.controller, |
492 | sizeof *ohci->hcca, &ohci->hcca_dma, 0); | 499 | sizeof *ohci->hcca, &ohci->hcca_dma, 0); |
493 | if (!ohci->hcca) | 500 | if (!ohci->hcca) |
494 | return -ENOMEM; | 501 | return -ENOMEM; |
495 | 502 | ||
496 | if ((ret = ohci_mem_init (ohci)) < 0) | 503 | if ((ret = ohci_mem_init (ohci)) < 0) |
497 | ohci_stop (ohci_to_hcd(ohci)); | 504 | ohci_stop (hcd); |
505 | else { | ||
506 | register_reboot_notifier (&ohci->reboot_notifier); | ||
507 | create_debug_files (ohci); | ||
508 | } | ||
498 | 509 | ||
499 | return ret; | 510 | return ret; |
500 | |||
501 | } | 511 | } |
502 | 512 | ||
503 | /*-------------------------------------------------------------------------*/ | 513 | /*-------------------------------------------------------------------------*/ |
@@ -510,6 +520,7 @@ static int ohci_run (struct ohci_hcd *ohci) | |||
510 | { | 520 | { |
511 | u32 mask, temp; | 521 | u32 mask, temp; |
512 | int first = ohci->fminterval == 0; | 522 | int first = ohci->fminterval == 0; |
523 | struct usb_hcd *hcd = ohci_to_hcd(ohci); | ||
513 | 524 | ||
514 | disable (ohci); | 525 | disable (ohci); |
515 | 526 | ||
@@ -525,18 +536,17 @@ static int ohci_run (struct ohci_hcd *ohci) | |||
525 | /* also: power/overcurrent flags in roothub.a */ | 536 | /* also: power/overcurrent flags in roothub.a */ |
526 | } | 537 | } |
527 | 538 | ||
528 | /* Reset USB nearly "by the book". RemoteWakeupConnected | 539 | /* Reset USB nearly "by the book". RemoteWakeupConnected was |
529 | * saved if boot firmware (BIOS/SMM/...) told us it's connected | 540 | * saved if boot firmware (BIOS/SMM/...) told us it's connected, |
530 | * (for OHCI integrated on mainboard, it normally is) | 541 | * or if bus glue did the same (e.g. for PCI add-in cards with |
542 | * PCI PM support). | ||
531 | */ | 543 | */ |
532 | ohci->hc_control = ohci_readl (ohci, &ohci->regs->control); | ||
533 | ohci_dbg (ohci, "resetting from state '%s', control = 0x%x\n", | 544 | ohci_dbg (ohci, "resetting from state '%s', control = 0x%x\n", |
534 | hcfs2string (ohci->hc_control & OHCI_CTRL_HCFS), | 545 | hcfs2string (ohci->hc_control & OHCI_CTRL_HCFS), |
535 | ohci->hc_control); | 546 | ohci_readl (ohci, &ohci->regs->control)); |
536 | 547 | if ((ohci->hc_control & OHCI_CTRL_RWC) != 0 | |
537 | if (ohci->hc_control & OHCI_CTRL_RWC | 548 | && !device_may_wakeup(hcd->self.controller)) |
538 | && !(ohci->flags & OHCI_QUIRK_AMD756)) | 549 | device_init_wakeup(hcd->self.controller, 1); |
539 | ohci_to_hcd(ohci)->can_wakeup = 1; | ||
540 | 550 | ||
541 | switch (ohci->hc_control & OHCI_CTRL_HCFS) { | 551 | switch (ohci->hc_control & OHCI_CTRL_HCFS) { |
542 | case OHCI_USB_OPER: | 552 | case OHCI_USB_OPER: |
@@ -632,7 +642,7 @@ retry: | |||
632 | ohci->hc_control &= OHCI_CTRL_RWC; | 642 | ohci->hc_control &= OHCI_CTRL_RWC; |
633 | ohci->hc_control |= OHCI_CONTROL_INIT | OHCI_USB_OPER; | 643 | ohci->hc_control |= OHCI_CONTROL_INIT | OHCI_USB_OPER; |
634 | ohci_writel (ohci, ohci->hc_control, &ohci->regs->control); | 644 | ohci_writel (ohci, ohci->hc_control, &ohci->regs->control); |
635 | ohci_to_hcd(ohci)->state = HC_STATE_RUNNING; | 645 | hcd->state = HC_STATE_RUNNING; |
636 | 646 | ||
637 | /* wake on ConnectStatusChange, matching external hubs */ | 647 | /* wake on ConnectStatusChange, matching external hubs */ |
638 | ohci_writel (ohci, RH_HS_DRWE, &ohci->regs->roothub.status); | 648 | ohci_writel (ohci, RH_HS_DRWE, &ohci->regs->roothub.status); |
@@ -667,15 +677,10 @@ retry: | |||
667 | 677 | ||
668 | // POTPGT delay is bits 24-31, in 2 ms units. | 678 | // POTPGT delay is bits 24-31, in 2 ms units. |
669 | mdelay ((temp >> 23) & 0x1fe); | 679 | mdelay ((temp >> 23) & 0x1fe); |
670 | ohci_to_hcd(ohci)->state = HC_STATE_RUNNING; | 680 | hcd->state = HC_STATE_RUNNING; |
671 | 681 | ||
672 | ohci_dump (ohci, 1); | 682 | ohci_dump (ohci, 1); |
673 | 683 | ||
674 | if (ohci_to_hcd(ohci)->self.root_hub == NULL) { | ||
675 | register_reboot_notifier (&ohci->reboot_notifier); | ||
676 | create_debug_files (ohci); | ||
677 | } | ||
678 | |||
679 | return 0; | 684 | return 0; |
680 | } | 685 | } |
681 | 686 | ||
diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c index 4b2226d77b34..0bb972b58336 100644 --- a/drivers/usb/host/ohci-hub.c +++ b/drivers/usb/host/ohci-hub.c | |||
@@ -107,7 +107,7 @@ static int ohci_bus_suspend (struct usb_hcd *hcd) | |||
107 | &ohci->regs->intrstatus); | 107 | &ohci->regs->intrstatus); |
108 | 108 | ||
109 | /* maybe resume can wake root hub */ | 109 | /* maybe resume can wake root hub */ |
110 | if (hcd->remote_wakeup) | 110 | if (device_may_wakeup(&ohci_to_hcd(ohci)->self.root_hub->dev)) |
111 | ohci->hc_control |= OHCI_CTRL_RWE; | 111 | ohci->hc_control |= OHCI_CTRL_RWE; |
112 | else | 112 | else |
113 | ohci->hc_control &= ~OHCI_CTRL_RWE; | 113 | ohci->hc_control &= ~OHCI_CTRL_RWE; |
@@ -246,9 +246,9 @@ static int ohci_bus_resume (struct usb_hcd *hcd) | |||
246 | (void) ohci_readl (ohci, &ohci->regs->control); | 246 | (void) ohci_readl (ohci, &ohci->regs->control); |
247 | msleep (3); | 247 | msleep (3); |
248 | 248 | ||
249 | temp = OHCI_CONTROL_INIT | OHCI_USB_OPER; | 249 | temp = ohci->hc_control; |
250 | if (hcd->can_wakeup) | 250 | temp &= OHCI_CTRL_RWC; |
251 | temp |= OHCI_CTRL_RWC; | 251 | temp |= OHCI_CONTROL_INIT | OHCI_USB_OPER; |
252 | ohci->hc_control = temp; | 252 | ohci->hc_control = temp; |
253 | ohci_writel (ohci, temp, &ohci->regs->control); | 253 | ohci_writel (ohci, temp, &ohci->regs->control); |
254 | (void) ohci_readl (ohci, &ohci->regs->control); | 254 | (void) ohci_readl (ohci, &ohci->regs->control); |
@@ -302,7 +302,7 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf) | |||
302 | { | 302 | { |
303 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | 303 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); |
304 | int i, changed = 0, length = 1; | 304 | int i, changed = 0, length = 1; |
305 | int can_suspend = hcd->can_wakeup; | 305 | int can_suspend = device_may_wakeup(&hcd->self.root_hub->dev); |
306 | unsigned long flags; | 306 | unsigned long flags; |
307 | 307 | ||
308 | spin_lock_irqsave (&ohci->lock, flags); | 308 | spin_lock_irqsave (&ohci->lock, flags); |
@@ -354,7 +354,7 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf) | |||
354 | */ | 354 | */ |
355 | if (!(status & RH_PS_CCS)) | 355 | if (!(status & RH_PS_CCS)) |
356 | continue; | 356 | continue; |
357 | if ((status & RH_PS_PSS) && hcd->remote_wakeup) | 357 | if ((status & RH_PS_PSS) && can_suspend) |
358 | continue; | 358 | continue; |
359 | can_suspend = 0; | 359 | can_suspend = 0; |
360 | } | 360 | } |
diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c index 1b09dde068e1..1bfe96f4d045 100644 --- a/drivers/usb/host/ohci-pci.c +++ b/drivers/usb/host/ohci-pci.c | |||
@@ -35,7 +35,10 @@ ohci_pci_start (struct usb_hcd *hcd) | |||
35 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | 35 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); |
36 | int ret; | 36 | int ret; |
37 | 37 | ||
38 | if(hcd->self.controller && hcd->self.controller->bus == &pci_bus_type) { | 38 | /* REVISIT this whole block should move to reset(), which handles |
39 | * all the other one-time init. | ||
40 | */ | ||
41 | if (hcd->self.controller) { | ||
39 | struct pci_dev *pdev = to_pci_dev(hcd->self.controller); | 42 | struct pci_dev *pdev = to_pci_dev(hcd->self.controller); |
40 | 43 | ||
41 | /* AMD 756, for most chips (early revs), corrupts register | 44 | /* AMD 756, for most chips (early revs), corrupts register |
@@ -45,7 +48,8 @@ ohci_pci_start (struct usb_hcd *hcd) | |||
45 | && pdev->device == 0x740c) { | 48 | && pdev->device == 0x740c) { |
46 | ohci->flags = OHCI_QUIRK_AMD756; | 49 | ohci->flags = OHCI_QUIRK_AMD756; |
47 | ohci_dbg (ohci, "AMD756 erratum 4 workaround\n"); | 50 | ohci_dbg (ohci, "AMD756 erratum 4 workaround\n"); |
48 | // also somewhat erratum 10 (suspend/resume issues) | 51 | /* also erratum 10 (suspend/resume issues) */ |
52 | device_init_wakeup(&hcd->self.root_hub->dev, 0); | ||
49 | } | 53 | } |
50 | 54 | ||
51 | /* FIXME for some of the early AMD 760 southbridges, OHCI | 55 | /* FIXME for some of the early AMD 760 southbridges, OHCI |
@@ -88,6 +92,13 @@ ohci_pci_start (struct usb_hcd *hcd) | |||
88 | ohci_dbg (ohci, | 92 | ohci_dbg (ohci, |
89 | "enabled Compaq ZFMicro chipset quirk\n"); | 93 | "enabled Compaq ZFMicro chipset quirk\n"); |
90 | } | 94 | } |
95 | |||
96 | /* RWC may not be set for add-in PCI cards, since boot | ||
97 | * firmware probably ignored them. This transfers PCI | ||
98 | * PM wakeup capabilities (once the PCI layer is fixed). | ||
99 | */ | ||
100 | if (device_may_wakeup(&pdev->dev)) | ||
101 | ohci->hc_control |= OHCI_CTRL_RWC; | ||
91 | } | 102 | } |
92 | 103 | ||
93 | /* NOTE: there may have already been a first reset, to | 104 | /* NOTE: there may have already been a first reset, to |