aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host')
-rw-r--r--drivers/usb/host/ohci-hcd.c49
-rw-r--r--drivers/usb/host/ohci-hub.c12
-rw-r--r--drivers/usb/host/ohci-pci.c15
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)
443static int ohci_init (struct ohci_hcd *ohci) 443static 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