Commit 9ac6678b authored by Aaron Armstrong Skomra's avatar Aaron Armstrong Skomra Committed by Jiri Kosina

HID: wacom: remove the battery when the EKR is off

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: default avatarAaron Skomra <skomra@gmail.com>
Signed-off-by: default avatarAaron Armstrong Skomra <aaron.skomra@wacom.com>
Reviewed-by: default avatarJason Gerecke <jason.gerecke@wacom.com>
Fixes: 9f1015d4 ("HID: wacom: EKR: attach the power_supply on first connection")
CC: stable@vger.kernel.org
Signed-off-by: default avatarJiri Kosina <jkosina@suse.cz>
parent 1d754604
...@@ -150,6 +150,7 @@ struct wacom_remote { ...@@ -150,6 +150,7 @@ struct wacom_remote {
struct input_dev *input; struct input_dev *input;
bool registered; bool registered;
struct wacom_battery battery; struct wacom_battery battery;
ktime_t active_time;
} remotes[WACOM_MAX_REMOTES]; } remotes[WACOM_MAX_REMOTES];
}; };
......
...@@ -2523,6 +2523,18 @@ static void wacom_wireless_work(struct work_struct *work) ...@@ -2523,6 +2523,18 @@ static void wacom_wireless_work(struct work_struct *work)
return; 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) static void wacom_remote_destroy_one(struct wacom *wacom, unsigned int index)
{ {
struct wacom_remote *remote = wacom->remote; struct wacom_remote *remote = wacom->remote;
...@@ -2537,9 +2549,7 @@ static void wacom_remote_destroy_one(struct wacom *wacom, unsigned int index) ...@@ -2537,9 +2549,7 @@ static void wacom_remote_destroy_one(struct wacom *wacom, unsigned int index)
remote->remotes[i].registered = false; remote->remotes[i].registered = false;
spin_unlock_irqrestore(&remote->remote_lock, flags); spin_unlock_irqrestore(&remote->remote_lock, flags);
if (remote->remotes[i].battery.battery) wacom_remote_destroy_battery(wacom, i);
devres_release_group(&wacom->hdev->dev,
&remote->remotes[i].battery.bat_desc);
if (remote->remotes[i].group.name) if (remote->remotes[i].group.name)
devres_release_group(&wacom->hdev->dev, devres_release_group(&wacom->hdev->dev,
...@@ -2547,7 +2557,6 @@ static void wacom_remote_destroy_one(struct wacom *wacom, unsigned int index) ...@@ -2547,7 +2557,6 @@ static void wacom_remote_destroy_one(struct wacom *wacom, unsigned int index)
remote->remotes[i].serial = 0; remote->remotes[i].serial = 0;
remote->remotes[i].group.name = NULL; remote->remotes[i].group.name = NULL;
remote->remotes[i].battery.battery = NULL;
wacom->led.groups[i].select = WACOM_STATUS_UNKNOWN; wacom->led.groups[i].select = WACOM_STATUS_UNKNOWN;
} }
} }
...@@ -2632,6 +2641,9 @@ static int wacom_remote_attach_battery(struct wacom *wacom, int index) ...@@ -2632,6 +2641,9 @@ static int wacom_remote_attach_battery(struct wacom *wacom, int index)
if (remote->remotes[index].battery.battery) if (remote->remotes[index].battery.battery)
return 0; return 0;
if (!remote->remotes[index].active_time)
return 0;
if (wacom->led.groups[index].select == WACOM_STATUS_UNKNOWN) if (wacom->led.groups[index].select == WACOM_STATUS_UNKNOWN)
return 0; return 0;
...@@ -2647,6 +2659,7 @@ static void wacom_remote_work(struct work_struct *work) ...@@ -2647,6 +2659,7 @@ static void wacom_remote_work(struct work_struct *work)
{ {
struct wacom *wacom = container_of(work, struct wacom, remote_work); struct wacom *wacom = container_of(work, struct wacom, remote_work);
struct wacom_remote *remote = wacom->remote; struct wacom_remote *remote = wacom->remote;
ktime_t kt = ktime_get();
struct wacom_remote_data data; struct wacom_remote_data data;
unsigned long flags; unsigned long flags;
unsigned int count; unsigned int count;
...@@ -2673,6 +2686,10 @@ static void wacom_remote_work(struct work_struct *work) ...@@ -2673,6 +2686,10 @@ static void wacom_remote_work(struct work_struct *work)
serial = data.remote[i].serial; serial = data.remote[i].serial;
if (data.remote[i].connected) { 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) { if (remote->remotes[i].serial == serial) {
wacom_remote_attach_battery(wacom, i); wacom_remote_attach_battery(wacom, i);
continue; continue;
......
...@@ -1134,6 +1134,7 @@ static int wacom_remote_irq(struct wacom_wac *wacom_wac, size_t len) ...@@ -1134,6 +1134,7 @@ static int wacom_remote_irq(struct wacom_wac *wacom_wac, size_t len)
if (index < 0 || !remote->remotes[index].registered) if (index < 0 || !remote->remotes[index].registered)
goto out; goto out;
remote->remotes[i].active_time = ktime_get();
input = remote->remotes[index].input; input = remote->remotes[index].input;
input_report_key(input, BTN_0, (data[9] & 0x01)); input_report_key(input, BTN_0, (data[9] & 0x01));
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#define WACOM_NAME_MAX 64 #define WACOM_NAME_MAX 64
#define WACOM_MAX_REMOTES 5 #define WACOM_MAX_REMOTES 5
#define WACOM_STATUS_UNKNOWN 255 #define WACOM_STATUS_UNKNOWN 255
#define WACOM_REMOTE_BATTERY_TIMEOUT 21000000000ll
/* packet length for individual models */ /* packet length for individual models */
#define WACOM_PKGLEN_BBFUN 9 #define WACOM_PKGLEN_BBFUN 9
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment