Skip to content

Commit 0d51157

Browse files
committed
ACPI: button: Eliminate the driver notify callback
Rework the ACPI button driver to install notify handlers or fixed event handlers for the devices it binds to by itself, reduce the indentation level in its notify handler routine and drop its notify callback. This will allow acpi_device_install_notify_handler() and acpi_device_remove_notify_handler() to be simplified going forward and it will allow the driver to use different notify handlers for the lid and for the power and sleep buttons. Signed-off-by: Rafael J. Wysocki <[email protected]> Reviewed-by: Michal Wilczynski <[email protected]>
1 parent 858fd16 commit 0d51157

File tree

1 file changed

+96
-44
lines changed

1 file changed

+96
-44
lines changed

drivers/acpi/button.c

Lines changed: 96 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,6 @@ static const struct dmi_system_id dmi_lid_quirks[] = {
126126

127127
static int acpi_button_add(struct acpi_device *device);
128128
static void acpi_button_remove(struct acpi_device *device);
129-
static void acpi_button_notify(struct acpi_device *device, u32 event);
130129

131130
#ifdef CONFIG_PM_SLEEP
132131
static int acpi_button_suspend(struct device *dev);
@@ -144,7 +143,6 @@ static struct acpi_driver acpi_button_driver = {
144143
.ops = {
145144
.add = acpi_button_add,
146145
.remove = acpi_button_remove,
147-
.notify = acpi_button_notify,
148146
},
149147
.drv.pm = &acpi_button_pm,
150148
};
@@ -400,45 +398,55 @@ static void acpi_lid_initialize_state(struct acpi_device *device)
400398
button->lid_state_initialized = true;
401399
}
402400

403-
static void acpi_button_notify(struct acpi_device *device, u32 event)
401+
static void acpi_button_notify(acpi_handle handle, u32 event, void *data)
404402
{
405-
struct acpi_button *button = acpi_driver_data(device);
403+
struct acpi_device *device = data;
404+
struct acpi_button *button;
406405
struct input_dev *input;
406+
int keycode;
407407

408-
switch (event) {
409-
case ACPI_FIXED_HARDWARE_EVENT:
410-
event = ACPI_BUTTON_NOTIFY_STATUS;
411-
fallthrough;
412-
case ACPI_BUTTON_NOTIFY_STATUS:
413-
input = button->input;
414-
if (button->type == ACPI_BUTTON_TYPE_LID) {
415-
if (button->lid_state_initialized)
416-
acpi_lid_update_state(device, true);
417-
} else {
418-
int keycode;
419-
420-
acpi_pm_wakeup_event(&device->dev);
421-
if (button->suspended)
422-
break;
423-
424-
keycode = test_bit(KEY_SLEEP, input->keybit) ?
425-
KEY_SLEEP : KEY_POWER;
426-
input_report_key(input, keycode, 1);
427-
input_sync(input);
428-
input_report_key(input, keycode, 0);
429-
input_sync(input);
430-
431-
acpi_bus_generate_netlink_event(
432-
device->pnp.device_class,
433-
dev_name(&device->dev),
434-
event, ++button->pushed);
435-
}
436-
break;
437-
default:
408+
if (event != ACPI_BUTTON_NOTIFY_STATUS) {
438409
acpi_handle_debug(device->handle, "Unsupported event [0x%x]\n",
439410
event);
440-
break;
411+
return;
441412
}
413+
414+
button = acpi_driver_data(device);
415+
416+
if (button->type == ACPI_BUTTON_TYPE_LID) {
417+
if (button->lid_state_initialized)
418+
acpi_lid_update_state(device, true);
419+
420+
return;
421+
}
422+
423+
acpi_pm_wakeup_event(&device->dev);
424+
425+
if (button->suspended)
426+
return;
427+
428+
input = button->input;
429+
keycode = test_bit(KEY_SLEEP, input->keybit) ? KEY_SLEEP : KEY_POWER;
430+
431+
input_report_key(input, keycode, 1);
432+
input_sync(input);
433+
input_report_key(input, keycode, 0);
434+
input_sync(input);
435+
436+
acpi_bus_generate_netlink_event(device->pnp.device_class,
437+
dev_name(&device->dev),
438+
event, ++button->pushed);
439+
}
440+
441+
static void acpi_button_notify_run(void *data)
442+
{
443+
acpi_button_notify(NULL, ACPI_BUTTON_NOTIFY_STATUS, data);
444+
}
445+
446+
static u32 acpi_button_event(void *data)
447+
{
448+
acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_button_notify_run, data);
449+
return ACPI_INTERRUPT_HANDLED;
442450
}
443451

444452
#ifdef CONFIG_PM_SLEEP
@@ -483,8 +491,9 @@ static int acpi_button_add(struct acpi_device *device)
483491
struct acpi_button *button;
484492
struct input_dev *input;
485493
const char *hid = acpi_device_hid(device);
494+
acpi_status status;
486495
char *name, *class;
487-
int error;
496+
int error = 0;
488497

489498
if (!strcmp(hid, ACPI_BUTTON_HID_LID) &&
490499
lid_init_state == ACPI_BUTTON_LID_INIT_DISABLED)
@@ -526,12 +535,15 @@ static int acpi_button_add(struct acpi_device *device)
526535
} else {
527536
pr_info("Unsupported hid [%s]\n", hid);
528537
error = -ENODEV;
529-
goto err_free_input;
530538
}
531539

532-
error = acpi_button_add_fs(device);
533-
if (error)
534-
goto err_free_input;
540+
if (!error)
541+
error = acpi_button_add_fs(device);
542+
543+
if (error) {
544+
input_free_device(input);
545+
goto err_free_button;
546+
}
535547

536548
snprintf(button->phys, sizeof(button->phys), "%s/button/input0", hid);
537549

@@ -559,6 +571,30 @@ static int acpi_button_add(struct acpi_device *device)
559571
error = input_register_device(input);
560572
if (error)
561573
goto err_remove_fs;
574+
575+
switch (device->device_type) {
576+
case ACPI_BUS_TYPE_POWER_BUTTON:
577+
status = acpi_install_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
578+
acpi_button_event,
579+
device);
580+
break;
581+
case ACPI_BUS_TYPE_SLEEP_BUTTON:
582+
status = acpi_install_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
583+
acpi_button_event,
584+
device);
585+
break;
586+
default:
587+
status = acpi_install_notify_handler(device->handle,
588+
ACPI_DEVICE_NOTIFY,
589+
acpi_button_notify,
590+
device);
591+
break;
592+
}
593+
if (ACPI_FAILURE(status)) {
594+
error = -ENODEV;
595+
goto err_input_unregister;
596+
}
597+
562598
if (button->type == ACPI_BUTTON_TYPE_LID) {
563599
/*
564600
* This assumes there's only one lid device, or if there are
@@ -571,11 +607,11 @@ static int acpi_button_add(struct acpi_device *device)
571607
pr_info("%s [%s]\n", name, acpi_device_bid(device));
572608
return 0;
573609

574-
err_remove_fs:
610+
err_input_unregister:
611+
input_unregister_device(input);
612+
err_remove_fs:
575613
acpi_button_remove_fs(device);
576-
err_free_input:
577-
input_free_device(input);
578-
err_free_button:
614+
err_free_button:
579615
kfree(button);
580616
return error;
581617
}
@@ -584,6 +620,22 @@ static void acpi_button_remove(struct acpi_device *device)
584620
{
585621
struct acpi_button *button = acpi_driver_data(device);
586622

623+
switch (device->device_type) {
624+
case ACPI_BUS_TYPE_POWER_BUTTON:
625+
acpi_remove_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
626+
acpi_button_event);
627+
break;
628+
case ACPI_BUS_TYPE_SLEEP_BUTTON:
629+
acpi_remove_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
630+
acpi_button_event);
631+
break;
632+
default:
633+
acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
634+
acpi_button_notify);
635+
break;
636+
}
637+
acpi_os_wait_events_complete();
638+
587639
acpi_button_remove_fs(device);
588640
input_unregister_device(button->input);
589641
kfree(button);

0 commit comments

Comments
 (0)