| .. | .. |
|---|
| 16 | 16 | |
|---|
| 17 | 17 | static const struct attribute_group *port_dev_group[]; |
|---|
| 18 | 18 | |
|---|
| 19 | +static ssize_t location_show(struct device *dev, |
|---|
| 20 | + struct device_attribute *attr, char *buf) |
|---|
| 21 | +{ |
|---|
| 22 | + struct usb_port *port_dev = to_usb_port(dev); |
|---|
| 23 | + |
|---|
| 24 | + return sprintf(buf, "0x%08x\n", port_dev->location); |
|---|
| 25 | +} |
|---|
| 26 | +static DEVICE_ATTR_RO(location); |
|---|
| 27 | + |
|---|
| 19 | 28 | static ssize_t connect_type_show(struct device *dev, |
|---|
| 20 | 29 | struct device_attribute *attr, char *buf) |
|---|
| 21 | 30 | { |
|---|
| .. | .. |
|---|
| 140 | 149 | |
|---|
| 141 | 150 | static struct attribute *port_dev_attrs[] = { |
|---|
| 142 | 151 | &dev_attr_connect_type.attr, |
|---|
| 152 | + &dev_attr_location.attr, |
|---|
| 143 | 153 | &dev_attr_quirks.attr, |
|---|
| 144 | 154 | &dev_attr_over_current_count.attr, |
|---|
| 145 | 155 | NULL, |
|---|
| .. | .. |
|---|
| 281 | 291 | } |
|---|
| 282 | 292 | #endif |
|---|
| 283 | 293 | |
|---|
| 294 | +static void usb_port_shutdown(struct device *dev) |
|---|
| 295 | +{ |
|---|
| 296 | + struct usb_port *port_dev = to_usb_port(dev); |
|---|
| 297 | + |
|---|
| 298 | + if (port_dev->child) |
|---|
| 299 | + usb_disable_usb2_hardware_lpm(port_dev->child); |
|---|
| 300 | +} |
|---|
| 301 | + |
|---|
| 284 | 302 | static const struct dev_pm_ops usb_port_pm_ops = { |
|---|
| 285 | 303 | #ifdef CONFIG_PM |
|---|
| 286 | 304 | .runtime_suspend = usb_port_runtime_suspend, |
|---|
| .. | .. |
|---|
| 297 | 315 | static struct device_driver usb_port_driver = { |
|---|
| 298 | 316 | .name = "usb", |
|---|
| 299 | 317 | .owner = THIS_MODULE, |
|---|
| 318 | + .shutdown = usb_port_shutdown, |
|---|
| 300 | 319 | }; |
|---|
| 301 | 320 | |
|---|
| 302 | 321 | static int link_peers(struct usb_port *left, struct usb_port *right) |
|---|