static int ohci_rbus_suspend (struct usb_hcd *hcd, pm_message_t message) { struct ohci_hcd *ohci = hcd_to_ohci (hcd); /* suspend root hub, hoping it keeps power during suspend */ if (time_before (jiffies, ohci->next_statechange)) msleep (100); #ifdef CONFIG_USB_SUSPEND (void) usb_suspend_device (hcd->self.root_hub, message); #else usb_lock_device (hcd->self.root_hub); (void) ohci_hub_suspend (hcd); usb_unlock_device (hcd->self.root_hub); #endif /* let things settle down a bit */ msleep (100); #ifdef CONFIG_PMAC_PBOOK if (_machine == _MACH_Pmac) { struct device_node *of_node; /* Disable USB PAD & cell clock */ of_node = pci_device_to_OF_node (to_pci_dev(hcd->self.controller)); if (of_node) pmac_call_feature(PMAC_FTR_USB_ENABLE, of_node, 0, 0); } #endif /* CONFIG_PMAC_PBOOK */ return 0; }
static int usb_generic_suspend(struct device *dev, pm_message_t message) { struct usb_interface *intf; struct usb_driver *driver; int status; /* USB devices enter SUSPEND state through their hubs, but can be * marked for FREEZE as soon as their children are already idled. * But those semantics are useless, so we equate the two (sigh). */ /*挂起usb设备*/ if (dev->driver == &usb_generic_driver) { if (dev->power.power_state.event == message.event) return 0; /* we need to rule out bogus requests through sysfs */ status = device_for_each_child(dev, NULL, verify_suspended); if (status) return status; /*挂起设备的操作*/ return usb_suspend_device (to_usb_device(dev)); } if ((dev->driver == NULL) || (dev->driver_data == &usb_generic_driver_data)) return 0; intf = to_usb_interface(dev); driver = to_usb_driver(dev->driver); /* with no hardware, USB interfaces only use FREEZE and ON states */ if (!is_active(intf)) return 0; //挂起usb设备接口驱动 if (driver->suspend && driver->resume) { status = driver->suspend(intf, message); if (status) dev_err(dev, "%s error %d\n", "suspend", status); else mark_quiesced(intf); } else { // FIXME else if there's no suspend method, disconnect... dev_warn(dev, "no suspend for driver %s?\n", driver->name); mark_quiesced(intf); status = 0; } return status; }