Commit d4de578a authored by Benjamin Tissoires's avatar Benjamin Tissoires
Browse files

Merge branch 'for-6.6/wacom' into for-linus

Battery fixes by Aaron Armstrong Skomra
parents d5c04a72 55ab9b2c
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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];
};

+31 −13
Original line number Diff line number Diff line
@@ -1997,7 +1997,7 @@ static int wacom_initialize_remotes(struct wacom *wacom)
	spin_lock_init(&remote->remote_lock);

	error = kfifo_alloc(&remote->remote_fifo,
			5 * sizeof(struct wacom_remote_data),
			5 * sizeof(struct wacom_remote_work_data),
			GFP_KERNEL);
	if (error) {
		hid_err(wacom->hdev, "failed allocating remote_fifo\n");
@@ -2523,6 +2523,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;
@@ -2537,9 +2549,7 @@ 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,
@@ -2547,7 +2557,6 @@ static void wacom_remote_destroy_one(struct wacom *wacom, unsigned int index)

			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;
		}
	}
@@ -2632,6 +2641,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;

@@ -2647,17 +2659,19 @@ 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;
	struct wacom_remote_data data;
	ktime_t kt = ktime_get();
	struct wacom_remote_work_data remote_work_data;
	unsigned long flags;
	unsigned int count;
	u32 serial;
	u32 work_serial;
	int i;

	spin_lock_irqsave(&remote->remote_lock, flags);

	count = kfifo_out(&remote->remote_fifo, &data, sizeof(data));
	count = kfifo_out(&remote->remote_fifo, &remote_work_data,
			  sizeof(remote_work_data));

	if (count != sizeof(data)) {
	if (count != sizeof(remote_work_data)) {
		hid_err(wacom->hdev,
			"workitem triggered without status available\n");
		spin_unlock_irqrestore(&remote->remote_lock, flags);
@@ -2670,10 +2684,14 @@ static void wacom_remote_work(struct work_struct *work)
	spin_unlock_irqrestore(&remote->remote_lock, flags);

	for (i = 0; i < WACOM_MAX_REMOTES; i++) {
		serial = data.remote[i].serial;
		if (data.remote[i].connected) {
		work_serial = remote_work_data.remote[i].serial;
		if (work_serial) {

			if (remote->remotes[i].serial == serial) {
			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 == work_serial) {
				wacom_remote_attach_battery(wacom, i);
				continue;
			}
@@ -2681,7 +2699,7 @@ static void wacom_remote_work(struct work_struct *work)
			if (remote->remotes[i].serial)
				wacom_remote_destroy_one(wacom, i);

			wacom_remote_create_one(wacom, serial, i);
			wacom_remote_create_one(wacom, work_serial, i);

		} else if (remote->remotes[i].serial) {
			wacom_remote_destroy_one(wacom, i);
+3 −4
Original line number Diff line number Diff line
@@ -1134,6 +1134,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));
@@ -1196,22 +1197,20 @@ static void wacom_remote_status_irq(struct wacom_wac *wacom_wac, size_t len)
	struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac);
	unsigned char *data = wacom_wac->data;
	struct wacom_remote *remote = wacom->remote;
	struct wacom_remote_data remote_data;
	struct wacom_remote_work_data remote_data;
	unsigned long flags;
	int i, ret;

	if (data[0] != WACOM_REPORT_DEVICE_LIST)
		return;

	memset(&remote_data, 0, sizeof(struct wacom_remote_data));
	memset(&remote_data, 0, sizeof(struct wacom_remote_work_data));

	for (i = 0; i < WACOM_MAX_REMOTES; i++) {
		int j = i * 6;
		int serial = (data[j+6] << 16) + (data[j+5] << 8) + data[j+4];
		bool connected = data[j+2];

		remote_data.remote[i].serial = serial;
		remote_data.remote[i].connected = connected;
	}

	spin_lock_irqsave(&remote->remote_lock, flags);
+2 −2
Original line number Diff line number Diff line
@@ -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
@@ -327,10 +328,9 @@ struct hid_data {
	ktime_t time_delayed;
};

struct wacom_remote_data {
struct wacom_remote_work_data {
	struct {
		u32 serial;
		bool connected;
	} remote[WACOM_MAX_REMOTES];
};