ACPI: button: fix handling lid state changes when input device closed
commit5.4-rM2-2.2.x-imx-squashed21988a8e51
upstream. 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> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
parent
c75b77cb9f
commit
5e25b44cc2
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue