mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 12:28:41 +08:00
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 <rafael.j.wysocki@intel.com> Reviewed-by: Michal Wilczynski <michal.wilczynski@intel.com>
This commit is contained in:
parent
858fd168a9
commit
0d51157dfa
@ -126,7 +126,6 @@ static const struct dmi_system_id dmi_lid_quirks[] = {
|
||||
|
||||
static int acpi_button_add(struct acpi_device *device);
|
||||
static void acpi_button_remove(struct acpi_device *device);
|
||||
static void acpi_button_notify(struct acpi_device *device, u32 event);
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int acpi_button_suspend(struct device *dev);
|
||||
@ -144,7 +143,6 @@ static struct acpi_driver acpi_button_driver = {
|
||||
.ops = {
|
||||
.add = acpi_button_add,
|
||||
.remove = acpi_button_remove,
|
||||
.notify = acpi_button_notify,
|
||||
},
|
||||
.drv.pm = &acpi_button_pm,
|
||||
};
|
||||
@ -400,45 +398,55 @@ static void acpi_lid_initialize_state(struct acpi_device *device)
|
||||
button->lid_state_initialized = true;
|
||||
}
|
||||
|
||||
static void acpi_button_notify(struct acpi_device *device, u32 event)
|
||||
static void acpi_button_notify(acpi_handle handle, u32 event, void *data)
|
||||
{
|
||||
struct acpi_button *button = acpi_driver_data(device);
|
||||
struct acpi_device *device = data;
|
||||
struct acpi_button *button;
|
||||
struct input_dev *input;
|
||||
int keycode;
|
||||
|
||||
switch (event) {
|
||||
case ACPI_FIXED_HARDWARE_EVENT:
|
||||
event = ACPI_BUTTON_NOTIFY_STATUS;
|
||||
fallthrough;
|
||||
case ACPI_BUTTON_NOTIFY_STATUS:
|
||||
input = button->input;
|
||||
if (button->type == ACPI_BUTTON_TYPE_LID) {
|
||||
if (button->lid_state_initialized)
|
||||
acpi_lid_update_state(device, true);
|
||||
} else {
|
||||
int keycode;
|
||||
|
||||
acpi_pm_wakeup_event(&device->dev);
|
||||
if (button->suspended)
|
||||
break;
|
||||
|
||||
keycode = test_bit(KEY_SLEEP, input->keybit) ?
|
||||
KEY_SLEEP : KEY_POWER;
|
||||
input_report_key(input, keycode, 1);
|
||||
input_sync(input);
|
||||
input_report_key(input, keycode, 0);
|
||||
input_sync(input);
|
||||
|
||||
acpi_bus_generate_netlink_event(
|
||||
device->pnp.device_class,
|
||||
dev_name(&device->dev),
|
||||
event, ++button->pushed);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (event != ACPI_BUTTON_NOTIFY_STATUS) {
|
||||
acpi_handle_debug(device->handle, "Unsupported event [0x%x]\n",
|
||||
event);
|
||||
break;
|
||||
return;
|
||||
}
|
||||
|
||||
button = acpi_driver_data(device);
|
||||
|
||||
if (button->type == ACPI_BUTTON_TYPE_LID) {
|
||||
if (button->lid_state_initialized)
|
||||
acpi_lid_update_state(device, true);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
acpi_pm_wakeup_event(&device->dev);
|
||||
|
||||
if (button->suspended)
|
||||
return;
|
||||
|
||||
input = button->input;
|
||||
keycode = test_bit(KEY_SLEEP, input->keybit) ? KEY_SLEEP : KEY_POWER;
|
||||
|
||||
input_report_key(input, keycode, 1);
|
||||
input_sync(input);
|
||||
input_report_key(input, keycode, 0);
|
||||
input_sync(input);
|
||||
|
||||
acpi_bus_generate_netlink_event(device->pnp.device_class,
|
||||
dev_name(&device->dev),
|
||||
event, ++button->pushed);
|
||||
}
|
||||
|
||||
static void acpi_button_notify_run(void *data)
|
||||
{
|
||||
acpi_button_notify(NULL, ACPI_BUTTON_NOTIFY_STATUS, data);
|
||||
}
|
||||
|
||||
static u32 acpi_button_event(void *data)
|
||||
{
|
||||
acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_button_notify_run, data);
|
||||
return ACPI_INTERRUPT_HANDLED;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
@ -483,8 +491,9 @@ static int acpi_button_add(struct acpi_device *device)
|
||||
struct acpi_button *button;
|
||||
struct input_dev *input;
|
||||
const char *hid = acpi_device_hid(device);
|
||||
acpi_status status;
|
||||
char *name, *class;
|
||||
int error;
|
||||
int error = 0;
|
||||
|
||||
if (!strcmp(hid, ACPI_BUTTON_HID_LID) &&
|
||||
lid_init_state == ACPI_BUTTON_LID_INIT_DISABLED)
|
||||
@ -526,12 +535,15 @@ static int acpi_button_add(struct acpi_device *device)
|
||||
} else {
|
||||
pr_info("Unsupported hid [%s]\n", hid);
|
||||
error = -ENODEV;
|
||||
goto err_free_input;
|
||||
}
|
||||
|
||||
error = acpi_button_add_fs(device);
|
||||
if (error)
|
||||
goto err_free_input;
|
||||
if (!error)
|
||||
error = acpi_button_add_fs(device);
|
||||
|
||||
if (error) {
|
||||
input_free_device(input);
|
||||
goto err_free_button;
|
||||
}
|
||||
|
||||
snprintf(button->phys, sizeof(button->phys), "%s/button/input0", hid);
|
||||
|
||||
@ -559,6 +571,30 @@ static int acpi_button_add(struct acpi_device *device)
|
||||
error = input_register_device(input);
|
||||
if (error)
|
||||
goto err_remove_fs;
|
||||
|
||||
switch (device->device_type) {
|
||||
case ACPI_BUS_TYPE_POWER_BUTTON:
|
||||
status = acpi_install_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
|
||||
acpi_button_event,
|
||||
device);
|
||||
break;
|
||||
case ACPI_BUS_TYPE_SLEEP_BUTTON:
|
||||
status = acpi_install_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
|
||||
acpi_button_event,
|
||||
device);
|
||||
break;
|
||||
default:
|
||||
status = acpi_install_notify_handler(device->handle,
|
||||
ACPI_DEVICE_NOTIFY,
|
||||
acpi_button_notify,
|
||||
device);
|
||||
break;
|
||||
}
|
||||
if (ACPI_FAILURE(status)) {
|
||||
error = -ENODEV;
|
||||
goto err_input_unregister;
|
||||
}
|
||||
|
||||
if (button->type == ACPI_BUTTON_TYPE_LID) {
|
||||
/*
|
||||
* 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)
|
||||
pr_info("%s [%s]\n", name, acpi_device_bid(device));
|
||||
return 0;
|
||||
|
||||
err_remove_fs:
|
||||
err_input_unregister:
|
||||
input_unregister_device(input);
|
||||
err_remove_fs:
|
||||
acpi_button_remove_fs(device);
|
||||
err_free_input:
|
||||
input_free_device(input);
|
||||
err_free_button:
|
||||
err_free_button:
|
||||
kfree(button);
|
||||
return error;
|
||||
}
|
||||
@ -584,6 +620,22 @@ static void acpi_button_remove(struct acpi_device *device)
|
||||
{
|
||||
struct acpi_button *button = acpi_driver_data(device);
|
||||
|
||||
switch (device->device_type) {
|
||||
case ACPI_BUS_TYPE_POWER_BUTTON:
|
||||
acpi_remove_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
|
||||
acpi_button_event);
|
||||
break;
|
||||
case ACPI_BUS_TYPE_SLEEP_BUTTON:
|
||||
acpi_remove_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
|
||||
acpi_button_event);
|
||||
break;
|
||||
default:
|
||||
acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
|
||||
acpi_button_notify);
|
||||
break;
|
||||
}
|
||||
acpi_os_wait_events_complete();
|
||||
|
||||
acpi_button_remove_fs(device);
|
||||
input_unregister_device(button->input);
|
||||
kfree(button);
|
||||
|
Loading…
Reference in New Issue
Block a user