Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 36375
b: refs/heads/master
c: 1cc8a25
h: refs/heads/master
i:
  36373: 9245354
  36371: 0344a40
  36367: 12a71e9
v: v3
  • Loading branch information
Alan Stern authored and Greg Kroah-Hartman committed Sep 27, 2006
1 parent 3cb56c3 commit 7e0f4c3
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 46 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 782da727b0d59e93c84a627948b1535a3db90392
refs/heads/master: 1cc8a25d5b680ff656927ffa9b66fae6b415b1d3
122 changes: 77 additions & 45 deletions trunk/drivers/usb/core/driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -751,81 +751,89 @@ EXPORT_SYMBOL_GPL_FUTURE(usb_deregister);

#ifdef CONFIG_PM

static int usb_suspend(struct device *dev, pm_message_t message)
/* Caller has locked udev */
static int suspend_device(struct usb_device *udev, pm_message_t msg)
{
struct usb_device *udev;
struct usb_device_driver *udriver;
struct usb_interface *intf;
struct usb_driver *driver;
int status;

if (is_usb_device(dev)) {
if (dev->driver == NULL)
return 0;
udev = to_usb_device(dev);
udriver = to_usb_device_driver(dev->driver);
if (dev->power.power_state.event == message.event)
return 0;
return udriver->suspend(udev, message);
}
if (udev->dev.driver == NULL)
return 0;
udriver = to_usb_device_driver(udev->dev.driver);
if (udev->dev.power.power_state.event == msg.event)
return 0;
return udriver->suspend(udev, msg);
}

/* Caller has locked udev */
static int resume_device(struct usb_device *udev)
{
struct usb_device_driver *udriver;

if (dev->driver == NULL)
if (udev->dev.power.power_state.event == PM_EVENT_ON)
return 0;

intf = to_usb_interface(dev);
driver = to_usb_driver(dev->driver);
/* mark things as "on" immediately, no matter what errors crop up */
udev->dev.power.power_state.event = PM_EVENT_ON;

if (udev->dev.driver == NULL)
return 0;
udriver = to_usb_device_driver(udev->dev.driver);
if (udev->state == USB_STATE_NOTATTACHED)
return 0;
return udriver->resume(udev);
}

/* Caller has locked intf */
static int suspend_interface(struct usb_interface *intf, pm_message_t msg)
{
struct usb_driver *driver;
int status;

if (intf->dev.driver == NULL)
return 0;

driver = to_usb_driver(intf->dev.driver);

/* with no hardware, USB interfaces only use FREEZE and ON states */
if (!is_active(intf))
return 0;

if (driver->suspend && driver->resume) {
status = driver->suspend(intf, message);
status = driver->suspend(intf, msg);
if (status)
dev_err(dev, "%s error %d\n", "suspend", status);
dev_err(&intf->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);
dev_warn(&intf->dev, "no suspend for driver %s?\n",
driver->name);
mark_quiesced(intf);
status = 0;
}
return status;
}

static int usb_resume(struct device *dev)
/* Caller has locked intf */
static int resume_interface(struct usb_interface *intf)
{
struct usb_device *udev;
struct usb_device_driver *udriver;
struct usb_interface *intf;
struct usb_driver *driver;
int status;
struct usb_driver *driver;
struct usb_device *udev;
int status;

if (dev->power.power_state.event == PM_EVENT_ON)
if (intf->dev.power.power_state.event == PM_EVENT_ON)
return 0;

/* mark things as "on" immediately, no matter what errors crop up */
dev->power.power_state.event = PM_EVENT_ON;
intf->dev.power.power_state.event = PM_EVENT_ON;

/* devices resume through their hubs */
if (is_usb_device(dev)) {
if (dev->driver == NULL)
return 0;
udev = to_usb_device(dev);
udriver = to_usb_device_driver(dev->driver);
if (udev->state == USB_STATE_NOTATTACHED)
return 0;
return udriver->resume(udev);
}

if (dev->driver == NULL) {
dev->power.power_state.event = PM_EVENT_FREEZE;
if (intf->dev.driver == NULL) {
intf->dev.power.power_state.event = PM_EVENT_FREEZE;
return 0;
}

intf = to_usb_interface(dev);
driver = to_usb_driver(dev->driver);
driver = to_usb_driver(intf->dev.driver);

udev = interface_to_usbdev(intf);
if (udev->state == USB_STATE_NOTATTACHED)
Expand All @@ -838,14 +846,38 @@ static int usb_resume(struct device *dev)
if (driver->resume) {
status = driver->resume(intf);
if (status) {
dev_err(dev, "%s error %d\n", "resume", status);
dev_err(&intf->dev, "%s error %d\n",
"resume", status);
mark_quiesced(intf);
}
} else
dev_warn(dev, "no resume for driver %s?\n", driver->name);
dev_warn(&intf->dev, "no resume for driver %s?\n",
driver->name);
return 0;
}

static int usb_suspend(struct device *dev, pm_message_t message)
{
int status;

if (is_usb_device(dev))
status = suspend_device(to_usb_device(dev), message);
else
status = suspend_interface(to_usb_interface(dev), message);
return status;
}

static int usb_resume(struct device *dev)
{
int status;

if (is_usb_device(dev))
status = resume_device(to_usb_device(dev));
else
status = resume_interface(to_usb_interface(dev));
return status;
}

#endif /* CONFIG_PM */

struct bus_type usb_bus_type = {
Expand Down

0 comments on commit 7e0f4c3

Please sign in to comment.