HID: core: Add hid_hw_may_wakeup() function
authorHans de Goede <hdegoede@redhat.com>
Sat, 29 May 2021 15:14:21 +0000 (17:14 +0200)
committerJiri Kosina <jkosina@suse.cz>
Fri, 25 Jun 2021 12:02:58 +0000 (14:02 +0200)
Add a hid_hw_may_wakeup() function, which is the equivalent of
device_may_wakeup() for hid devices.

In most cases this just returns device_may_wakeup(hdev->dev.parent), but for
some ll-drivers this is not correct. E.g. usb_hid_driver instantiated hid
devices have their parent set to the usb-interface to which the usb_hid_driver
is bound, but the power/wakeup* sysfs attributes are part of the usb-device,
which is the usb-interface's parent.

For these special cases a new may_wakeup callback is added to
hid_ll_driver, so that ll-drivers can override the default behavior.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
include/linux/hid.h

index 10e922cee4ebbd732dad747a739b36e7bf12aa0c..51a4dad3565e55c2f50b83f90162c306ebacf5e3 100644 (file)
@@ -800,6 +800,7 @@ struct hid_driver {
  * @raw_request: send raw report request to device (e.g. feature report)
  * @output_report: send output report to device
  * @idle: send idle request to device
+ * @may_wakeup: return if device may act as a wakeup source during system-suspend
  */
 struct hid_ll_driver {
        int (*start)(struct hid_device *hdev);
@@ -824,6 +825,7 @@ struct hid_ll_driver {
        int (*output_report) (struct hid_device *hdev, __u8 *buf, size_t len);
 
        int (*idle)(struct hid_device *hdev, int report, int idle, int reqtype);
+       bool (*may_wakeup)(struct hid_device *hdev);
 };
 
 extern struct hid_ll_driver i2c_hid_ll_driver;
@@ -1149,6 +1151,22 @@ static inline int hid_hw_idle(struct hid_device *hdev, int report, int idle,
        return 0;
 }
 
+/**
+ * hid_may_wakeup - return if the hid device may act as a wakeup source during system-suspend
+ *
+ * @hdev: hid device
+ */
+static inline bool hid_hw_may_wakeup(struct hid_device *hdev)
+{
+       if (hdev->ll_driver->may_wakeup)
+               return hdev->ll_driver->may_wakeup(hdev);
+
+       if (hdev->dev.parent)
+               return device_may_wakeup(hdev->dev.parent);
+
+       return false;
+}
+
 /**
  * hid_hw_wait - wait for buffered io to complete
  *