mirror of
https://github.com/torvalds/linux.git
synced 2024-11-14 16:12:02 +00:00
ACPI: button: fix handling lid state changes when input device closed
The original intent of84d3f6b764
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:84d3f6b764
("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>
This commit is contained in:
parent
549738f15d
commit
21988a8e51
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user