|
@@ -443,11 +443,16 @@ ohci_reboot (struct notifier_block *block, unsigned long code, void *null)
|
|
|
static int ohci_init (struct ohci_hcd *ohci)
|
|
|
{
|
|
|
int ret;
|
|
|
+ struct usb_hcd *hcd = ohci_to_hcd(ohci);
|
|
|
|
|
|
disable (ohci);
|
|
|
- ohci->regs = ohci_to_hcd(ohci)->regs;
|
|
|
+ ohci->regs = hcd->regs;
|
|
|
ohci->next_statechange = jiffies;
|
|
|
|
|
|
+ /* REVISIT this BIOS handshake is now moved into PCI "quirks", and
|
|
|
+ * was never needed for most non-PCI systems ... remove the code?
|
|
|
+ */
|
|
|
+
|
|
|
#ifndef IR_DISABLE
|
|
|
/* SMM owns the HC? not for long! */
|
|
|
if (!no_handshake && ohci_readl (ohci,
|
|
@@ -478,8 +483,10 @@ static int ohci_init (struct ohci_hcd *ohci)
|
|
|
|
|
|
/* Disable HC interrupts */
|
|
|
ohci_writel (ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable);
|
|
|
- // flush the writes
|
|
|
- (void) ohci_readl (ohci, &ohci->regs->control);
|
|
|
+
|
|
|
+ /* flush the writes, and save key bits like RWC */
|
|
|
+ if (ohci_readl (ohci, &ohci->regs->control) & OHCI_CTRL_RWC)
|
|
|
+ ohci->hc_control |= OHCI_CTRL_RWC;
|
|
|
|
|
|
/* Read the number of ports unless overridden */
|
|
|
if (ohci->num_ports == 0)
|
|
@@ -488,16 +495,19 @@ static int ohci_init (struct ohci_hcd *ohci)
|
|
|
if (ohci->hcca)
|
|
|
return 0;
|
|
|
|
|
|
- ohci->hcca = dma_alloc_coherent (ohci_to_hcd(ohci)->self.controller,
|
|
|
+ ohci->hcca = dma_alloc_coherent (hcd->self.controller,
|
|
|
sizeof *ohci->hcca, &ohci->hcca_dma, 0);
|
|
|
if (!ohci->hcca)
|
|
|
return -ENOMEM;
|
|
|
|
|
|
if ((ret = ohci_mem_init (ohci)) < 0)
|
|
|
- ohci_stop (ohci_to_hcd(ohci));
|
|
|
+ ohci_stop (hcd);
|
|
|
+ else {
|
|
|
+ register_reboot_notifier (&ohci->reboot_notifier);
|
|
|
+ create_debug_files (ohci);
|
|
|
+ }
|
|
|
|
|
|
return ret;
|
|
|
-
|
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
@@ -510,6 +520,7 @@ static int ohci_run (struct ohci_hcd *ohci)
|
|
|
{
|
|
|
u32 mask, temp;
|
|
|
int first = ohci->fminterval == 0;
|
|
|
+ struct usb_hcd *hcd = ohci_to_hcd(ohci);
|
|
|
|
|
|
disable (ohci);
|
|
|
|
|
@@ -525,18 +536,17 @@ static int ohci_run (struct ohci_hcd *ohci)
|
|
|
/* also: power/overcurrent flags in roothub.a */
|
|
|
}
|
|
|
|
|
|
- /* Reset USB nearly "by the book". RemoteWakeupConnected
|
|
|
- * saved if boot firmware (BIOS/SMM/...) told us it's connected
|
|
|
- * (for OHCI integrated on mainboard, it normally is)
|
|
|
+ /* Reset USB nearly "by the book". RemoteWakeupConnected was
|
|
|
+ * saved if boot firmware (BIOS/SMM/...) told us it's connected,
|
|
|
+ * or if bus glue did the same (e.g. for PCI add-in cards with
|
|
|
+ * PCI PM support).
|
|
|
*/
|
|
|
- ohci->hc_control = ohci_readl (ohci, &ohci->regs->control);
|
|
|
ohci_dbg (ohci, "resetting from state '%s', control = 0x%x\n",
|
|
|
hcfs2string (ohci->hc_control & OHCI_CTRL_HCFS),
|
|
|
- ohci->hc_control);
|
|
|
-
|
|
|
- if (ohci->hc_control & OHCI_CTRL_RWC
|
|
|
- && !(ohci->flags & OHCI_QUIRK_AMD756))
|
|
|
- ohci_to_hcd(ohci)->can_wakeup = 1;
|
|
|
+ ohci_readl (ohci, &ohci->regs->control));
|
|
|
+ if ((ohci->hc_control & OHCI_CTRL_RWC) != 0
|
|
|
+ && !device_may_wakeup(hcd->self.controller))
|
|
|
+ device_init_wakeup(hcd->self.controller, 1);
|
|
|
|
|
|
switch (ohci->hc_control & OHCI_CTRL_HCFS) {
|
|
|
case OHCI_USB_OPER:
|
|
@@ -632,7 +642,7 @@ retry:
|
|
|
ohci->hc_control &= OHCI_CTRL_RWC;
|
|
|
ohci->hc_control |= OHCI_CONTROL_INIT | OHCI_USB_OPER;
|
|
|
ohci_writel (ohci, ohci->hc_control, &ohci->regs->control);
|
|
|
- ohci_to_hcd(ohci)->state = HC_STATE_RUNNING;
|
|
|
+ hcd->state = HC_STATE_RUNNING;
|
|
|
|
|
|
/* wake on ConnectStatusChange, matching external hubs */
|
|
|
ohci_writel (ohci, RH_HS_DRWE, &ohci->regs->roothub.status);
|
|
@@ -667,15 +677,10 @@ retry:
|
|
|
|
|
|
// POTPGT delay is bits 24-31, in 2 ms units.
|
|
|
mdelay ((temp >> 23) & 0x1fe);
|
|
|
- ohci_to_hcd(ohci)->state = HC_STATE_RUNNING;
|
|
|
+ hcd->state = HC_STATE_RUNNING;
|
|
|
|
|
|
ohci_dump (ohci, 1);
|
|
|
|
|
|
- if (ohci_to_hcd(ohci)->self.root_hub == NULL) {
|
|
|
- register_reboot_notifier (&ohci->reboot_notifier);
|
|
|
- create_debug_files (ohci);
|
|
|
- }
|
|
|
-
|
|
|
return 0;
|
|
|
}
|
|
|
|