0001
0002
0003
0004
0005
0006
0007 #include <linux/module.h>
0008 #include <linux/usb.h>
0009 #include <linux/device.h>
0010 #include <linux/errno.h>
0011 #include <linux/kernel.h>
0012 #include <linux/acpi.h>
0013 #include <linux/pci.h>
0014 #include <linux/usb/hcd.h>
0015
0016 #include "hub.h"
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026 bool usb_acpi_power_manageable(struct usb_device *hdev, int index)
0027 {
0028 acpi_handle port_handle;
0029 int port1 = index + 1;
0030
0031 port_handle = usb_get_hub_port_acpi_handle(hdev,
0032 port1);
0033 if (port_handle)
0034 return acpi_bus_power_manageable(port_handle);
0035 else
0036 return false;
0037 }
0038 EXPORT_SYMBOL_GPL(usb_acpi_power_manageable);
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052 int usb_acpi_set_power_state(struct usb_device *hdev, int index, bool enable)
0053 {
0054 struct usb_hub *hub = usb_hub_to_struct_hub(hdev);
0055 struct usb_port *port_dev;
0056 acpi_handle port_handle;
0057 unsigned char state;
0058 int port1 = index + 1;
0059 int error = -EINVAL;
0060
0061 if (!hub)
0062 return -ENODEV;
0063 port_dev = hub->ports[port1 - 1];
0064
0065 port_handle = (acpi_handle) usb_get_hub_port_acpi_handle(hdev, port1);
0066 if (!port_handle)
0067 return error;
0068
0069 if (enable)
0070 state = ACPI_STATE_D0;
0071 else
0072 state = ACPI_STATE_D3_COLD;
0073
0074 error = acpi_bus_set_power(port_handle, state);
0075 if (!error)
0076 dev_dbg(&port_dev->dev, "acpi: power was set to %d\n", enable);
0077 else
0078 dev_dbg(&port_dev->dev, "acpi: power failed to be set\n");
0079
0080 return error;
0081 }
0082 EXPORT_SYMBOL_GPL(usb_acpi_set_power_state);
0083
0084 static enum usb_port_connect_type usb_acpi_get_connect_type(acpi_handle handle,
0085 struct acpi_pld_info *pld)
0086 {
0087 enum usb_port_connect_type connect_type = USB_PORT_CONNECT_TYPE_UNKNOWN;
0088 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
0089 union acpi_object *upc = NULL;
0090 acpi_status status;
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100 status = acpi_evaluate_object(handle, "_UPC", NULL, &buffer);
0101 if (ACPI_FAILURE(status))
0102 goto out;
0103
0104 upc = buffer.pointer;
0105 if (!upc || (upc->type != ACPI_TYPE_PACKAGE) || upc->package.count != 4)
0106 goto out;
0107
0108 if (upc->package.elements[0].integer.value)
0109 if (pld->user_visible)
0110 connect_type = USB_PORT_CONNECT_TYPE_HOT_PLUG;
0111 else
0112 connect_type = USB_PORT_CONNECT_TYPE_HARD_WIRED;
0113 else if (!pld->user_visible)
0114 connect_type = USB_PORT_NOT_USED;
0115 out:
0116 kfree(upc);
0117 return connect_type;
0118 }
0119
0120
0121
0122
0123
0124
0125 #define USB_ACPI_LOCATION_VALID (1 << 31)
0126
0127 static struct acpi_device *
0128 usb_acpi_get_companion_for_port(struct usb_port *port_dev)
0129 {
0130 struct usb_device *udev;
0131 struct acpi_device *adev;
0132 acpi_handle *parent_handle;
0133 int port1;
0134
0135
0136 udev = to_usb_device(port_dev->dev.parent->parent);
0137
0138
0139
0140
0141
0142
0143 if (!udev->parent) {
0144 adev = ACPI_COMPANION(&udev->dev);
0145 port1 = usb_hcd_find_raw_port_number(bus_to_hcd(udev->bus),
0146 port_dev->portnum);
0147 } else {
0148 parent_handle = usb_get_hub_port_acpi_handle(udev->parent,
0149 udev->portnum);
0150 if (!parent_handle)
0151 return NULL;
0152
0153 adev = acpi_fetch_acpi_dev(parent_handle);
0154 port1 = port_dev->portnum;
0155 }
0156
0157 return acpi_find_child_by_adr(adev, port1);
0158 }
0159
0160 static struct acpi_device *
0161 usb_acpi_find_companion_for_port(struct usb_port *port_dev)
0162 {
0163 struct acpi_device *adev;
0164 struct acpi_pld_info *pld;
0165 acpi_handle *handle;
0166 acpi_status status;
0167
0168 adev = usb_acpi_get_companion_for_port(port_dev);
0169 if (!adev)
0170 return NULL;
0171
0172 handle = adev->handle;
0173 status = acpi_get_physical_device_location(handle, &pld);
0174 if (ACPI_SUCCESS(status) && pld) {
0175 port_dev->location = USB_ACPI_LOCATION_VALID
0176 | pld->group_token << 8 | pld->group_position;
0177 port_dev->connect_type = usb_acpi_get_connect_type(handle, pld);
0178 ACPI_FREE(pld);
0179 }
0180
0181 return adev;
0182 }
0183
0184 static struct acpi_device *
0185 usb_acpi_find_companion_for_device(struct usb_device *udev)
0186 {
0187 struct acpi_device *adev;
0188 struct usb_port *port_dev;
0189 struct usb_hub *hub;
0190
0191 if (!udev->parent) {
0192
0193
0194
0195
0196 adev = ACPI_COMPANION(udev->bus->sysdev);
0197 return acpi_find_child_device(adev, 0, false);
0198 }
0199
0200 hub = usb_hub_to_struct_hub(udev->parent);
0201 if (!hub)
0202 return NULL;
0203
0204
0205
0206
0207
0208 port_dev = hub->ports[udev->portnum - 1];
0209 return usb_acpi_get_companion_for_port(port_dev);
0210 }
0211
0212 static struct acpi_device *usb_acpi_find_companion(struct device *dev)
0213 {
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242 if (is_usb_device(dev))
0243 return usb_acpi_find_companion_for_device(to_usb_device(dev));
0244 else if (is_usb_port(dev))
0245 return usb_acpi_find_companion_for_port(to_usb_port(dev));
0246
0247 return NULL;
0248 }
0249
0250 static bool usb_acpi_bus_match(struct device *dev)
0251 {
0252 return is_usb_device(dev) || is_usb_port(dev);
0253 }
0254
0255 static struct acpi_bus_type usb_acpi_bus = {
0256 .name = "USB",
0257 .match = usb_acpi_bus_match,
0258 .find_companion = usb_acpi_find_companion,
0259 };
0260
0261 int usb_acpi_register(void)
0262 {
0263 return register_acpi_bus_type(&usb_acpi_bus);
0264 }
0265
0266 void usb_acpi_unregister(void)
0267 {
0268 unregister_acpi_bus_type(&usb_acpi_bus);
0269 }