On Monday 09 May 2005 2:22 pm, Alan Stern wrote: > > > The code still isn't quite right because the root hub doesn't > > > automatically resume. I haven't tried to track down the reason, but maybe > > > replacing the schedule_work() call with usb_hcd_resume_root_hub() would > > > help. (That replacement should be made in any case.)
I was just looking at that in conjunction with a different issue, and I noticed a glitch: it's conditionalized for USB_SUSPEND (which implies PM) not just PM, but autosuspend kicks in with PM. This patch does that conversion, and it also has the other tweak. Worked for me ... you? - Dave
This updates OHCI to use the new usbcore resume_root_hub() mechanism, and fixes that mechanism so it's available with CONFIG_PM. It also continues getting rid of some #ifdefs of the form (PM || USB_SUSPEND); they're superfluous: USB_SUSPEND is a strict superset of PM. Signed-off-by: David Brownell <[EMAIL PROTECTED]> --- g26.orig/drivers/usb/core/hcd.c 2005-05-09 18:17:30.000000000 -0700 +++ g26/drivers/usb/core/hcd.c 2005-05-09 18:18:56.000000000 -0700 @@ -1420,7 +1420,7 @@ /*-------------------------------------------------------------------------*/ -#ifdef CONFIG_USB_SUSPEND +#ifdef CONFIG_PM static int hcd_hub_suspend (struct usb_bus *bus) { @@ -1460,13 +1460,9 @@ usb_resume_root_hub (hcd->self.root_hub); spin_unlock_irqrestore (&hcd_root_hub_lock, flags); } +EXPORT_SYMBOL_GPL(usb_hcd_resume_root_hub); -#else -void usb_hcd_resume_root_hub (struct usb_hcd *hcd) -{ -} #endif -EXPORT_SYMBOL_GPL(usb_hcd_resume_root_hub); /*-------------------------------------------------------------------------*/ @@ -1519,7 +1515,7 @@ .buffer_alloc = hcd_buffer_alloc, .buffer_free = hcd_buffer_free, .disable = hcd_endpoint_disable, -#ifdef CONFIG_USB_SUSPEND +#ifdef CONFIG_PM .hub_suspend = hcd_hub_suspend, .hub_resume = hcd_hub_resume, #endif --- g26.orig/drivers/usb/host/ohci-hub.c 2005-05-09 18:17:30.000000000 -0700 +++ g26/drivers/usb/host/ohci-hub.c 2005-05-09 18:18:56.000000000 -0700 @@ -36,7 +36,7 @@ /*-------------------------------------------------------------------------*/ -#if defined(CONFIG_USB_SUSPEND) || defined(CONFIG_PM) +#ifdef CONFIG_PM #define OHCI_SCHED_ENABLES \ (OHCI_CTRL_CLE|OHCI_CTRL_BLE|OHCI_CTRL_PLE|OHCI_CTRL_IE) @@ -277,24 +277,7 @@ return 0; } -static void ohci_rh_resume (void *_hcd) -{ - struct usb_hcd *hcd = _hcd; - - usb_lock_device (hcd->self.root_hub); - (void) ohci_hub_resume (hcd); - usb_unlock_device (hcd->self.root_hub); -} - -#else - -static void ohci_rh_resume (void *_hcd) -{ - struct ohci_hcd *ohci = hcd_to_ohci (_hcd); - ohci_dbg(ohci, "rh_resume ??\n"); -} - -#endif /* CONFIG_USB_SUSPEND || CONFIG_PM */ +#endif /* CONFIG_PM */ /*-------------------------------------------------------------------------*/ @@ -553,7 +536,7 @@ temp = RH_PS_POCI; if ((ohci->hc_control & OHCI_CTRL_HCFS) != OHCI_USB_OPER) - schedule_work (&ohci->rh_resume); + usb_hcd_resume_root_hub(hcd); break; case USB_PORT_FEAT_C_SUSPEND: temp = RH_PS_PSSC; --- g26.orig/drivers/usb/host/ohci-mem.c 2005-05-09 18:18:25.000000000 -0700 +++ g26/drivers/usb/host/ohci-mem.c 2005-05-09 18:18:56.000000000 -0700 @@ -28,7 +28,6 @@ ohci->next_statechange = jiffies; spin_lock_init (&ohci->lock); INIT_LIST_HEAD (&ohci->pending); - INIT_WORK (&ohci->rh_resume, ohci_rh_resume, ohci_to_hcd(ohci)); ohci->reboot_notifier.notifier_call = ohci_reboot; } --- g26.orig/drivers/usb/host/ohci.h 2005-05-09 18:18:25.000000000 -0700 +++ g26/drivers/usb/host/ohci.h 2005-05-09 18:18:56.000000000 -0700 @@ -389,7 +389,6 @@ unsigned long next_statechange; /* suspend/resume */ u32 fminterval; /* saved register */ - struct work_struct rh_resume; struct notifier_block reboot_notifier; unsigned long flags; /* for HC bugs */ --- g26.orig/drivers/usb/host/ohci-hcd.c 2005-05-09 18:18:25.000000000 -0700 +++ g26/drivers/usb/host/ohci-hcd.c 2005-05-09 18:18:56.000000000 -0700 @@ -747,7 +747,10 @@ if (ints & OHCI_INTR_RD) { ohci_vdbg (ohci, "resume detect\n"); if (hcd->state != HC_STATE_QUIESCING) - schedule_work(&ohci->rh_resume); + usb_hcd_resume_root_hub(hcd); + /* in case root is autosuspended */ + ohci_writel (ohci, OHCI_INTR_RD, ®s->intrstatus); + ints &= ~OHCI_INTR_RD; } if (ints & OHCI_INTR_WDH) { --- g26.orig/drivers/usb/core/hub.c 2005-05-09 18:17:30.000000000 -0700 +++ g26/drivers/usb/core/hub.c 2005-05-09 18:24:35.000000000 -0700 @@ -1971,14 +1971,6 @@ return 0; } -void usb_resume_root_hub(struct usb_device *hdev) -{ - struct usb_hub *hub = hdev_to_hub(hdev); - - hub->resume_root_hub = 1; - kick_khubd(hub); -} - #else /* !CONFIG_USB_SUSPEND */ int usb_suspend_device(struct usb_device *udev, pm_message_t state) @@ -2000,6 +1992,17 @@ EXPORT_SYMBOL(usb_suspend_device); EXPORT_SYMBOL(usb_resume_device); +#ifdef CONFIG_PM + +void usb_resume_root_hub(struct usb_device *hdev) +{ + struct usb_hub *hub = hdev_to_hub(hdev); + + hub->resume_root_hub = 1; + kick_khubd(hub); +} + +#endif /* CONFIG_PM */ /* USB 2.0 spec, 7.1.7.3 / fig 7-29: