Skip to content

Commit

Permalink
HID: wacom: remove the battery when the EKR is off
Browse files Browse the repository at this point in the history
Currently the EKR battery remains even after we stop getting information
from the device. This can lead to a stale battery persisting indefinitely
in userspace.

The remote sends a heartbeat every 10 seconds. Delete the battery if we
miss two heartbeats (after 21 seconds). Restore the battery once we see
a heartbeat again.

Signed-off-by: Aaron Skomra <skomra@gmail.com>
Signed-off-by: Aaron Armstrong Skomra <aaron.skomra@wacom.com>
Reviewed-by: Jason Gerecke <jason.gerecke@wacom.com>
Fixes: 9f1015d45f62 ("HID: wacom: EKR: attach the power_supply on first connection")
CC: stable@vger.kernel.org
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
[joshua.dickens@wacom.com: Imported into input-wacom repository (9ac6678b95b0)]
Signed-off-by: Joshua Dickens <joshua.dickens@wacom.com>
  • Loading branch information
skomra authored and jigpu committed Aug 31, 2023
1 parent 67cf286 commit ee4d5b2
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 1 deletion.
5 changes: 4 additions & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:
runs-on: ubuntu-20.04
strategy:
matrix:
kernel: ["6.3", "5.10", "4.14", "4.6", "4.5", "4.1", "3.19", "3.18", "3.17"]
kernel: ["6.3", "5.10", "4.14", "4.10", "4.6", "4.5", "4.1", "3.19", "3.18", "3.17"]
include:
- kernel: "3.17"
compile_cflags: -fno-pie -Wno-error=format-truncation
Expand All @@ -29,6 +29,9 @@ jobs:
- kernel: "4.6"
compile_cflags: -fno-pie -Wno-error=format-truncation -Wno-error=pointer-sign
prepare_cflags: -fno-pie -no-pie
- kernel: "4.10"
compile_cflags: -fno-pie -Wno-error=format-truncation -Wno-error=pointer-sign
prepare_cflags: -fno-pie -no-pie
- kernel: "4.14"
compile_cflags: -Wno-error=format-truncation -Wno-error=pointer-sign
- kernel: "5.10"
Expand Down
3 changes: 3 additions & 0 deletions 4.5/wacom.h
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,9 @@ struct wacom_remote {
struct input_dev *input;
bool registered;
struct wacom_battery battery;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0)
ktime_t active_time;
#endif
} remotes[WACOM_MAX_REMOTES];
};

Expand Down
34 changes: 34 additions & 0 deletions 4.5/wacom_sys.c
Original file line number Diff line number Diff line change
Expand Up @@ -2585,6 +2585,20 @@ static void wacom_wireless_work(struct work_struct *work)
return;
}

#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0)
static void wacom_remote_destroy_battery(struct wacom *wacom, int index)
{
struct wacom_remote *remote = wacom->remote;

if (remote->remotes[index].battery.battery) {
devres_release_group(&wacom->hdev->dev,
&remote->remotes[index].battery.bat_desc);
remote->remotes[index].battery.battery = NULL;
remote->remotes[index].active_time = 0;
}
}
#endif

static void wacom_remote_destroy_one(struct wacom *wacom, unsigned int index)
{
struct wacom_remote *remote = wacom->remote;
Expand All @@ -2599,17 +2613,23 @@ static void wacom_remote_destroy_one(struct wacom *wacom, unsigned int index)
remote->remotes[i].registered = false;
spin_unlock_irqrestore(&remote->remote_lock, flags);

#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0)
wacom_remote_destroy_battery(wacom, i);
#else
if (remote->remotes[i].battery.battery)
devres_release_group(&wacom->hdev->dev,
&remote->remotes[i].battery.bat_desc);
#endif

if (remote->remotes[i].group.name)
devres_release_group(&wacom->hdev->dev,
&remote->remotes[i]);

remote->remotes[i].serial = 0;
remote->remotes[i].group.name = NULL;
#if LINUX_VERSION_CODE < KERNEL_VERSION(4,10,0)
remote->remotes[i].battery.battery = NULL;
#endif
wacom->led.groups[i].select = WACOM_STATUS_UNKNOWN;
}
}
Expand Down Expand Up @@ -2694,6 +2714,11 @@ static int wacom_remote_attach_battery(struct wacom *wacom, int index)
if (remote->remotes[index].battery.battery)
return 0;

#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0)
if (!remote->remotes[index].active_time)
return 0;
#endif

if (wacom->led.groups[index].select == WACOM_STATUS_UNKNOWN)
return 0;

Expand All @@ -2709,6 +2734,9 @@ static void wacom_remote_work(struct work_struct *work)
{
struct wacom *wacom = container_of(work, struct wacom, remote_work);
struct wacom_remote *remote = wacom->remote;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0)
ktime_t kt = ktime_get();
#endif
struct wacom_remote_data data;
unsigned long flags;
unsigned int count;
Expand All @@ -2735,6 +2763,12 @@ static void wacom_remote_work(struct work_struct *work)
serial = data.remote[i].serial;
if (data.remote[i].connected) {

#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0)
if (kt - remote->remotes[i].active_time > WACOM_REMOTE_BATTERY_TIMEOUT
&& remote->remotes[i].active_time != 0)
wacom_remote_destroy_battery(wacom, i);
#endif

if (remote->remotes[i].serial == serial) {
wacom_remote_attach_battery(wacom, i);
continue;
Expand Down
3 changes: 3 additions & 0 deletions 4.5/wacom_wac.c
Original file line number Diff line number Diff line change
Expand Up @@ -1144,6 +1144,9 @@ static int wacom_remote_irq(struct wacom_wac *wacom_wac, size_t len)
if (index < 0 || !remote->remotes[index].registered)
goto out;

#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0)
remote->remotes[i].active_time = ktime_get();
#endif
input = remote->remotes[index].input;

input_report_key(input, BTN_0, (data[9] & 0x01));
Expand Down
2 changes: 2 additions & 0 deletions 4.5/wacom_wac.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@
#include <linux/types.h>
#include <linux/hid.h>
#include <linux/kfifo.h>
#include <linux/version.h>

/* maximum packet length for USB/BT devices */
#define WACOM_PKGLEN_MAX 361

#define WACOM_NAME_MAX 64
#define WACOM_MAX_REMOTES 5
#define WACOM_STATUS_UNKNOWN 255
#define WACOM_REMOTE_BATTERY_TIMEOUT 21000000000ll

/* packet length for individual models */
#define WACOM_PKGLEN_BBFUN 9
Expand Down

0 comments on commit ee4d5b2

Please sign in to comment.