a1b93e890d
Virtual machines often use an ACPI power button event to tell the machine to shut down gracefully. Provide an extremely lightweight "tiny power button" driver to handle this event by signaling init directly, rather than running a separate daemon (such as acpid or systemd-logind) that adds to startup time and VM image complexity. The kernel configuration defines the default signal to send init, and userspace can change this signal via a module parameter. Suggested-by: "Rafael J. Wysocki" <rafael@kernel.org> Signed-off-by: Josh Triplett <josh@joshtriplett.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
47 lines
1.3 KiB
C
47 lines
1.3 KiB
C
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
#include <linux/module.h>
|
|
#include <linux/sched/signal.h>
|
|
#include <linux/acpi.h>
|
|
#include <acpi/button.h>
|
|
|
|
ACPI_MODULE_NAME("tiny-power-button");
|
|
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 int acpi_noop_add_remove(struct acpi_device *device)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static void acpi_tiny_power_button_notify(struct acpi_device *device, u32 event)
|
|
{
|
|
kill_cad_pid(power_signal, 1);
|
|
}
|
|
|
|
static struct acpi_driver acpi_tiny_power_button_driver = {
|
|
.name = "tiny-power-button",
|
|
.class = "tiny-power-button",
|
|
.ids = tiny_power_button_device_ids,
|
|
.ops = {
|
|
.add = acpi_noop_add_remove,
|
|
.remove = acpi_noop_add_remove,
|
|
.notify = acpi_tiny_power_button_notify,
|
|
},
|
|
};
|
|
|
|
module_driver(acpi_tiny_power_button_driver,
|
|
acpi_bus_register_driver,
|
|
acpi_bus_unregister_driver);
|