Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 325861
b: refs/heads/master
c: d557542
h: refs/heads/master
i:
  325859: 1f0c0df
v: v3
  • Loading branch information
Lan Tianyu authored and Greg Kroah-Hartman committed Sep 10, 2012
1 parent 96520b1 commit 1d1343e
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 16 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: ff823c79a5c33194c2e5594f7c4686ea3547910c
refs/heads/master: d557542421da643358201664903e67fd01dfca1a
18 changes: 18 additions & 0 deletions trunk/drivers/usb/core/hub.c
Original file line number Diff line number Diff line change
Expand Up @@ -5077,3 +5077,21 @@ struct usb_device *usb_hub_find_child(struct usb_device *hdev,
return hub->ports[port1 - 1]->child;
}
EXPORT_SYMBOL_GPL(usb_hub_find_child);

#ifdef CONFIG_ACPI
/**
* usb_get_hub_port_acpi_handle - Get the usb port's acpi handle
* @hdev: USB device belonging to the usb hub
* @port1: port num of the port
*
* Return port's acpi handle if successful, NULL if params are
* invaild.
*/
acpi_handle usb_get_hub_port_acpi_handle(struct usb_device *hdev,
int port1)
{
struct usb_hub *hub = hdev_to_hub(hdev);

return DEVICE_ACPI_HANDLE(&hub->ports[port1 - 1]->dev);
}
#endif
67 changes: 52 additions & 15 deletions trunk/drivers/usb/core/usb-acpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,22 +70,59 @@ static int usb_acpi_check_pld(struct usb_device *udev, acpi_handle handle)
static int usb_acpi_find_device(struct device *dev, acpi_handle *handle)
{
struct usb_device *udev;
struct device *parent;
acpi_handle *parent_handle;
int port_num;

if (!is_usb_device(dev))
return -ENODEV;

udev = to_usb_device(dev);
parent = dev->parent;
parent_handle = DEVICE_ACPI_HANDLE(parent);

if (!parent_handle)
return -ENODEV;

*handle = acpi_get_child(parent_handle, udev->portnum);

if (!*handle)
/*
* In the ACPI DSDT table, only usb root hub and usb ports are
* acpi device nodes. The hierarchy like following.
* Device (EHC1)
* Device (HUBN)
* Device (PR01)
* Device (PR11)
* Device (PR12)
* Device (PR13)
* ...
* So all binding process is divided into two parts. binding
* root hub and usb ports.
*/
if (is_usb_device(dev)) {
udev = to_usb_device(dev);
if (udev->parent)
return -ENODEV;
/* root hub's parent is the usb hcd. */
parent_handle = DEVICE_ACPI_HANDLE(dev->parent);
*handle = acpi_get_child(parent_handle, udev->portnum);
if (!*handle)
return -ENODEV;
return 0;
} else if (is_usb_port(dev)) {
sscanf(dev_name(dev), "port%d", &port_num);
/* Get the struct usb_device point of port's hub */
udev = to_usb_device(dev->parent->parent);

/*
* The root hub ports' parent is the root hub. The non-root-hub
* ports' parent is the parent hub port which the hub is
* connected to.
*/
if (!udev->parent) {
*handle = acpi_get_child(DEVICE_ACPI_HANDLE(&udev->dev),
port_num);
if (!*handle)
return -ENODEV;
} else {
parent_handle =
usb_get_hub_port_acpi_handle(udev->parent,
udev->portnum);
if (!parent_handle)
return -ENODEV;

*handle = acpi_get_child(parent_handle, port_num);
if (!*handle)
return -ENODEV;
}
} else
return -ENODEV;

/*
Expand All @@ -102,7 +139,7 @@ static int usb_acpi_find_device(struct device *dev, acpi_handle *handle)

static struct acpi_bus_type usb_acpi_bus = {
.bus = &usb_bus_type,
.find_bridge = NULL,
.find_bridge = usb_acpi_find_device,
.find_device = usb_acpi_find_device,
};

Expand Down
9 changes: 9 additions & 0 deletions trunk/drivers/usb/core/usb.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include <linux/pm.h>
#include <linux/acpi.h>

struct dev_state;

Expand Down Expand Up @@ -115,6 +116,7 @@ extern struct bus_type usb_bus_type;
extern struct device_type usb_device_type;
extern struct device_type usb_if_device_type;
extern struct device_type usb_ep_device_type;
extern struct device_type usb_port_device_type;
extern struct usb_device_driver usb_generic_driver;

static inline int is_usb_device(const struct device *dev)
Expand All @@ -132,6 +134,11 @@ static inline int is_usb_endpoint(const struct device *dev)
return dev->type == &usb_ep_device_type;
}

static inline int is_usb_port(const struct device *dev)
{
return dev->type == &usb_port_device_type;
}

/* Do the same for device drivers and interface drivers. */

static inline int is_usb_device_driver(struct device_driver *drv)
Expand Down Expand Up @@ -166,6 +173,8 @@ extern void usb_notify_remove_bus(struct usb_bus *ubus);
#ifdef CONFIG_ACPI
extern int usb_acpi_register(void);
extern void usb_acpi_unregister(void);
extern acpi_handle usb_get_hub_port_acpi_handle(struct usb_device *hdev,
int port1);
#else
static inline int usb_acpi_register(void) { return 0; };
static inline void usb_acpi_unregister(void) { };
Expand Down

0 comments on commit 1d1343e

Please sign in to comment.