if (!hub)
return -EINVAL;
+ if (hub->in_reset) {
+ port_dev->power_is_on = 1;
+ return 0;
+ }
usb_autopm_get_interface(intf);
set_bit(port1, hub->busy_bits);
if (!hub)
return -EINVAL;
+ if (hub->in_reset)
+ return -EBUSY;
if (dev_pm_qos_flags(&port_dev->dev, PM_QOS_FLAG_NO_POWER_OFF)
== PM_QOS_FLAGS_ALL)
.pm = &usb_port_pm_ops,
};
+static struct device_driver usb_port_driver = {
+ .name = "usb",
+ .owner = THIS_MODULE,
+};
+
int usb_hub_create_port_device(struct usb_hub *hub, int port1)
{
struct usb_port *port_dev = NULL;
port_dev->dev.parent = hub->intfdev;
port_dev->dev.groups = port_dev_group;
port_dev->dev.type = &usb_port_device_type;
- dev_set_name(&port_dev->dev, "port%d", port1);
-
+ port_dev->dev.driver = &usb_port_driver;
+ dev_set_name(&port_dev->dev, "%s-port%d", dev_name(&hub->hdev->dev),
+ port1);
retval = device_register(&port_dev->dev);
if (retval)
goto error_register;
pm_runtime_set_active(&port_dev->dev);
- /* It would be dangerous if user space couldn't
- * prevent usb device from being powered off. So don't
- * enable port runtime pm if failed to expose port's pm qos.
+ /*
+ * Do not enable port runtime pm if the hub does not support
+ * power switching. Also, userspace must have final say of
+ * whether a port is permitted to power-off. Do not enable
+ * runtime pm if we fail to expose pm_qos_no_power_off.
*/
- if (!dev_pm_qos_expose_flags(&port_dev->dev,
- PM_QOS_FLAG_NO_POWER_OFF))
+ if (hub_is_port_power_switchable(hub)
+ && dev_pm_qos_expose_flags(&port_dev->dev,
+ PM_QOS_FLAG_NO_POWER_OFF) == 0)
pm_runtime_enable(&port_dev->dev);
device_enable_async_suspend(&port_dev->dev);