usb/acpi: Bind ACPI node to USB port, not usb_device.
[platform/adaptation/renesas_rcar/renesas_kernel.git] / drivers / usb / core / usb-acpi.c
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
22 static int usb_acpi_check_upc(struct usb_device *udev, acpi_handle handle)
23 {
24         acpi_status status;
25         struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
26         union acpi_object *upc;
27         int ret = 0;
28
29         status = acpi_evaluate_object(handle, "_UPC", NULL, &buffer);
30
31         if (ACPI_FAILURE(status))
32                 return -ENODEV;
33
34         upc = buffer.pointer;
35
36         if (!upc || (upc->type != ACPI_TYPE_PACKAGE)
37                 || upc->package.count != 4) {
38                 ret = -EINVAL;
39                 goto out;
40         }
41
42         if (upc->package.elements[0].integer.value)
43                 udev->removable = USB_DEVICE_REMOVABLE;
44         else
45                 udev->removable = USB_DEVICE_FIXED;
46
47 out:
48         kfree(upc);
49         return ret;
50 }
51
52 static int usb_acpi_check_pld(struct usb_device *udev, acpi_handle handle)
53 {
54         acpi_status status;
55         struct acpi_pld pld;
56
57         status = acpi_get_physical_device_location(handle, &pld);
58
59         if (ACPI_FAILURE(status))
60                 return -ENODEV;
61
62         if (pld.user_visible)
63                 udev->removable = USB_DEVICE_REMOVABLE;
64         else
65                 udev->removable = USB_DEVICE_FIXED;
66
67         return 0;
68 }
69
70 static int usb_acpi_find_device(struct device *dev, acpi_handle *handle)
71 {
72         struct usb_device *udev;
73         acpi_handle *parent_handle;
74         int port_num;
75
76         /*
77          * In the ACPI DSDT table, only usb root hub and usb ports are
78          * acpi device nodes. The hierarchy like following.
79          * Device (EHC1)
80          *      Device (HUBN)
81          *              Device (PR01)
82          *                      Device (PR11)
83          *                      Device (PR12)
84          *                      Device (PR13)
85          *                      ...
86          * So all binding process is divided into two parts. binding
87          * root hub and usb ports.
88          */
89         if (is_usb_device(dev)) {
90                 udev = to_usb_device(dev);
91                 if (udev->parent)
92                         return -ENODEV;
93                 /* root hub's parent is the usb hcd. */
94                 parent_handle = DEVICE_ACPI_HANDLE(dev->parent);
95                 *handle = acpi_get_child(parent_handle, udev->portnum);
96                 if (!*handle)
97                         return -ENODEV;
98                 return 0;
99         } else if (is_usb_port(dev)) {
100                 sscanf(dev_name(dev), "port%d", &port_num);
101                 /* Get the struct usb_device point of port's hub */
102                 udev = to_usb_device(dev->parent->parent);
103
104                 /*
105                  * The root hub ports' parent is the root hub. The non-root-hub
106                  * ports' parent is the parent hub port which the hub is
107                  * connected to.
108                  */
109                 if (!udev->parent) {
110                         *handle = acpi_get_child(DEVICE_ACPI_HANDLE(&udev->dev),
111                                 port_num);
112                         if (!*handle)
113                                 return -ENODEV;
114                 } else {
115                         parent_handle =
116                                 usb_get_hub_port_acpi_handle(udev->parent,
117                                 udev->portnum);
118                         if (!parent_handle)
119                                 return -ENODEV;
120
121                         *handle = acpi_get_child(parent_handle, port_num);
122                         if (!*handle)
123                                 return -ENODEV;
124                 }
125         } else
126                 return -ENODEV;
127
128         /*
129          * PLD will tell us whether a port is removable to the user or
130          * not. If we don't get an answer from PLD (it's not present
131          * or it's malformed) then try to infer it from UPC. If a
132          * device isn't connectable then it's probably not removable.
133          */
134         if (usb_acpi_check_pld(udev, *handle) != 0)
135                 usb_acpi_check_upc(udev, *handle);
136
137         return 0;
138 }
139
140 static struct acpi_bus_type usb_acpi_bus = {
141         .bus = &usb_bus_type,
142         .find_bridge = usb_acpi_find_device,
143         .find_device = usb_acpi_find_device,
144 };
145
146 int usb_acpi_register(void)
147 {
148         return register_acpi_bus_type(&usb_acpi_bus);
149 }
150
151 void usb_acpi_unregister(void)
152 {
153         unregister_acpi_bus_type(&usb_acpi_bus);
154 }