Hi, Johan's patch means that for the affected touchscreen the port can never be powered off. It seems to me that this needs a special flag. What do you think? Regards Oliver >From a4d154ead29c0c7d1e11d29d8202c33526e08558 Mon Sep 17 00:00:00 2001 From: Oliver Neukum <oneukum@xxxxxxx> Date: Tue, 9 Sep 2014 16:07:32 +0200 Subject: [PATCH] usb: introduce flag for interfaces needing remote wakeup but allow power off Some devices cannot enter sleep without bad side effects unless remote wakeup is enabled. That means that under the current algorithm port power off cannot be used. There's no algoritmic helping that. The driver needs to tell us and that needs a flag. Signed-off-by: Oliver Neukum <oneukum@xxxxxxx> --- drivers/usb/core/hub.c | 26 +++++++++++++++++++++++++- include/linux/usb.h | 1 + 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 8a4dcbc..5aaeb83 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -3028,6 +3028,29 @@ static unsigned wakeup_enabled_descendants(struct usb_device *udev) } /* + * poweroff_check - checked whether remote wakeup allows powering off + * some devices cannot suspend without remote wakeup + * drivers are forced to request remote wakeup but + * that shouldn't count for switching off port power + */ +static int poweroff_check(struct usb_device *udev) +{ + struct usb_interface *intf; + int i; + + if (udev->actconfig) { + for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) { + intf = udev->actconfig->interface[i]; + + if (intf->needs_remote_wakeup && !intf->faked_remote_wakeup) + return 0; + } + } + + return 1; +} + +/* * usb_port_suspend - suspend a usb device's upstream port * @udev: device that's no longer in active use, not a root hub * Context: must be able to sleep; device not locked; pm locks held @@ -3173,7 +3196,8 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg) usb_set_device_state(udev, USB_STATE_SUSPENDED); } - if (status == 0 && !udev->do_remote_wakeup && udev->persist_enabled + if (status == 0 && poweroff_check(udev) + && udev->persist_enabled && test_and_clear_bit(port1, hub->child_usage_bits)) pm_runtime_put_sync(&port_dev->dev); diff --git a/include/linux/usb.h b/include/linux/usb.h index d2465bc..fdadf3b 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -183,6 +183,7 @@ struct usb_interface { unsigned needs_binding:1; /* needs delayed unbind/rebind */ unsigned reset_running:1; unsigned resetting_device:1; /* true: bandwidth alloc after reset */ + unsigned faked_remote_wakeup:1; /* the driver is not interested in wakeups */ struct device dev; /* interface specific device info */ struct device *usb_dev; -- 1.8.4.5 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html