This source file includes following definitions.
- usb_acpi_power_manageable
- usb_acpi_set_power_state
- usb_acpi_get_connect_type
- usb_acpi_find_port
- usb_acpi_get_companion_for_port
- usb_acpi_find_companion_for_port
- usb_acpi_find_companion_for_device
- usb_acpi_find_companion
- usb_acpi_bus_match
- usb_acpi_register
- usb_acpi_unregister
   1 
   2 
   3 
   4 
   5 
   6 
   7 #include <linux/module.h>
   8 #include <linux/usb.h>
   9 #include <linux/device.h>
  10 #include <linux/errno.h>
  11 #include <linux/kernel.h>
  12 #include <linux/acpi.h>
  13 #include <linux/pci.h>
  14 #include <linux/usb/hcd.h>
  15 
  16 #include "hub.h"
  17 
  18 
  19 
  20 
  21 
  22 
  23 
  24 
  25 
  26 bool usb_acpi_power_manageable(struct usb_device *hdev, int index)
  27 {
  28         acpi_handle port_handle;
  29         int port1 = index + 1;
  30 
  31         port_handle = usb_get_hub_port_acpi_handle(hdev,
  32                 port1);
  33         if (port_handle)
  34                 return acpi_bus_power_manageable(port_handle);
  35         else
  36                 return false;
  37 }
  38 EXPORT_SYMBOL_GPL(usb_acpi_power_manageable);
  39 
  40 
  41 
  42 
  43 
  44 
  45 
  46 
  47 
  48 
  49 
  50 
  51 
  52 int usb_acpi_set_power_state(struct usb_device *hdev, int index, bool enable)
  53 {
  54         struct usb_hub *hub = usb_hub_to_struct_hub(hdev);
  55         struct usb_port *port_dev;
  56         acpi_handle port_handle;
  57         unsigned char state;
  58         int port1 = index + 1;
  59         int error = -EINVAL;
  60 
  61         if (!hub)
  62                 return -ENODEV;
  63         port_dev = hub->ports[port1 - 1];
  64 
  65         port_handle = (acpi_handle) usb_get_hub_port_acpi_handle(hdev, port1);
  66         if (!port_handle)
  67                 return error;
  68 
  69         if (enable)
  70                 state = ACPI_STATE_D0;
  71         else
  72                 state = ACPI_STATE_D3_COLD;
  73 
  74         error = acpi_bus_set_power(port_handle, state);
  75         if (!error)
  76                 dev_dbg(&port_dev->dev, "acpi: power was set to %d\n", enable);
  77         else
  78                 dev_dbg(&port_dev->dev, "acpi: power failed to be set\n");
  79 
  80         return error;
  81 }
  82 EXPORT_SYMBOL_GPL(usb_acpi_set_power_state);
  83 
  84 static enum usb_port_connect_type usb_acpi_get_connect_type(acpi_handle handle,
  85                 struct acpi_pld_info *pld)
  86 {
  87         enum usb_port_connect_type connect_type = USB_PORT_CONNECT_TYPE_UNKNOWN;
  88         struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
  89         union acpi_object *upc;
  90         acpi_status status;
  91 
  92         
  93 
  94 
  95 
  96 
  97 
  98 
  99 
 100         status = acpi_evaluate_object(handle, "_UPC", NULL, &buffer);
 101         upc = buffer.pointer;
 102         if (!upc || (upc->type != ACPI_TYPE_PACKAGE)
 103                 || upc->package.count != 4) {
 104                 goto out;
 105         }
 106 
 107         if (upc->package.elements[0].integer.value)
 108                 if (pld->user_visible)
 109                         connect_type = USB_PORT_CONNECT_TYPE_HOT_PLUG;
 110                 else
 111                         connect_type = USB_PORT_CONNECT_TYPE_HARD_WIRED;
 112         else if (!pld->user_visible)
 113                 connect_type = USB_PORT_NOT_USED;
 114 out:
 115         kfree(upc);
 116         return connect_type;
 117 }
 118 
 119 
 120 
 121 
 122 
 123 
 124 #define USB_ACPI_LOCATION_VALID (1 << 31)
 125 
 126 static struct acpi_device *usb_acpi_find_port(struct acpi_device *parent,
 127                                               int raw)
 128 {
 129         struct acpi_device *adev;
 130 
 131         if (!parent)
 132                 return NULL;
 133 
 134         list_for_each_entry(adev, &parent->children, node) {
 135                 if (acpi_device_adr(adev) == raw)
 136                         return adev;
 137         }
 138 
 139         return acpi_find_child_device(parent, raw, false);
 140 }
 141 
 142 static struct acpi_device *
 143 usb_acpi_get_companion_for_port(struct usb_port *port_dev)
 144 {
 145         struct usb_device *udev;
 146         struct acpi_device *adev;
 147         acpi_handle *parent_handle;
 148         int port1;
 149 
 150         
 151         udev = to_usb_device(port_dev->dev.parent->parent);
 152 
 153         
 154 
 155 
 156 
 157 
 158         if (!udev->parent) {
 159                 adev = ACPI_COMPANION(&udev->dev);
 160                 port1 = usb_hcd_find_raw_port_number(bus_to_hcd(udev->bus),
 161                                                      port_dev->portnum);
 162         } else {
 163                 parent_handle = usb_get_hub_port_acpi_handle(udev->parent,
 164                                                              udev->portnum);
 165                 if (!parent_handle)
 166                         return NULL;
 167 
 168                 acpi_bus_get_device(parent_handle, &adev);
 169                 port1 = port_dev->portnum;
 170         }
 171 
 172         return usb_acpi_find_port(adev, port1);
 173 }
 174 
 175 static struct acpi_device *
 176 usb_acpi_find_companion_for_port(struct usb_port *port_dev)
 177 {
 178         struct acpi_device *adev;
 179         struct acpi_pld_info *pld;
 180         acpi_handle *handle;
 181         acpi_status status;
 182 
 183         adev = usb_acpi_get_companion_for_port(port_dev);
 184         if (!adev)
 185                 return NULL;
 186 
 187         handle = adev->handle;
 188         status = acpi_get_physical_device_location(handle, &pld);
 189         if (!ACPI_FAILURE(status) && pld) {
 190                 port_dev->location = USB_ACPI_LOCATION_VALID
 191                         | pld->group_token << 8 | pld->group_position;
 192                 port_dev->connect_type = usb_acpi_get_connect_type(handle, pld);
 193                 ACPI_FREE(pld);
 194         }
 195 
 196         return adev;
 197 }
 198 
 199 static struct acpi_device *
 200 usb_acpi_find_companion_for_device(struct usb_device *udev)
 201 {
 202         struct acpi_device *adev;
 203         struct usb_port *port_dev;
 204         struct usb_hub *hub;
 205 
 206         if (!udev->parent) {
 207                 
 208                 adev = ACPI_COMPANION(udev->dev.parent);
 209                 return acpi_find_child_device(adev, 0, false);
 210         }
 211 
 212         hub = usb_hub_to_struct_hub(udev->parent);
 213         if (!hub)
 214                 return NULL;
 215 
 216         
 217 
 218 
 219 
 220         port_dev = hub->ports[udev->portnum - 1];
 221         return usb_acpi_get_companion_for_port(port_dev);
 222 }
 223 
 224 static struct acpi_device *usb_acpi_find_companion(struct device *dev)
 225 {
 226         
 227 
 228 
 229 
 230 
 231 
 232 
 233 
 234 
 235 
 236 
 237 
 238 
 239 
 240 
 241 
 242 
 243 
 244 
 245 
 246 
 247 
 248 
 249 
 250 
 251 
 252 
 253 
 254         if (is_usb_device(dev))
 255                 return usb_acpi_find_companion_for_device(to_usb_device(dev));
 256         else if (is_usb_port(dev))
 257                 return usb_acpi_find_companion_for_port(to_usb_port(dev));
 258 
 259         return NULL;
 260 }
 261 
 262 static bool usb_acpi_bus_match(struct device *dev)
 263 {
 264         return is_usb_device(dev) || is_usb_port(dev);
 265 }
 266 
 267 static struct acpi_bus_type usb_acpi_bus = {
 268         .name = "USB",
 269         .match = usb_acpi_bus_match,
 270         .find_companion = usb_acpi_find_companion,
 271 };
 272 
 273 int usb_acpi_register(void)
 274 {
 275         return register_acpi_bus_type(&usb_acpi_bus);
 276 }
 277 
 278 void usb_acpi_unregister(void)
 279 {
 280         unregister_acpi_bus_type(&usb_acpi_bus);
 281 }