[RFC]Johan's patch for touchscreens and port power off

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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




[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux