This patch is to add "auto" option to attribute portX/control.
When echo "auto", the port's feature PORT_POWER would be clear
if the port's connect type was mark not-used(connectability and
visibility are both cleared) and with no device attached.

Signed-off-by: Lan Tianyu <[email protected]>
---
 drivers/usb/core/hub.c |   17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index b8a5af4..65c91300 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -42,6 +42,7 @@
 enum port_power_policy {
        USB_PORT_POWER_ON = 0,
        USB_PORT_POWER_OFF,
+       USB_PORT_POWER_AUTO,
 };
 
 struct usb_port {
@@ -105,6 +106,7 @@ struct device_type usb_port_device_type = {
 
 static const char on_string[] = "on";
 static const char off_string[] = "off";
+static const char auto_string[] = "auto";
 static const struct attribute_group *port_dev_group[];
 
 static inline int hub_is_superspeed(struct usb_device *hdev)
@@ -4703,6 +4705,9 @@ static ssize_t show_port_power_control(struct device *dev,
        case USB_PORT_POWER_OFF:
                result = off_string;
                break;
+       case USB_PORT_POWER_AUTO:
+               result = auto_string;
+               break;
        default:
                return -EINVAL;
        }
@@ -4741,6 +4746,18 @@ static ssize_t store_port_power_control(struct device 
*dev,
                usb_autopm_put_interface(intf);
                if (ret < 0)
                        return -EIO;
+       } else if (len == sizeof(auto_string) - 1
+                       && strncmp(buf, auto_string, len) == 0) {
+               hub_port->port_power_policy = USB_PORT_POWER_AUTO;
+               if (hub_port->connect_type
+                       == USB_PORT_NOT_USED && !hub_port->child) {
+                       usb_autopm_get_interface(intf);
+                       ret = clear_port_feature(hdev, port1,
+                               USB_PORT_FEAT_POWER);
+                       usb_autopm_put_interface(intf);
+                       if (ret < 0)
+                               return -EIO;
+               }
        } else
                return -EINVAL;
 
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to