hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/acpi/button.c
....@@ -1,22 +1,9 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * button.c - ACPI Button Driver
34 *
45 * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
56 * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
6
- *
7
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8
- *
9
- * This program is free software; you can redistribute it and/or modify
10
- * it under the terms of the GNU General Public License as published by
11
- * the Free Software Foundation; either version 2 of the License, or (at
12
- * your option) any later version.
13
- *
14
- * This program is distributed in the hope that it will be useful, but
15
- * WITHOUT ANY WARRANTY; without even the implied warranty of
16
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17
- * General Public License for more details.
18
- *
19
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
207 */
218
229 #define pr_fmt(fmt) "ACPI: button: " fmt
....@@ -37,29 +24,35 @@
3724 #define PREFIX "ACPI: "
3825
3926 #define ACPI_BUTTON_CLASS "button"
40
-#define ACPI_BUTTON_FILE_INFO "info"
4127 #define ACPI_BUTTON_FILE_STATE "state"
4228 #define ACPI_BUTTON_TYPE_UNKNOWN 0x00
4329 #define ACPI_BUTTON_NOTIFY_STATUS 0x80
4430
4531 #define ACPI_BUTTON_SUBCLASS_POWER "power"
46
-#define ACPI_BUTTON_HID_POWER "PNP0C0C"
4732 #define ACPI_BUTTON_DEVICE_NAME_POWER "Power Button"
4833 #define ACPI_BUTTON_TYPE_POWER 0x01
4934
5035 #define ACPI_BUTTON_SUBCLASS_SLEEP "sleep"
51
-#define ACPI_BUTTON_HID_SLEEP "PNP0C0E"
5236 #define ACPI_BUTTON_DEVICE_NAME_SLEEP "Sleep Button"
5337 #define ACPI_BUTTON_TYPE_SLEEP 0x03
5438
5539 #define ACPI_BUTTON_SUBCLASS_LID "lid"
56
-#define ACPI_BUTTON_HID_LID "PNP0C0D"
5740 #define ACPI_BUTTON_DEVICE_NAME_LID "Lid Switch"
5841 #define ACPI_BUTTON_TYPE_LID 0x05
5942
60
-#define ACPI_BUTTON_LID_INIT_IGNORE 0x00
61
-#define ACPI_BUTTON_LID_INIT_OPEN 0x01
62
-#define ACPI_BUTTON_LID_INIT_METHOD 0x02
43
+enum {
44
+ ACPI_BUTTON_LID_INIT_IGNORE,
45
+ ACPI_BUTTON_LID_INIT_OPEN,
46
+ ACPI_BUTTON_LID_INIT_METHOD,
47
+ ACPI_BUTTON_LID_INIT_DISABLED,
48
+};
49
+
50
+static const char * const lid_init_state_str[] = {
51
+ [ACPI_BUTTON_LID_INIT_IGNORE] = "ignore",
52
+ [ACPI_BUTTON_LID_INIT_OPEN] = "open",
53
+ [ACPI_BUTTON_LID_INIT_METHOD] = "method",
54
+ [ACPI_BUTTON_LID_INIT_DISABLED] = "disabled",
55
+};
6356
6457 #define _COMPONENT ACPI_BUTTON_COMPONENT
6558 ACPI_MODULE_NAME("button");
....@@ -78,18 +71,16 @@
7871 };
7972 MODULE_DEVICE_TABLE(acpi, button_device_ids);
8073
81
-/*
82
- * Some devices which don't even have a lid in anyway have a broken _LID
83
- * method (e.g. pointing to a floating gpio pin) causing spurious LID events.
84
- */
85
-static const struct dmi_system_id lid_blacklst[] = {
74
+/* Please keep this list sorted alphabetically by vendor and model */
75
+static const struct dmi_system_id dmi_lid_quirks[] = {
8676 {
87
- /* GP-electronic T701 */
77
+ /* GP-electronic T701, _LID method points to a floating GPIO */
8878 .matches = {
8979 DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
9080 DMI_MATCH(DMI_PRODUCT_NAME, "T701"),
9181 DMI_MATCH(DMI_BIOS_VERSION, "BYT70A.YNCHENG.WIN.007"),
9282 },
83
+ .driver_data = (void *)(long)ACPI_BUTTON_LID_INIT_DISABLED,
9384 },
9485 {
9586 /*
....@@ -163,9 +154,8 @@
163154 bool lid_state_initialized;
164155 };
165156
166
-static BLOCKING_NOTIFIER_HEAD(acpi_lid_notifier);
167157 static struct acpi_device *lid_device;
168
-static u8 lid_init_state = ACPI_BUTTON_LID_INIT_METHOD;
158
+static long lid_init_state = -1;
169159
170160 static unsigned long lid_report_interval __read_mostly = 500;
171161 module_param(lid_report_interval, ulong, 0644);
....@@ -193,7 +183,6 @@
193183 static int acpi_lid_notify_state(struct acpi_device *device, int state)
194184 {
195185 struct acpi_button *button = acpi_driver_data(device);
196
- int ret;
197186 ktime_t next_report;
198187 bool do_update;
199188
....@@ -270,18 +259,7 @@
270259 button->last_time = ktime_get();
271260 }
272261
273
- ret = blocking_notifier_call_chain(&acpi_lid_notifier, state, device);
274
- if (ret == NOTIFY_DONE)
275
- ret = blocking_notifier_call_chain(&acpi_lid_notifier, state,
276
- device);
277
- if (ret == NOTIFY_DONE || ret == NOTIFY_OK) {
278
- /*
279
- * It is also regarded as success if the notifier_chain
280
- * returns NOTIFY_OK or NOTIFY_DONE.
281
- */
282
- ret = 0;
283
- }
284
- return ret;
262
+ return 0;
285263 }
286264
287265 static int __maybe_unused acpi_button_state_seq_show(struct seq_file *seq,
....@@ -378,18 +356,6 @@
378356 /* --------------------------------------------------------------------------
379357 Driver Interface
380358 -------------------------------------------------------------------------- */
381
-int acpi_lid_notifier_register(struct notifier_block *nb)
382
-{
383
- return blocking_notifier_chain_register(&acpi_lid_notifier, nb);
384
-}
385
-EXPORT_SYMBOL(acpi_lid_notifier_register);
386
-
387
-int acpi_lid_notifier_unregister(struct notifier_block *nb)
388
-{
389
- return blocking_notifier_chain_unregister(&acpi_lid_notifier, nb);
390
-}
391
-EXPORT_SYMBOL(acpi_lid_notifier_unregister);
392
-
393359 int acpi_lid_open(void)
394360 {
395361 if (!lid_device)
....@@ -441,7 +407,7 @@
441407 switch (event) {
442408 case ACPI_FIXED_HARDWARE_EVENT:
443409 event = ACPI_BUTTON_NOTIFY_STATUS;
444
- /* fall through */
410
+ fallthrough;
445411 case ACPI_BUTTON_NOTIFY_STATUS:
446412 input = button->input;
447413 if (button->type == ACPI_BUTTON_TYPE_LID) {
....@@ -519,7 +485,8 @@
519485 char *name, *class;
520486 int error;
521487
522
- if (!strcmp(hid, ACPI_BUTTON_HID_LID) && dmi_check_system(lid_blacklst))
488
+ if (!strcmp(hid, ACPI_BUTTON_HID_LID) &&
489
+ lid_init_state == ACPI_BUTTON_LID_INIT_DISABLED)
523490 return -ENODEV;
524491
525492 button = kzalloc(sizeof(struct acpi_button), GFP_KERNEL);
....@@ -625,36 +592,30 @@
625592 static int param_set_lid_init_state(const char *val,
626593 const struct kernel_param *kp)
627594 {
628
- int result = 0;
595
+ int i;
629596
630
- if (!strncmp(val, "open", sizeof("open") - 1)) {
631
- lid_init_state = ACPI_BUTTON_LID_INIT_OPEN;
632
- pr_info("Notify initial lid state as open\n");
633
- } else if (!strncmp(val, "method", sizeof("method") - 1)) {
634
- lid_init_state = ACPI_BUTTON_LID_INIT_METHOD;
635
- pr_info("Notify initial lid state with _LID return value\n");
636
- } else if (!strncmp(val, "ignore", sizeof("ignore") - 1)) {
637
- lid_init_state = ACPI_BUTTON_LID_INIT_IGNORE;
638
- pr_info("Do not notify initial lid state\n");
639
- } else
640
- result = -EINVAL;
641
- return result;
597
+ i = sysfs_match_string(lid_init_state_str, val);
598
+ if (i < 0)
599
+ return i;
600
+
601
+ lid_init_state = i;
602
+ pr_info("Initial lid state set to '%s'\n", lid_init_state_str[i]);
603
+ return 0;
642604 }
643605
644
-static int param_get_lid_init_state(char *buffer,
645
- const struct kernel_param *kp)
606
+static int param_get_lid_init_state(char *buf, const struct kernel_param *kp)
646607 {
647
- switch (lid_init_state) {
648
- case ACPI_BUTTON_LID_INIT_OPEN:
649
- return sprintf(buffer, "open");
650
- case ACPI_BUTTON_LID_INIT_METHOD:
651
- return sprintf(buffer, "method");
652
- case ACPI_BUTTON_LID_INIT_IGNORE:
653
- return sprintf(buffer, "ignore");
654
- default:
655
- return sprintf(buffer, "invalid");
656
- }
657
- return 0;
608
+ int i, c = 0;
609
+
610
+ for (i = 0; i < ARRAY_SIZE(lid_init_state_str); i++)
611
+ if (i == lid_init_state)
612
+ c += sprintf(buf + c, "[%s] ", lid_init_state_str[i]);
613
+ else
614
+ c += sprintf(buf + c, "%s ", lid_init_state_str[i]);
615
+
616
+ buf[c - 1] = '\n'; /* Replace the final space with a newline */
617
+
618
+ return c;
658619 }
659620
660621 module_param_call(lid_init_state,
....@@ -664,6 +625,16 @@
664625
665626 static int acpi_button_register_driver(struct acpi_driver *driver)
666627 {
628
+ const struct dmi_system_id *dmi_id;
629
+
630
+ if (lid_init_state == -1) {
631
+ dmi_id = dmi_first_match(dmi_lid_quirks);
632
+ if (dmi_id)
633
+ lid_init_state = (long)dmi_id->driver_data;
634
+ else
635
+ lid_init_state = ACPI_BUTTON_LID_INIT_METHOD;
636
+ }
637
+
667638 /*
668639 * Modules such as nouveau.ko and i915.ko have a link time dependency
669640 * on acpi_lid_open(), and would therefore not be loadable on ACPI