Skip to content

Commit

Permalink
ACPI: button: fix handling lid state changes when input device closed
Browse files Browse the repository at this point in the history
commit 21988a8 upstream.

The original intent of 84d3f6b was to delay evaluating lid state until
all drivers have been loaded, with input device being opened from userspace
serving as a signal for this condition. Let's ensure that state updates
happen even if userspace closed (or in the future inhibited) input device.

Note that if we go through suspend/resume cycle we assume the system has
been fully initialized even if LID input device has not been opened yet.

This has a side-effect of fixing access to input->users outside of
input->mutex protections by the way of eliminating said accesses and using
driver private flag.

Fixes: 84d3f6b ("ACPI / button: Delay acpi_lid_initialize_state() until first user space open")
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Cc: 4.15+ <stable@vger.kernel.org> # 4.15+
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
dtor authored and gregkh committed Nov 5, 2020
1 parent c75b77c commit 5e25b44
Showing 1 changed file with 7 additions and 6 deletions.
13 changes: 7 additions & 6 deletions drivers/acpi/button.c
Expand Up @@ -136,6 +136,7 @@ struct acpi_button {
int last_state;
ktime_t last_time;
bool suspended;
bool lid_state_initialized;
};

static BLOCKING_NOTIFIER_HEAD(acpi_lid_notifier);
Expand Down Expand Up @@ -391,6 +392,8 @@ static int acpi_lid_update_state(struct acpi_device *device,

static void acpi_lid_initialize_state(struct acpi_device *device)
{
struct acpi_button *button = acpi_driver_data(device);

switch (lid_init_state) {
case ACPI_BUTTON_LID_INIT_OPEN:
(void)acpi_lid_notify_state(device, 1);
Expand All @@ -402,13 +405,14 @@ static void acpi_lid_initialize_state(struct acpi_device *device)
default:
break;
}

button->lid_state_initialized = true;
}

static void acpi_button_notify(struct acpi_device *device, u32 event)
{
struct acpi_button *button = acpi_driver_data(device);
struct input_dev *input;
int users;

switch (event) {
case ACPI_FIXED_HARDWARE_EVENT:
Expand All @@ -417,10 +421,7 @@ static void acpi_button_notify(struct acpi_device *device, u32 event)
case ACPI_BUTTON_NOTIFY_STATUS:
input = button->input;
if (button->type == ACPI_BUTTON_TYPE_LID) {
mutex_lock(&button->input->mutex);
users = button->input->users;
mutex_unlock(&button->input->mutex);
if (users)
if (button->lid_state_initialized)
acpi_lid_update_state(device, true);
} else {
int keycode;
Expand Down Expand Up @@ -465,7 +466,7 @@ static int acpi_button_resume(struct device *dev)
struct acpi_button *button = acpi_driver_data(device);

button->suspended = false;
if (button->type == ACPI_BUTTON_TYPE_LID && button->input->users) {
if (button->type == ACPI_BUTTON_TYPE_LID) {
button->last_state = !!acpi_lid_evaluate_state(device);
button->last_time = ktime_get();
acpi_lid_initialize_state(device);
Expand Down

0 comments on commit 5e25b44

Please sign in to comment.