Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 325864
b: refs/heads/master
c: f7ac778
h: refs/heads/master
v: v3
  • Loading branch information
Lan Tianyu authored and Greg Kroah-Hartman committed Sep 10, 2012
1 parent d5fcb8b commit 5d5779c
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 693d8eb853f62a1341cf59df151b12c053f34e8a
refs/heads/master: f7ac7787ad361e31a7972e2854ed8dc2eedfac3b
62 changes: 62 additions & 0 deletions trunk/drivers/usb/core/usb-acpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,68 @@

#include "usb.h"

/**
* usb_acpi_power_manageable - check whether usb port has
* acpi power resource.
* @hdev: USB device belonging to the usb hub
* @index: port index based zero
*
* Return true if the port has acpi power resource and false if no.
*/
bool usb_acpi_power_manageable(struct usb_device *hdev, int index)
{
acpi_handle port_handle;
int port1 = index + 1;

port_handle = usb_get_hub_port_acpi_handle(hdev,
port1);
if (port_handle)
return acpi_bus_power_manageable(port_handle);
else
return false;
}
EXPORT_SYMBOL_GPL(usb_acpi_power_manageable);

/**
* usb_acpi_set_power_state - control usb port's power via acpi power
* resource
* @hdev: USB device belonging to the usb hub
* @index: port index based zero
* @enable: power state expected to be set
*
* Notice to use usb_acpi_power_manageable() to check whether the usb port
* has acpi power resource before invoking this function.
*
* Returns 0 on success, else negative errno.
*/
int usb_acpi_set_power_state(struct usb_device *hdev, int index, bool enable)
{
acpi_handle port_handle;
unsigned char state;
int port1 = index + 1;
int error = -EINVAL;

port_handle = (acpi_handle)usb_get_hub_port_acpi_handle(hdev,
port1);
if (!port_handle)
return error;

if (enable)
state = ACPI_STATE_D0;
else
state = ACPI_STATE_D3_COLD;

error = acpi_bus_set_power(port_handle, state);
if (!error)
dev_dbg(&hdev->dev, "The power of hub port %d was set to %d\n",
port1, enable);
else
dev_dbg(&hdev->dev, "The power of hub port failed to be set\n");

return error;
}
EXPORT_SYMBOL_GPL(usb_acpi_set_power_state);

static int usb_acpi_check_port_connect_type(struct usb_device *hdev,
acpi_handle handle, int port1)
{
Expand Down
12 changes: 12 additions & 0 deletions trunk/drivers/usb/host/xhci-hub.c
Original file line number Diff line number Diff line change
Expand Up @@ -766,6 +766,12 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,

temp = xhci_readl(xhci, port_array[wIndex]);
xhci_dbg(xhci, "set port power, actual port %d status = 0x%x\n", wIndex, temp);

temp = usb_acpi_power_manageable(hcd->self.root_hub,
wIndex);
if (temp)
usb_acpi_set_power_state(hcd->self.root_hub,
wIndex, true);
break;
case USB_PORT_FEAT_RESET:
temp = (temp | PORT_RESET);
Expand Down Expand Up @@ -868,6 +874,12 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
case USB_PORT_FEAT_POWER:
xhci_writel(xhci, temp & ~PORT_POWER,
port_array[wIndex]);

temp = usb_acpi_power_manageable(hcd->self.root_hub,
wIndex);
if (temp)
usb_acpi_set_power_state(hcd->self.root_hub,
wIndex, false);
break;
default:
goto error;
Expand Down
10 changes: 10 additions & 0 deletions trunk/include/linux/usb.h
Original file line number Diff line number Diff line change
Expand Up @@ -602,6 +602,16 @@ extern int usb_lock_device_for_reset(struct usb_device *udev,
extern int usb_reset_device(struct usb_device *dev);
extern void usb_queue_reset_device(struct usb_interface *dev);

#ifdef CONFIG_ACPI
extern int usb_acpi_set_power_state(struct usb_device *hdev, int index,
bool enable);
extern bool usb_acpi_power_manageable(struct usb_device *hdev, int index);
#else
static inline int usb_acpi_set_power_state(struct usb_device *hdev, int index,
bool enable) { return 0; }
static inline bool usb_acpi_power_manageable(struct usb_device *hdev, int index)
{ return true; }
#endif

/* USB autosuspend and autoresume */
#ifdef CONFIG_USB_SUSPEND
Expand Down

0 comments on commit 5d5779c

Please sign in to comment.