]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.1-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 21 Oct 2023 15:38:50 +0000 (17:38 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 21 Oct 2023 15:38:50 +0000 (17:38 +0200)
added patches:
hid-input-map-battery-system-charging.patch

queue-6.1/hid-input-map-battery-system-charging.patch [new file with mode: 0644]
queue-6.1/series

diff --git a/queue-6.1/hid-input-map-battery-system-charging.patch b/queue-6.1/hid-input-map-battery-system-charging.patch
new file mode 100644 (file)
index 0000000..2ac4926
--- /dev/null
@@ -0,0 +1,228 @@
+From a608dc1c06397dc50ab773498433432fb5938f92 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Jos=C3=A9=20Exp=C3=B3sito?= <jose.exposito89@gmail.com>
+Date: Thu, 24 Nov 2022 18:59:37 +0100
+Subject: HID: input: map battery system charging
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: José Expósito <jose.exposito89@gmail.com>
+
+commit a608dc1c06397dc50ab773498433432fb5938f92 upstream.
+
+HID descriptors with Battery System (0x85) Charging (0x44) usage are
+ignored and POWER_SUPPLY_STATUS_DISCHARGING is always reported to user
+space, even when the device is charging.
+
+Map this usage and when it is reported set the right charging status.
+
+In addition, add KUnit tests to make sure that the charging status is
+correctly set and reported. They can be run with the usual command:
+
+    $ ./tools/testing/kunit/kunit.py run --kunitconfig=drivers/hid
+
+Signed-off-by: José Expósito <jose.exposito89@gmail.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/hid/.kunitconfig     |    1 
+ drivers/hid/hid-input-test.c |   80 +++++++++++++++++++++++++++++++++++++++++++
+ drivers/hid/hid-input.c      |   36 ++++++++++++++++++-
+ include/linux/hid.h          |    2 +
+ 4 files changed, 117 insertions(+), 2 deletions(-)
+ create mode 100644 drivers/hid/hid-input-test.c
+
+--- a/drivers/hid/.kunitconfig
++++ b/drivers/hid/.kunitconfig
+@@ -1,5 +1,6 @@
+ CONFIG_KUNIT=y
+ CONFIG_USB=y
+ CONFIG_USB_HID=y
++CONFIG_HID_BATTERY_STRENGTH=y
+ CONFIG_HID_UCLOGIC=y
+ CONFIG_HID_KUNIT_TEST=y
+--- /dev/null
++++ b/drivers/hid/hid-input-test.c
+@@ -0,0 +1,80 @@
++// SPDX-License-Identifier: GPL-2.0+
++/*
++ *  HID to Linux Input mapping
++ *
++ *  Copyright (c) 2022 José Expósito <jose.exposito89@gmail.com>
++ */
++
++#include <kunit/test.h>
++
++static void hid_test_input_set_battery_charge_status(struct kunit *test)
++{
++      struct hid_device *dev;
++      bool handled;
++
++      dev = kunit_kzalloc(test, sizeof(*dev), GFP_KERNEL);
++      KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
++
++      handled = hidinput_set_battery_charge_status(dev, HID_DG_HEIGHT, 0);
++      KUNIT_EXPECT_FALSE(test, handled);
++      KUNIT_EXPECT_EQ(test, dev->battery_charge_status, POWER_SUPPLY_STATUS_UNKNOWN);
++
++      handled = hidinput_set_battery_charge_status(dev, HID_BAT_CHARGING, 0);
++      KUNIT_EXPECT_TRUE(test, handled);
++      KUNIT_EXPECT_EQ(test, dev->battery_charge_status, POWER_SUPPLY_STATUS_DISCHARGING);
++
++      handled = hidinput_set_battery_charge_status(dev, HID_BAT_CHARGING, 1);
++      KUNIT_EXPECT_TRUE(test, handled);
++      KUNIT_EXPECT_EQ(test, dev->battery_charge_status, POWER_SUPPLY_STATUS_CHARGING);
++}
++
++static void hid_test_input_get_battery_property(struct kunit *test)
++{
++      struct power_supply *psy;
++      struct hid_device *dev;
++      union power_supply_propval val;
++      int ret;
++
++      dev = kunit_kzalloc(test, sizeof(*dev), GFP_KERNEL);
++      KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
++      dev->battery_avoid_query = true;
++
++      psy = kunit_kzalloc(test, sizeof(*psy), GFP_KERNEL);
++      KUNIT_ASSERT_NOT_ERR_OR_NULL(test, psy);
++      psy->drv_data = dev;
++
++      dev->battery_status = HID_BATTERY_UNKNOWN;
++      dev->battery_charge_status = POWER_SUPPLY_STATUS_CHARGING;
++      ret = hidinput_get_battery_property(psy, POWER_SUPPLY_PROP_STATUS, &val);
++      KUNIT_EXPECT_EQ(test, ret, 0);
++      KUNIT_EXPECT_EQ(test, val.intval, POWER_SUPPLY_STATUS_UNKNOWN);
++
++      dev->battery_status = HID_BATTERY_REPORTED;
++      dev->battery_charge_status = POWER_SUPPLY_STATUS_CHARGING;
++      ret = hidinput_get_battery_property(psy, POWER_SUPPLY_PROP_STATUS, &val);
++      KUNIT_EXPECT_EQ(test, ret, 0);
++      KUNIT_EXPECT_EQ(test, val.intval, POWER_SUPPLY_STATUS_CHARGING);
++
++      dev->battery_status = HID_BATTERY_REPORTED;
++      dev->battery_charge_status = POWER_SUPPLY_STATUS_DISCHARGING;
++      ret = hidinput_get_battery_property(psy, POWER_SUPPLY_PROP_STATUS, &val);
++      KUNIT_EXPECT_EQ(test, ret, 0);
++      KUNIT_EXPECT_EQ(test, val.intval, POWER_SUPPLY_STATUS_DISCHARGING);
++}
++
++static struct kunit_case hid_input_tests[] = {
++      KUNIT_CASE(hid_test_input_set_battery_charge_status),
++      KUNIT_CASE(hid_test_input_get_battery_property),
++      { }
++};
++
++static struct kunit_suite hid_input_test_suite = {
++      .name = "hid_input",
++      .test_cases = hid_input_tests,
++};
++
++kunit_test_suite(hid_input_test_suite);
++
++MODULE_DESCRIPTION("HID input KUnit tests");
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("José Expósito <jose.exposito89@gmail.com>");
+--- a/drivers/hid/hid-input.c
++++ b/drivers/hid/hid-input.c
+@@ -492,7 +492,7 @@ static int hidinput_get_battery_property
+               if (dev->battery_status == HID_BATTERY_UNKNOWN)
+                       val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
+               else
+-                      val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
++                      val->intval = dev->battery_charge_status;
+               break;
+       case POWER_SUPPLY_PROP_SCOPE:
+@@ -560,6 +560,7 @@ static int hidinput_setup_battery(struct
+       dev->battery_max = max;
+       dev->battery_report_type = report_type;
+       dev->battery_report_id = field->report->id;
++      dev->battery_charge_status = POWER_SUPPLY_STATUS_DISCHARGING;
+       /*
+        * Stylus is normally not connected to the device and thus we
+@@ -626,6 +627,20 @@ static void hidinput_update_battery(stru
+               power_supply_changed(dev->battery);
+       }
+ }
++
++static bool hidinput_set_battery_charge_status(struct hid_device *dev,
++                                             unsigned int usage, int value)
++{
++      switch (usage) {
++      case HID_BAT_CHARGING:
++              dev->battery_charge_status = value ?
++                                           POWER_SUPPLY_STATUS_CHARGING :
++                                           POWER_SUPPLY_STATUS_DISCHARGING;
++              return true;
++      }
++
++      return false;
++}
+ #else  /* !CONFIG_HID_BATTERY_STRENGTH */
+ static int hidinput_setup_battery(struct hid_device *dev, unsigned report_type,
+                                 struct hid_field *field, bool is_percentage)
+@@ -640,6 +655,12 @@ static void hidinput_cleanup_battery(str
+ static void hidinput_update_battery(struct hid_device *dev, int value)
+ {
+ }
++
++static bool hidinput_set_battery_charge_status(struct hid_device *dev,
++                                             unsigned int usage, int value)
++{
++      return false;
++}
+ #endif        /* CONFIG_HID_BATTERY_STRENGTH */
+ static bool hidinput_field_in_collection(struct hid_device *device, struct hid_field *field,
+@@ -1239,6 +1260,9 @@ static void hidinput_configure_usage(str
+                       hidinput_setup_battery(device, HID_INPUT_REPORT, field, true);
+                       usage->type = EV_PWR;
+                       return;
++              case HID_BAT_CHARGING:
++                      usage->type = EV_PWR;
++                      return;
+               }
+               goto unknown;
+@@ -1481,7 +1505,11 @@ void hidinput_hid_event(struct hid_devic
+               return;
+       if (usage->type == EV_PWR) {
+-              hidinput_update_battery(hid, value);
++              bool handled = hidinput_set_battery_charge_status(hid, usage->hid, value);
++
++              if (!handled)
++                      hidinput_update_battery(hid, value);
++
+               return;
+       }
+@@ -2346,3 +2374,7 @@ void hidinput_disconnect(struct hid_devi
+       cancel_work_sync(&hid->led_work);
+ }
+ EXPORT_SYMBOL_GPL(hidinput_disconnect);
++
++#ifdef CONFIG_HID_KUNIT_TEST
++#include "hid-input-test.c"
++#endif
+--- a/include/linux/hid.h
++++ b/include/linux/hid.h
+@@ -312,6 +312,7 @@ struct hid_item {
+ #define HID_DG_LATENCYMODE    0x000d0060
+ #define HID_BAT_ABSOLUTESTATEOFCHARGE 0x00850065
++#define HID_BAT_CHARGING              0x00850044
+ #define HID_VD_ASUS_CUSTOM_MEDIA_KEYS 0xff310076
+@@ -612,6 +613,7 @@ struct hid_device {                                                        /* device repo
+       __s32 battery_max;
+       __s32 battery_report_type;
+       __s32 battery_report_id;
++      __s32 battery_charge_status;
+       enum hid_battery_status battery_status;
+       bool battery_avoid_query;
+       ktime_t battery_ratelimit_time;
index 1df8cfec54c7400872e01b83c5eba0b3624bc112..810e5debf3965f8d55769d9fc1e81a085f977835 100644 (file)
@@ -179,3 +179,4 @@ nvme-pci-add-bogus_nid-for-intel-0a54-device.patch
 nvmet-auth-complete-a-request-only-after-freeing-the-dhchap-pointers.patch
 nvme-rdma-do-not-try-to-stop-unallocated-queues.patch
 kvm-x86-mmu-stop-zapping-invalidated-tdp-mmu-roots-asynchronously.patch
+hid-input-map-battery-system-charging.patch