Commit 21988a8e authored by dmitry.torokhov@gmail.com's avatar dmitry.torokhov@gmail.com Committed by Rafael J. Wysocki

ACPI: button: fix handling lid state changes when input device closed

The original intent of 84d3f6b7 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: 84d3f6b7 ("ACPI / button: Delay acpi_lid_initialize_state() until first user space open")
Signed-off-by: default avatarDmitry Torokhov <dmitry.torokhov@gmail.com>
Reviewed-by: default avatarHans de Goede <hdegoede@redhat.com>
Cc: 4.15+ <stable@vger.kernel.org> # 4.15+
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent 549738f1
......@@ -153,6 +153,7 @@ struct acpi_button {
int last_state;
ktime_t last_time;
bool suspended;
bool lid_state_initialized;
};
static struct acpi_device *lid_device;
......@@ -383,6 +384,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);
......@@ -394,13 +397,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:
......@@ -409,10 +413,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;
......@@ -457,7 +458,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);
......
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