summaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/Kconfig24
-rw-r--r--drivers/acpi/Makefile1
-rw-r--r--drivers/acpi/ac.c25
-rw-r--r--drivers/acpi/acpi_video.c2
-rw-r--r--drivers/acpi/battery.c10
-rw-r--r--drivers/acpi/button.c3
-rw-r--r--drivers/acpi/osl.c2
-rw-r--r--drivers/acpi/proc.c14
-rw-r--r--drivers/acpi/tiny-power-button.c46
-rw-r--r--drivers/acpi/wakeup.c24
10 files changed, 107 insertions, 44 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index cc57bab146b5..ce2730d61a8f 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -190,6 +190,30 @@ config ACPI_BUTTON
To compile this driver as a module, choose M here:
the module will be called button.
+config ACPI_TINY_POWER_BUTTON
+ tristate "Tiny Power Button Driver"
+ depends on !ACPI_BUTTON
+ help
+ This driver provides a tiny alternative to the ACPI Button driver.
+ The tiny power button driver only handles the power button. Rather
+ than notifying userspace via the input layer or a netlink event, this
+ driver directly signals the init process to shut down.
+
+ This driver is particularly suitable for cloud and VM environments,
+ which use a simulated power button to initiate a controlled poweroff,
+ but which may not want to run a separate userspace daemon to process
+ input events.
+
+config ACPI_TINY_POWER_BUTTON_SIGNAL
+ int "Tiny Power Button Signal"
+ depends on ACPI_TINY_POWER_BUTTON
+ default 38
+ help
+ Default signal to send to init in response to the power button.
+
+ Likely values here include 38 (SIGRTMIN+4) to power off, or 2
+ (SIGINT) to simulate Ctrl+Alt+Del.
+
config ACPI_VIDEO
tristate "Video"
depends on X86 && BACKLIGHT_CLASS_DEVICE
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index 33fdaf67454e..e81e1ebbfb32 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -71,6 +71,7 @@ obj-$(CONFIG_ACPI_IPMI) += acpi_ipmi.o
obj-$(CONFIG_ACPI_AC) += ac.o
obj-$(CONFIG_ACPI_BUTTON) += button.o
+obj-$(CONFIG_ACPI_TINY_POWER_BUTTON) += tiny-power-button.o
obj-$(CONFIG_ACPI_FAN) += fan.o
obj-$(CONFIG_ACPI_VIDEO) += video.o
obj-$(CONFIG_ACPI_TAD) += acpi_tad.o
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c
index 829f37d36b9f..69d2db13886b 100644
--- a/drivers/acpi/ac.c
+++ b/drivers/acpi/ac.c
@@ -293,29 +293,30 @@ static int __init ac_do_not_check_pmic_quirk(const struct dmi_system_id *d)
return 0;
}
+/* Please keep this list alphabetically sorted */
static const struct dmi_system_id ac_dmi_table[] __initconst = {
{
- /* Thinkpad e530 */
- .callback = thinkpad_e530_quirk,
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
- DMI_MATCH(DMI_PRODUCT_NAME, "32597CG"),
+ /* ECS EF20EA, AXP288 PMIC but uses separate fuel-gauge */
+ .callback = ac_do_not_check_pmic_quirk,
+ .matches = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "EF20EA"),
},
},
{
- /* ECS EF20EA */
+ /* Lenovo Ideapad Miix 320, AXP288 PMIC, separate fuel-gauge */
.callback = ac_do_not_check_pmic_quirk,
.matches = {
- DMI_MATCH(DMI_PRODUCT_NAME, "EF20EA"),
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "80XF"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo MIIX 320-10ICR"),
},
},
{
- /* Lenovo Ideapad Miix 320 */
- .callback = ac_do_not_check_pmic_quirk,
+ /* Lenovo Thinkpad e530, see comment in acpi_ac_notify() */
+ .callback = thinkpad_e530_quirk,
.matches = {
- DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"),
- DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "80XF"),
- DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Lenovo MIIX 320-10ICR"),
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "32597CG"),
},
},
{},
diff --git a/drivers/acpi/acpi_video.c b/drivers/acpi/acpi_video.c
index 15c5b272e698..bc96457c9e25 100644
--- a/drivers/acpi/acpi_video.c
+++ b/drivers/acpi/acpi_video.c
@@ -943,7 +943,7 @@ acpi_video_init_brightness(struct acpi_video_device *device)
int i, max_level = 0;
unsigned long long level, level_old;
struct acpi_video_device_brightness *br = NULL;
- int result = -EINVAL;
+ int result;
result = acpi_video_get_levels(device->dev, &br, &max_level);
if (result)
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index 111a407dcc77..366c389175d8 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -1365,19 +1365,19 @@ static const struct dmi_system_id bat_dmi_table[] __initconst = {
},
},
{
- /* ECS EF20EA */
+ /* ECS EF20EA, AXP288 PMIC but uses separate fuel-gauge */
.callback = battery_do_not_check_pmic_quirk,
.matches = {
DMI_MATCH(DMI_PRODUCT_NAME, "EF20EA"),
},
},
{
- /* Lenovo Ideapad Miix 320 */
+ /* Lenovo Ideapad Miix 320, AXP288 PMIC, separate fuel-gauge */
.callback = battery_do_not_check_pmic_quirk,
.matches = {
- DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"),
- DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "80XF"),
- DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Lenovo MIIX 320-10ICR"),
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "80XF"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo MIIX 320-10ICR"),
},
},
{},
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index f6925f16c4a2..00112cf15322 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -30,17 +30,14 @@
#define ACPI_BUTTON_NOTIFY_STATUS 0x80
#define ACPI_BUTTON_SUBCLASS_POWER "power"
-#define ACPI_BUTTON_HID_POWER "PNP0C0C"
#define ACPI_BUTTON_DEVICE_NAME_POWER "Power Button"
#define ACPI_BUTTON_TYPE_POWER 0x01
#define ACPI_BUTTON_SUBCLASS_SLEEP "sleep"
-#define ACPI_BUTTON_HID_SLEEP "PNP0C0E"
#define ACPI_BUTTON_DEVICE_NAME_SLEEP "Sleep Button"
#define ACPI_BUTTON_TYPE_SLEEP 0x03
#define ACPI_BUTTON_SUBCLASS_LID "lid"
-#define ACPI_BUTTON_HID_LID "PNP0C0D"
#define ACPI_BUTTON_DEVICE_NAME_LID "Lid Switch"
#define ACPI_BUTTON_TYPE_LID 0x05
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 41168c027a5a..762c5d50b8fe 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -1598,6 +1598,7 @@ void acpi_os_delete_lock(acpi_spinlock handle)
*/
acpi_cpu_flags acpi_os_acquire_lock(acpi_spinlock lockp)
+ __acquires(lockp)
{
acpi_cpu_flags flags;
spin_lock_irqsave(lockp, flags);
@@ -1609,6 +1610,7 @@ acpi_cpu_flags acpi_os_acquire_lock(acpi_spinlock lockp)
*/
void acpi_os_release_lock(acpi_spinlock lockp, acpi_cpu_flags flags)
+ __releases(lockp)
{
spin_unlock_irqrestore(lockp, flags);
}
diff --git a/drivers/acpi/proc.c b/drivers/acpi/proc.c
index 0e62ef265ce4..7892980b3ce4 100644
--- a/drivers/acpi/proc.c
+++ b/drivers/acpi/proc.c
@@ -22,14 +22,13 @@ ACPI_MODULE_NAME("sleep")
static int
acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset)
{
- struct list_head *node, *next;
+ struct acpi_device *dev, *tmp;
seq_printf(seq, "Device\tS-state\t Status Sysfs node\n");
mutex_lock(&acpi_device_lock);
- list_for_each_safe(node, next, &acpi_wakeup_device_list) {
- struct acpi_device *dev =
- container_of(node, struct acpi_device, wakeup_list);
+ list_for_each_entry_safe(dev, tmp, &acpi_wakeup_device_list,
+ wakeup_list) {
struct acpi_device_physical_node *entry;
if (!dev->wakeup.flags.valid)
@@ -96,7 +95,7 @@ acpi_system_write_wakeup_device(struct file *file,
const char __user * buffer,
size_t count, loff_t * ppos)
{
- struct list_head *node, *next;
+ struct acpi_device *dev, *tmp;
char strbuf[5];
char str[5] = "";
@@ -109,9 +108,8 @@ acpi_system_write_wakeup_device(struct file *file,
sscanf(strbuf, "%s", str);
mutex_lock(&acpi_device_lock);
- list_for_each_safe(node, next, &acpi_wakeup_device_list) {
- struct acpi_device *dev =
- container_of(node, struct acpi_device, wakeup_list);
+ list_for_each_entry_safe(dev, tmp, &acpi_wakeup_device_list,
+ wakeup_list) {
if (!dev->wakeup.flags.valid)
continue;
diff --git a/drivers/acpi/tiny-power-button.c b/drivers/acpi/tiny-power-button.c
new file mode 100644
index 000000000000..6273d73c0b59
--- /dev/null
+++ b/drivers/acpi/tiny-power-button.c
@@ -0,0 +1,46 @@
+// 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);
diff --git a/drivers/acpi/wakeup.c b/drivers/acpi/wakeup.c
index 9614126bf56e..c28244df56a5 100644
--- a/drivers/acpi/wakeup.c
+++ b/drivers/acpi/wakeup.c
@@ -30,12 +30,10 @@ ACPI_MODULE_NAME("wakeup_devices")
*/
void acpi_enable_wakeup_devices(u8 sleep_state)
{
- struct list_head *node, *next;
-
- list_for_each_safe(node, next, &acpi_wakeup_device_list) {
- struct acpi_device *dev =
- container_of(node, struct acpi_device, wakeup_list);
+ struct acpi_device *dev, *tmp;
+ list_for_each_entry_safe(dev, tmp, &acpi_wakeup_device_list,
+ wakeup_list) {
if (!dev->wakeup.flags.valid
|| sleep_state > (u32) dev->wakeup.sleep_state
|| !(device_may_wakeup(&dev->dev)
@@ -57,12 +55,10 @@ void acpi_enable_wakeup_devices(u8 sleep_state)
*/
void acpi_disable_wakeup_devices(u8 sleep_state)
{
- struct list_head *node, *next;
-
- list_for_each_safe(node, next, &acpi_wakeup_device_list) {
- struct acpi_device *dev =
- container_of(node, struct acpi_device, wakeup_list);
+ struct acpi_device *dev, *tmp;
+ list_for_each_entry_safe(dev, tmp, &acpi_wakeup_device_list,
+ wakeup_list) {
if (!dev->wakeup.flags.valid
|| sleep_state > (u32) dev->wakeup.sleep_state
|| !(device_may_wakeup(&dev->dev)
@@ -79,13 +75,11 @@ void acpi_disable_wakeup_devices(u8 sleep_state)
int __init acpi_wakeup_device_init(void)
{
- struct list_head *node, *next;
+ struct acpi_device *dev, *tmp;
mutex_lock(&acpi_device_lock);
- list_for_each_safe(node, next, &acpi_wakeup_device_list) {
- struct acpi_device *dev = container_of(node,
- struct acpi_device,
- wakeup_list);
+ list_for_each_entry_safe(dev, tmp, &acpi_wakeup_device_list,
+ wakeup_list) {
if (device_can_wakeup(&dev->dev)) {
/* Button GPEs are supposed to be always enabled. */
acpi_enable_gpe(dev->wakeup.gpe_device,