示例#1
0
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;
}