Skip to content

Commit

Permalink
HID: wacom: leds: actually release the LEDs on disconnect
Browse files Browse the repository at this point in the history
There is a bug (?) in devm_led_classdev_register() in which its increments
the refcount of the parent. If the parent is an input device, that means
the ref count never reaches 0 when devm_input_device_release() gets called.
This means that the LEDs and all the devres resources attached to the
input device are not released.

Manually force the release of the group so that the leds are released once
we are done using them.

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Acked-by: Ping Cheng <pingc@wacom.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
  • Loading branch information
Benjamin Tissoires authored and Jiri Kosina committed Aug 5, 2016
1 parent 97f5541 commit 589e506
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 1 deletion.
1 change: 1 addition & 0 deletions drivers/hid/wacom.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ struct wacom_group_leds {
u8 select; /* status led selector (0..3) */
struct wacom_led *leds;
unsigned int count;
struct device *dev;
};

struct wacom_battery {
Expand Down
27 changes: 26 additions & 1 deletion drivers/hid/wacom_sys.c
Original file line number Diff line number Diff line change
Expand Up @@ -1068,6 +1068,13 @@ static int wacom_led_register_one(struct device *dev, struct wacom *wacom,
return 0;
}

static void wacom_led_groups_release_one(void *data)
{
struct wacom_group_leds *group = data;

devres_release_group(group->dev, group);
}

static int wacom_led_groups_alloc_and_register_one(struct device *dev,
struct wacom *wacom,
int group_id, int count,
Expand Down Expand Up @@ -1098,7 +1105,25 @@ static int wacom_led_groups_alloc_and_register_one(struct device *dev,
goto err;
}

devres_remove_group(dev, &wacom->led.groups[group_id]);
wacom->led.groups[group_id].dev = dev;

devres_close_group(dev, &wacom->led.groups[group_id]);

/*
* There is a bug (?) in devm_led_classdev_register() in which its
* increments the refcount of the parent. If the parent is an input
* device, that means the ref count never reaches 0 when
* devm_input_device_release() gets called.
* This means that the LEDs are still there after disconnect.
* Manually force the release of the group so that the leds are released
* once we are done using them.
*/
error = devm_add_action_or_reset(&wacom->hdev->dev,
wacom_led_groups_release_one,
&wacom->led.groups[group_id]);
if (error)
return error;

return 0;

err:
Expand Down

0 comments on commit 589e506

Please sign in to comment.