aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Garrett <mjg@redhat.com>2012-05-11 04:08:27 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-05-11 20:06:13 -0400
commitda0af6e78ef311d97754aa03e10eade82cc99e16 (patch)
tree52d904e831d619452299844c7f55b61be2d62a53
parent38ac0f1b90dc9486cc039f1a4d8b0202813e5b67 (diff)
usb: Bind devices to ACPI devices when possible
Built-in USB devices will typically have a representation in the system ACPI tables. Add support for binding the two together so the USB code can make use of the associated methods. Signed-off-by: Matthew Garrett <mjg@redhat.com> Signed-off-by: Lan Tianyu <tianyu.lan@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/usb/core/Makefile1
-rw-r--r--drivers/usb/core/usb-acpi.c60
-rw-r--r--drivers/usb/core/usb.c6
-rw-r--r--drivers/usb/core/usb.h7
4 files changed, 74 insertions, 0 deletions
diff --git a/drivers/usb/core/Makefile b/drivers/usb/core/Makefile
index c4ea846d3c0..26059b93dbf 100644
--- a/drivers/usb/core/Makefile
+++ b/drivers/usb/core/Makefile
@@ -9,5 +9,6 @@ usbcore-y += config.o file.o buffer.o sysfs.o endpoint.o
9usbcore-y += devio.o notify.o generic.o quirks.o devices.o 9usbcore-y += devio.o notify.o generic.o quirks.o devices.o
10 10
11usbcore-$(CONFIG_PCI) += hcd-pci.o 11usbcore-$(CONFIG_PCI) += hcd-pci.o
12usbcore-$(CONFIG_ACPI) += usb-acpi.o
12 13
13obj-$(CONFIG_USB) += usbcore.o 14obj-$(CONFIG_USB) += usbcore.o
diff --git a/drivers/usb/core/usb-acpi.c b/drivers/usb/core/usb-acpi.c
new file mode 100644
index 00000000000..cab5cb7c256
--- /dev/null
+++ b/drivers/usb/core/usb-acpi.c
@@ -0,0 +1,60 @@
1/*
2 * USB-ACPI glue code
3 *
4 * Copyright 2012 Red Hat <mjg@redhat.com>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation, version 2.
9 *
10 */
11#include <linux/module.h>
12#include <linux/usb.h>
13#include <linux/device.h>
14#include <linux/errno.h>
15#include <linux/kernel.h>
16#include <linux/acpi.h>
17#include <linux/pci.h>
18#include <acpi/acpi_bus.h>
19
20#include "usb.h"
21
22static int usb_acpi_find_device(struct device *dev, acpi_handle *handle)
23{
24 struct usb_device *udev;
25 struct device *parent;
26 acpi_handle *parent_handle;
27
28 if (!is_usb_device(dev))
29 return -ENODEV;
30
31 udev = to_usb_device(dev);
32 parent = dev->parent;
33 parent_handle = DEVICE_ACPI_HANDLE(parent);
34
35 if (!parent_handle)
36 return -ENODEV;
37
38 *handle = acpi_get_child(parent_handle, udev->portnum);
39
40 if (!*handle)
41 return -ENODEV;
42
43 return 0;
44}
45
46static struct acpi_bus_type usb_acpi_bus = {
47 .bus = &usb_bus_type,
48 .find_bridge = NULL,
49 .find_device = usb_acpi_find_device,
50};
51
52int usb_acpi_register(void)
53{
54 return register_acpi_bus_type(&usb_acpi_bus);
55}
56
57void usb_acpi_unregister(void)
58{
59 unregister_acpi_bus_type(&usb_acpi_bus);
60}
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 0ce862bfdd7..7998a67503c 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -1015,6 +1015,9 @@ static int __init usb_init(void)
1015 if (retval) 1015 if (retval)
1016 goto out; 1016 goto out;
1017 1017
1018 retval = usb_acpi_register();
1019 if (retval)
1020 goto acpi_register_failed;
1018 retval = bus_register(&usb_bus_type); 1021 retval = bus_register(&usb_bus_type);
1019 if (retval) 1022 if (retval)
1020 goto bus_register_failed; 1023 goto bus_register_failed;
@@ -1049,6 +1052,8 @@ major_init_failed:
1049bus_notifier_failed: 1052bus_notifier_failed:
1050 bus_unregister(&usb_bus_type); 1053 bus_unregister(&usb_bus_type);
1051bus_register_failed: 1054bus_register_failed:
1055 usb_acpi_unregister();
1056acpi_register_failed:
1052 usb_debugfs_cleanup(); 1057 usb_debugfs_cleanup();
1053out: 1058out:
1054 return retval; 1059 return retval;
@@ -1070,6 +1075,7 @@ static void __exit usb_exit(void)
1070 usb_hub_cleanup(); 1075 usb_hub_cleanup();
1071 bus_unregister_notifier(&usb_bus_type, &usb_bus_nb); 1076 bus_unregister_notifier(&usb_bus_type, &usb_bus_nb);
1072 bus_unregister(&usb_bus_type); 1077 bus_unregister(&usb_bus_type);
1078 usb_acpi_unregister();
1073 usb_debugfs_cleanup(); 1079 usb_debugfs_cleanup();
1074} 1080}
1075 1081
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h
index 71648dcbe43..5c5c538ea73 100644
--- a/drivers/usb/core/usb.h
+++ b/drivers/usb/core/usb.h
@@ -156,3 +156,10 @@ extern void usb_notify_remove_device(struct usb_device *udev);
156extern void usb_notify_add_bus(struct usb_bus *ubus); 156extern void usb_notify_add_bus(struct usb_bus *ubus);
157extern void usb_notify_remove_bus(struct usb_bus *ubus); 157extern void usb_notify_remove_bus(struct usb_bus *ubus);
158 158
159#ifdef CONFIG_ACPI
160extern int usb_acpi_register(void);
161extern void usb_acpi_unregister(void);
162#else
163static inline int usb_acpi_register(void) { return 0; };
164static inline void usb_acpi_unregister(void) { };
165#endif