On Thu, Jun 09, 2005 at 09:14:52PM -0700, David Brownell wrote: > On Thursday 09 June 2005 8:39 pm, Todd Poynor wrote: ... > > So far as I thought I knew, pm_message_t will eventually become a struct > > with fields that can be used to properly describe what sort of driver > > behavior is needed at suspend and resume... > > That's one theory; I can't see it checking out though...
OK, I know a cell phone vendor or two that want more info on system suspend/resume behaviors available to drivers, so I'll pitch in to try to turn this parameter into something useful. > It was only swsusp that forced "3"; the other 2.6 code, now deleted, > was doing PM_SUSPEND_MEM (3) or PM_SUSPEND_DISK (4). Ah I see, I meant that both "standby" and "mem" suspends (which we can map to two different sleep modes on the PXA27x that have different power cycling behavior for I/O devices) both suspend devices to state 3, was forgetting about the suspend-to-disk option. > This patch reads fine to me except that you're not setting the > dev->power.power_state to (bleech) PMSG_SUSPEND or PMSG_ON, > which means that operations through sysfs power/state files will > be more borked than usual ... not all paths through the driver > core will maintain that field, so drivers need to. At least, > so long as the field exists. It's mostly just trouble. :) Ugh, at one point in the not-too-distant past both system suspend/resume and individual device "runtime" suspend/resume managed that field on behalf of drivers, but I see system suspend/resume no longer does so. Here's a new patch that assigns a "message" to the "state" field (may this simply be a passing phase). Thanks -- Todd Power Management for the Intel XScale PXA27x OHCI USB host controller Signed-off-by: Todd Poynor <[EMAIL PROTECTED]> Index: linux-2.6.12-rc4/drivers/usb/host/ohci-pxa27x.c =================================================================== --- linux-2.6.12-rc4.orig/drivers/usb/host/ohci-pxa27x.c 2005-06-09 02:56:43.000000000 +0000 +++ linux-2.6.12-rc4/drivers/usb/host/ohci-pxa27x.c 2005-06-10 20:27:04.000000000 +0000 @@ -310,6 +310,7 @@ .hub_suspend = ohci_hub_suspend, .hub_resume = ohci_hub_resume, #endif + .start_port_reset = ohci_start_port_reset, }; /*-------------------------------------------------------------------------*/ @@ -337,32 +338,69 @@ return 0; } -static int ohci_hcd_pxa27x_drv_suspend(struct device *dev, pm_message_t state, u32 level) + +#ifdef CONFIG_PM + +static int ohci_hcd_pxa27x_drv_suspend(struct device *dev, pm_message_t message, u32 level) { -// struct platform_device *pdev = to_platform_device(dev); -// struct usb_hcd *hcd = dev_get_drvdata(dev); - printk("%s: not implemented yet\n", __FUNCTION__); + struct platform_device *pdev = to_platform_device(dev); + struct ohci_hcd *ohci = hcd_to_ohci(dev_get_drvdata(dev)); + int status = -EINVAL; - return 0; + if (level != SUSPEND_POWER_DOWN) + return 0; + + down(&ohci_to_hcd(ohci)->self.root_hub->serialize); + status = ohci_hub_suspend(ohci_to_hcd(ohci)); + if (status == 0) { + pxa27x_stop_hc(pdev); + ohci_to_hcd(ohci)->self.root_hub->state = + USB_STATE_SUSPENDED; + ohci_to_hcd(ohci)->state = HC_STATE_SUSPENDED; + dev->power.power_state = PMSG_SUSPEND; + } + up(&ohci_to_hcd(ohci)->self.root_hub->serialize); + return status; } static int ohci_hcd_pxa27x_drv_resume(struct device *dev, u32 level) { -// struct platform_device *pdev = to_platform_device(dev); -// struct usb_hcd *hcd = dev_get_drvdata(dev); - printk("%s: not implemented yet\n", __FUNCTION__); + struct platform_device *pdev = to_platform_device(dev); + struct ohci_hcd *ohci = hcd_to_ohci(dev_get_drvdata(dev)); + int status = 0; - return 0; + if (level != RESUME_POWER_ON) + return 0; + + if (time_before(jiffies, ohci->next_statechange)) + msleep(5); + ohci->next_statechange = jiffies; + pxa27x_start_hc(pdev); +#ifdef CONFIG_USB_SUSPEND + /* get extra cleanup even if remote wakeup isn't in use */ + status = usb_resume_device(ohci_to_hcd(ohci)->self.root_hub); +#else + down(&ohci_to_hcd(ohci)->self.root_hub->serialize); + status = ohci_hub_resume(ohci_to_hcd(ohci)); + up(&ohci_to_hcd(ohci)->self.root_hub->serialize); +#endif + if (status == 0) + dev->power.power_state = PMSG_ON; + + return status; } +#endif static struct device_driver ohci_hcd_pxa27x_driver = { .name = "pxa27x-ohci", .bus = &platform_bus_type, .probe = ohci_hcd_pxa27x_drv_probe, .remove = ohci_hcd_pxa27x_drv_remove, +#ifdef CONFIG_PM .suspend = ohci_hcd_pxa27x_drv_suspend, - .resume = ohci_hcd_pxa27x_drv_resume, + .resume = ohci_hcd_pxa27x_drv_resume, +#endif }; static int __init ohci_hcd_pxa27x_init (void) ------------------------------------------------------- This SF.Net email is sponsored by: NEC IT Guy Games. How far can you shotput a projector? How fast can you ride your desk chair down the office luge track? If you want to score the big prize, get to know the little guy. Play to win an NEC 61" plasma display: http://www.necitguy.com/?r=20 _______________________________________________ linux-usb-devel@lists.sourceforge.net To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel