Something went wrong. Try again.
Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
Something went wrong. Try again.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788// SPDX-License-Identifier: GPL-2.0-or-later#include <linux/acpi.h>#include <linux/module.h>#include <linux/platform_device.h>#include <linux/sched/signal.h>#include <acpi/button.h>
MODULE_AUTHOR("Josh Triplett");MODULE_DESCRIPTION("ACPI Tiny Power Button Driver");MODULE_LICENSE("GPL");
static int power_signal __read_mostly = CONFIG_ACPI_TINY_POWER_BUTTON_SIGNAL;module_param(power_signal, int, 0644);MODULE_PARM_DESC(power_signal, "Power button sends this signal to init");
static const struct acpi_device_id tiny_power_button_device_ids[] = { { ACPI_BUTTON_HID_POWER, 0 }, { ACPI_BUTTON_HID_POWERF, 0 }, { "", 0 },};MODULE_DEVICE_TABLE(acpi, tiny_power_button_device_ids);
static void acpi_tiny_power_button_notify(acpi_handle handle, u32 event, void *data){ kill_cad_pid(power_signal, 1);}
static void acpi_tiny_power_button_notify_run(void *not_used){ acpi_tiny_power_button_notify(NULL, ACPI_FIXED_HARDWARE_EVENT, NULL);}
static u32 acpi_tiny_power_button_event(void *not_used){ acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_tiny_power_button_notify_run, NULL); return ACPI_INTERRUPT_HANDLED;}
static int acpi_tiny_power_button_probe(struct platform_device *pdev){ struct acpi_device *device; acpi_status status;
device = ACPI_COMPANION(&pdev->dev); if (!device) return -ENODEV;
if (device->device_type == ACPI_BUS_TYPE_POWER_BUTTON) { status = acpi_install_fixed_event_handler(ACPI_EVENT_POWER_BUTTON, acpi_tiny_power_button_event, NULL); } else { status = acpi_install_notify_handler(device->handle, ACPI_DEVICE_NOTIFY, acpi_tiny_power_button_notify, NULL); } if (ACPI_FAILURE(status)) return -ENODEV;
return 0;}
static void acpi_tiny_power_button_remove(struct platform_device *pdev){ struct acpi_device *device = ACPI_COMPANION(&pdev->dev);
if (device->device_type == ACPI_BUS_TYPE_POWER_BUTTON) { acpi_remove_fixed_event_handler(ACPI_EVENT_POWER_BUTTON, acpi_tiny_power_button_event); } else { acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY, acpi_tiny_power_button_notify); } acpi_os_wait_events_complete();}
static struct platform_driver acpi_tiny_power_button_driver = { .probe = acpi_tiny_power_button_probe, .remove = acpi_tiny_power_button_remove, .driver = { .name = "acpi-tiny-power-button", .acpi_match_table = tiny_power_button_device_ids, },};
module_platform_driver(acpi_tiny_power_button_driver);