Skip to content

Commit

Permalink
[PATCH] remove usb_suspend_device() parameter
Browse files Browse the repository at this point in the history
This patch removes the extra usb_suspend_device() parameter.  The original
reason to pass that parameter was so that this routine could suspend any
active children.  A previous patch removed that functionality ... leaving
no reason to pass the parameter.  A close analogy is pci_set_power_state,
which doesn't need a pm_message_t either.

On the internal code path that comes through the driver model, the parameter
is now used to distinguish cases where USB devices need to "freeze" but not
suspend.   It also checks for an error case that's accessible through sysfs:
attempting to suspend a device before its interfaces (or for hubs, ports).

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

 drivers/usb/core/hub.c         |   34 +++++++++++++++++++++-------------
 drivers/usb/core/usb.c         |   23 +++++++++++++++++++++--
 drivers/usb/host/ehci-hcd.c    |    2 +-
 drivers/usb/host/isp116x-hcd.c |    2 +-
 drivers/usb/host/ohci-pci.c    |    2 +-
 include/linux/usb.h            |    2 +-
 6 files changed, 46 insertions(+), 19 deletions(-)
  • Loading branch information
David Brownell authored and Greg Kroah-Hartman committed Oct 28, 2005
1 parent c9f89fa commit 390a8c3
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 19 deletions.
34 changes: 21 additions & 13 deletions drivers/usb/core/hub.c
Original file line number Diff line number Diff line change
Expand Up @@ -1323,11 +1323,9 @@ int usb_new_device(struct usb_device *udev)
* (Includes HNP test device.)
*/
if (udev->bus->b_hnp_enable || udev->bus->is_b_host) {
static int __usb_suspend_device (struct usb_device *,
int port1, pm_message_t state);
err = __usb_suspend_device(udev,
udev->bus->otg_port,
PMSG_SUSPEND);
static int __usb_suspend_device(struct usb_device *,
int port1);
err = __usb_suspend_device(udev, udev->bus->otg_port);
if (err < 0)
dev_dbg(&udev->dev, "HNP fail, %d\n", err);
}
Expand Down Expand Up @@ -1517,7 +1515,7 @@ static void hub_port_logical_disconnect(struct usb_hub *hub, int port1)
/* FIXME let caller ask to power down the port:
* - some devices won't enumerate without a VBUS power cycle
* - SRP saves power that way
* - usb_suspend_device(dev, PMSG_SUSPEND)
* - ... new call, TBD ...
* That's easy if this hub can switch power per-port, and
* khubd reactivates the port later (timer, SRP, etc).
* Powerdown must be optional, because of reset/DFU.
Expand Down Expand Up @@ -1599,9 +1597,12 @@ static int hub_port_suspend(struct usb_hub *hub, int port1,
* Other than re-initializing the hub (plug/unplug, except for root hubs),
* Linux (2.6) currently has NO mechanisms to initiate that: no khubd
* timer, no SRP, no requests through sysfs.
*
* If CONFIG_USB_SUSPEND isn't enabled, devices only really suspend when
* the root hub for their bus goes into global suspend ... so we don't
* (falsely) update the device power state to say it suspended.
*/
static int __usb_suspend_device (struct usb_device *udev, int port1,
pm_message_t state)
static int __usb_suspend_device (struct usb_device *udev, int port1)
{
int status;

Expand Down Expand Up @@ -1648,14 +1649,13 @@ static int __usb_suspend_device (struct usb_device *udev, int port1,
udev);

if (status == 0)
udev->dev.power.power_state = state;
udev->dev.power.power_state = PMSG_SUSPEND;
return status;
}

/**
* usb_suspend_device - suspend a usb device
* @udev: device that's no longer in active use
* @state: PMSG_SUSPEND to suspend
* Context: must be able to sleep; device not locked
*
* Suspends a USB device that isn't in active use, conserving power.
Expand All @@ -1664,26 +1664,32 @@ static int __usb_suspend_device (struct usb_device *udev, int port1,
* suspend by the host, using usb_resume_device(). It's also routine
* to disconnect devices while they are suspended.
*
* This only affects the USB hardware for a device; its interfaces
* (and, for hubs, child devices) must already have been suspended.
*
* Suspending OTG devices may trigger HNP, if that's been enabled
* between a pair of dual-role devices. That will change roles, such
* as from A-Host to A-Peripheral or from B-Host back to B-Peripheral.
*
* Returns 0 on success, else negative errno.
*/
int usb_suspend_device(struct usb_device *udev, pm_message_t state)
int usb_suspend_device(struct usb_device *udev)
{
int port1, status;

port1 = locktree(udev);
if (port1 < 0)
return port1;

status = __usb_suspend_device(udev, port1, state);
status = __usb_suspend_device(udev, port1);
usb_unlock_device(udev);
return status;
}

/*
* If the USB "suspend" state is in use (rather than "global suspend"),
* many devices will be individually taken out of suspend state using
* special" resume" signaling. These routines kick in shortly after
* hardware resume signaling is finished, either because of selective
* resume (by host) or remote wakeup (by device) ... now see what changed
* in the tree that's rooted at this device.
Expand Down Expand Up @@ -1986,13 +1992,15 @@ void usb_resume_root_hub(struct usb_device *hdev)

#else /* !CONFIG_USB_SUSPEND */

int usb_suspend_device(struct usb_device *udev, pm_message_t state)
int usb_suspend_device(struct usb_device *udev)
{
/* state does NOT lie by saying it's USB_STATE_SUSPENDED! */
return 0;
}

int usb_resume_device(struct usb_device *udev)
{
udev->dev.power_state.event = PM_EVENT_ON;
return 0;
}

Expand Down
23 changes: 21 additions & 2 deletions drivers/usb/core/usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -1414,14 +1414,33 @@ void usb_buffer_unmap_sg (struct usb_device *dev, unsigned pipe,
usb_pipein (pipe) ? DMA_FROM_DEVICE : DMA_TO_DEVICE);
}

static int verify_suspended(struct device *dev, void *unused)
{
return (dev->power.power_state.event == PM_EVENT_ON) ? -EBUSY : 0;
}

static int usb_generic_suspend(struct device *dev, pm_message_t message)
{
struct usb_interface *intf;
struct usb_driver *driver;
int status;

if (dev->driver == &usb_generic_driver)
return usb_suspend_device (to_usb_device(dev), message);
/* USB devices enter SUSPEND state through their hubs, but can be
* marked for FREEZE as soon as their children are already idled.
*/
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;
if (message.event == PM_EVENT_FREEZE) {
dev->power.power_state = message;
return 0;
}
return usb_suspend_device (to_usb_device(dev));
}

if ((dev->driver == NULL) ||
(dev->driver_data == &usb_generic_driver_data))
Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/host/ehci-hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -759,7 +759,7 @@ static int ehci_suspend (struct usb_hcd *hcd, pm_message_t message)
msleep (100);

#ifdef CONFIG_USB_SUSPEND
(void) usb_suspend_device (hcd->self.root_hub, message);
(void) usb_suspend_device (hcd->self.root_hub);
#else
usb_lock_device (hcd->self.root_hub);
(void) ehci_hub_suspend (hcd);
Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/host/isp116x-hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1781,7 +1781,7 @@ static int isp116x_suspend(struct device *dev, pm_message_t state)

VDBG("%s: state %x\n", __func__, state);

ret = usb_suspend_device(hcd->self.root_hub, state);
ret = usb_suspend_device(hcd->self.root_hub);
if (!ret) {
dev->power.power_state = state;
INFO("%s suspended\n", hcd_name);
Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/host/ohci-pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ static int ohci_pci_suspend (struct usb_hcd *hcd, pm_message_t message)
msleep (100);

#ifdef CONFIG_USB_SUSPEND
(void) usb_suspend_device (hcd->self.root_hub, message);
(void) usb_suspend_device (hcd->self.root_hub);
#else
usb_lock_device (hcd->self.root_hub);
(void) ohci_hub_suspend (hcd);
Expand Down
2 changes: 1 addition & 1 deletion include/linux/usb.h
Original file line number Diff line number Diff line change
Expand Up @@ -976,7 +976,7 @@ extern int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe,
int timeout);

/* selective suspend/resume */
extern int usb_suspend_device(struct usb_device *dev, pm_message_t message);
extern int usb_suspend_device(struct usb_device *dev);
extern int usb_resume_device(struct usb_device *dev);


Expand Down

0 comments on commit 390a8c3

Please sign in to comment.