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
commit 9ac6678 upstream.

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: 9f1015d ("HID: wacom: EKR: attach the power_supply on first connection")
CC: stable@vger.kernel.org
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
skomra authored and gregkh committed Sep 6, 2023
1 parent 48729a1 commit bd69537
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 4 deletions.
1 change: 1 addition & 0 deletions drivers/hid/wacom.h
Expand Up @@ -150,6 +150,7 @@ struct wacom_remote {
struct input_dev *input;
bool registered;
struct wacom_battery battery;
ktime_t active_time;
} remotes[WACOM_MAX_REMOTES];
};

Expand Down
25 changes: 21 additions & 4 deletions drivers/hid/wacom_sys.c
Expand Up @@ -2527,6 +2527,18 @@ static void wacom_wireless_work(struct work_struct *work)
return;
}

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;
}
}

static void wacom_remote_destroy_one(struct wacom *wacom, unsigned int index)
{
struct wacom_remote *remote = wacom->remote;
Expand All @@ -2541,17 +2553,14 @@ 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 (remote->remotes[i].battery.battery)
devres_release_group(&wacom->hdev->dev,
&remote->remotes[i].battery.bat_desc);
wacom_remote_destroy_battery(wacom, i);

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;
remote->remotes[i].battery.battery = NULL;
wacom->led.groups[i].select = WACOM_STATUS_UNKNOWN;
}
}
Expand Down Expand Up @@ -2636,6 +2645,9 @@ static int wacom_remote_attach_battery(struct wacom *wacom, int index)
if (remote->remotes[index].battery.battery)
return 0;

if (!remote->remotes[index].active_time)
return 0;

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

Expand All @@ -2651,6 +2663,7 @@ 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;
ktime_t kt = ktime_get();
struct wacom_remote_data data;
unsigned long flags;
unsigned int count;
Expand All @@ -2677,6 +2690,10 @@ static void wacom_remote_work(struct work_struct *work)
serial = data.remote[i].serial;
if (data.remote[i].connected) {

if (kt - remote->remotes[i].active_time > WACOM_REMOTE_BATTERY_TIMEOUT
&& remote->remotes[i].active_time != 0)
wacom_remote_destroy_battery(wacom, i);

if (remote->remotes[i].serial == serial) {
wacom_remote_attach_battery(wacom, i);
continue;
Expand Down
1 change: 1 addition & 0 deletions drivers/hid/wacom_wac.c
Expand Up @@ -1129,6 +1129,7 @@ static int wacom_remote_irq(struct wacom_wac *wacom_wac, size_t len)
if (index < 0 || !remote->remotes[index].registered)
goto out;

remote->remotes[i].active_time = ktime_get();
input = remote->remotes[index].input;

input_report_key(input, BTN_0, (data[9] & 0x01));
Expand Down
1 change: 1 addition & 0 deletions drivers/hid/wacom_wac.h
Expand Up @@ -13,6 +13,7 @@
#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 bd69537

Please sign in to comment.