Commit 4956eccd authored by Alan Stern's avatar Alan Stern Committed by Greg Kroah-Hartman

USB: remove __usb_port_suspend

This patch (as915b) combines the public routine usb_port_suspend() and
the private routine __usb_port_suspend() into a single function.

By removing the explicit mention of otg_port in the call to
__usb_port_suspend(), we prevent a possible error in which the system
tries to perform HNP on the wrong port when a non-targeted device is
plugged into a non-OTG port.
Signed-off-by: default avatarAlan Stern <stern@rowland.harvard.edu>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent d576bb9f
...@@ -1333,7 +1333,6 @@ static inline void show_string(struct usb_device *udev, char *id, char *string) ...@@ -1333,7 +1333,6 @@ static inline void show_string(struct usb_device *udev, char *id, char *string)
#ifdef CONFIG_USB_OTG #ifdef CONFIG_USB_OTG
#include "otg_whitelist.h" #include "otg_whitelist.h"
static int __usb_port_suspend(struct usb_device *, int port1);
#endif #endif
/** /**
...@@ -1439,7 +1438,7 @@ int usb_new_device(struct usb_device *udev) ...@@ -1439,7 +1438,7 @@ int usb_new_device(struct usb_device *udev)
* (Includes HNP test device.) * (Includes HNP test device.)
*/ */
if (udev->bus->b_hnp_enable || udev->bus->is_b_host) { if (udev->bus->b_hnp_enable || udev->bus->is_b_host) {
err = __usb_port_suspend(udev, udev->bus->otg_port); err = usb_port_suspend(udev);
if (err < 0) if (err < 0)
dev_dbg(&udev->dev, "HNP fail, %d\n", err); dev_dbg(&udev->dev, "HNP fail, %d\n", err);
} }
...@@ -1683,6 +1682,23 @@ static int hub_port_suspend(struct usb_hub *hub, int port1, ...@@ -1683,6 +1682,23 @@ static int hub_port_suspend(struct usb_hub *hub, int port1,
} }
/* /*
* usb_port_suspend - suspend a usb device's upstream port
* @udev: device that's no longer in active use
* Context: must be able to sleep; device not locked; pm locks held
*
* Suspends a USB device that isn't in active use, conserving power.
* Devices may wake out of a suspend, if anything important happens,
* using the remote wakeup mechanism. They may also be taken out of
* suspend by the host, using usb_port_resume(). 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.
*
* Devices on USB hub ports have only one "suspend" state, corresponding * Devices on USB hub ports have only one "suspend" state, corresponding
* to ACPI D2, "may cause the device to lose some context". * to ACPI D2, "may cause the device to lose some context".
* State transitions include: * State transitions include:
...@@ -1699,21 +1715,19 @@ static int hub_port_suspend(struct usb_hub *hub, int port1, ...@@ -1699,21 +1715,19 @@ static int hub_port_suspend(struct usb_hub *hub, int port1,
* If CONFIG_USB_SUSPEND isn't enabled, devices only really suspend when * 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 * the root hub for their bus goes into global suspend ... so we don't
* (falsely) update the device power state to say it suspended. * (falsely) update the device power state to say it suspended.
*
* Returns 0 on success, else negative errno.
*/ */
static int __usb_port_suspend (struct usb_device *udev, int port1) int usb_port_suspend(struct usb_device *udev)
{ {
int status = 0; int status = 0;
/* caller owns the udev device lock */
if (port1 < 0)
return port1;
/* we change the device's upstream USB link, /* we change the device's upstream USB link,
* but root hubs have no upstream USB link. * but root hubs have no upstream USB link.
*/ */
if (udev->parent) if (udev->parent)
status = hub_port_suspend(hdev_to_hub(udev->parent), port1, status = hub_port_suspend(hdev_to_hub(udev->parent),
udev); udev->portnum, udev);
else { else {
dev_dbg(&udev->dev, "usb %ssuspend\n", dev_dbg(&udev->dev, "usb %ssuspend\n",
udev->auto_pm ? "auto-" : ""); udev->auto_pm ? "auto-" : "");
...@@ -1722,31 +1736,6 @@ static int __usb_port_suspend (struct usb_device *udev, int port1) ...@@ -1722,31 +1736,6 @@ static int __usb_port_suspend (struct usb_device *udev, int port1)
return status; return status;
} }
/*
* usb_port_suspend - suspend a usb device's upstream port
* @udev: device that's no longer in active use
* Context: must be able to sleep; device not locked; pm locks held
*
* Suspends a USB device that isn't in active use, conserving power.
* Devices may wake out of a suspend, if anything important happens,
* using the remote wakeup mechanism. They may also be taken out of
* suspend by the host, using usb_port_resume(). 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_port_suspend(struct usb_device *udev)
{
return __usb_port_suspend(udev, udev->portnum);
}
/* /*
* If the USB "suspend" state is in use (rather than "global suspend"), * If the USB "suspend" state is in use (rather than "global suspend"),
* many devices will be individually taken out of suspend state using * many devices will be individually taken out of suspend state using
......
...@@ -53,8 +53,16 @@ static inline void usb_pm_unlock(struct usb_device *udev) ...@@ -53,8 +53,16 @@ static inline void usb_pm_unlock(struct usb_device *udev)
#else #else
#define usb_port_suspend(dev) 0 static inline int usb_port_suspend(struct usb_device *udev)
#define usb_port_resume(dev) 0 {
return 0;
}
static inline int usb_port_resume(struct usb_device *udev)
{
return 0;
}
static inline void usb_pm_lock(struct usb_device *udev) {} static inline void usb_pm_lock(struct usb_device *udev) {}
static inline void usb_pm_unlock(struct usb_device *udev) {} static inline void usb_pm_unlock(struct usb_device *udev) {}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment