1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * button.c - ACPI Button Driver 4 * 5 * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com> 6 * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> 7 */ 8 9 #define pr_fmt(fmt) "ACPI: button: " fmt 10 11 #include <linux/compiler.h> 12 #include <linux/kernel.h> 13 #include <linux/module.h> 14 #include <linux/init.h> 15 #include <linux/types.h> 16 #include <linux/proc_fs.h> 17 #include <linux/seq_file.h> 18 #include <linux/input.h> 19 #include <linux/slab.h> 20 #include <linux/acpi.h> 21 #include <linux/dmi.h> 22 #include <acpi/button.h> 23 24 #define PREFIX "ACPI: " 25 26 #define ACPI_BUTTON_CLASS "button" 27 #define ACPI_BUTTON_FILE_INFO "info" 28 #define ACPI_BUTTON_FILE_STATE "state" 29 #define ACPI_BUTTON_TYPE_UNKNOWN 0x00 30 #define ACPI_BUTTON_NOTIFY_STATUS 0x80 31 32 #define ACPI_BUTTON_SUBCLASS_POWER "power" 33 #define ACPI_BUTTON_HID_POWER "PNP0C0C" 34 #define ACPI_BUTTON_DEVICE_NAME_POWER "Power Button" 35 #define ACPI_BUTTON_TYPE_POWER 0x01 36 37 #define ACPI_BUTTON_SUBCLASS_SLEEP "sleep" 38 #define ACPI_BUTTON_HID_SLEEP "PNP0C0E" 39 #define ACPI_BUTTON_DEVICE_NAME_SLEEP "Sleep Button" 40 #define ACPI_BUTTON_TYPE_SLEEP 0x03 41 42 #define ACPI_BUTTON_SUBCLASS_LID "lid" 43 #define ACPI_BUTTON_HID_LID "PNP0C0D" 44 #define ACPI_BUTTON_DEVICE_NAME_LID "Lid Switch" 45 #define ACPI_BUTTON_TYPE_LID 0x05 46 47 enum { 48 ACPI_BUTTON_LID_INIT_IGNORE, 49 ACPI_BUTTON_LID_INIT_OPEN, 50 ACPI_BUTTON_LID_INIT_METHOD, 51 ACPI_BUTTON_LID_INIT_DISABLED, 52 }; 53 54 static const char * const lid_init_state_str[] = { 55 [ACPI_BUTTON_LID_INIT_IGNORE] = "ignore", 56 [ACPI_BUTTON_LID_INIT_OPEN] = "open", 57 [ACPI_BUTTON_LID_INIT_METHOD] = "method", 58 [ACPI_BUTTON_LID_INIT_DISABLED] = "disabled", 59 }; 60 61 #define _COMPONENT ACPI_BUTTON_COMPONENT 62 ACPI_MODULE_NAME("button"); 63 64 MODULE_AUTHOR("Paul Diefenbaugh"); 65 MODULE_DESCRIPTION("ACPI Button Driver"); 66 MODULE_LICENSE("GPL"); 67 68 static const struct acpi_device_id button_device_ids[] = { 69 {ACPI_BUTTON_HID_LID, 0}, 70 {ACPI_BUTTON_HID_SLEEP, 0}, 71 {ACPI_BUTTON_HID_SLEEPF, 0}, 72 {ACPI_BUTTON_HID_POWER, 0}, 73 {ACPI_BUTTON_HID_POWERF, 0}, 74 {"", 0}, 75 }; 76 MODULE_DEVICE_TABLE(acpi, button_device_ids); 77 78 /* Please keep this list sorted alphabetically by vendor and model */ 79 static const struct dmi_system_id dmi_lid_quirks[] = { 80 { 81 /* 82 * Acer Switch 10 SW5-012. _LID method messes with home and 83 * power button GPIO IRQ settings causing an interrupt storm on 84 * both GPIOs. This is unfixable without a DSDT override, so we 85 * have to disable the lid-switch functionality altogether :| 86 */ 87 .matches = { 88 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 89 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW5-012"), 90 }, 91 .driver_data = (void *)(long)ACPI_BUTTON_LID_INIT_DISABLED, 92 }, 93 { 94 /* 95 * Asus T200TA, _LID keeps reporting closed after every second 96 * openening of the lid. Causing immediate re-suspend after 97 * opening every other open. Using LID_INIT_OPEN fixes this. 98 */ 99 .matches = { 100 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 101 DMI_MATCH(DMI_PRODUCT_NAME, "T200TA"), 102 }, 103 .driver_data = (void *)(long)ACPI_BUTTON_LID_INIT_OPEN, 104 }, 105 { 106 /* GP-electronic T701, _LID method points to a floating GPIO */ 107 .matches = { 108 DMI_MATCH(DMI_SYS_VENDOR, "Insyde"), 109 DMI_MATCH(DMI_PRODUCT_NAME, "T701"), 110 DMI_MATCH(DMI_BIOS_VERSION, "BYT70A.YNCHENG.WIN.007"), 111 }, 112 .driver_data = (void *)(long)ACPI_BUTTON_LID_INIT_DISABLED, 113 }, 114 { 115 /* 116 * Medion Akoya E2215T, notification of the LID device only 117 * happens on close, not on open and _LID always returns closed. 118 */ 119 .matches = { 120 DMI_MATCH(DMI_SYS_VENDOR, "MEDION"), 121 DMI_MATCH(DMI_PRODUCT_NAME, "E2215T MD60198"), 122 }, 123 .driver_data = (void *)(long)ACPI_BUTTON_LID_INIT_OPEN, 124 }, 125 {} 126 }; 127 128 static int acpi_button_add(struct acpi_device *device); 129 static int acpi_button_remove(struct acpi_device *device); 130 static void acpi_button_notify(struct acpi_device *device, u32 event); 131 132 #ifdef CONFIG_PM_SLEEP 133 static int acpi_button_suspend(struct device *dev); 134 static int acpi_button_resume(struct device *dev); 135 #else 136 #define acpi_button_suspend NULL 137 #define acpi_button_resume NULL 138 #endif 139 static SIMPLE_DEV_PM_OPS(acpi_button_pm, acpi_button_suspend, acpi_button_resume); 140 141 static struct acpi_driver acpi_button_driver = { 142 .name = "button", 143 .class = ACPI_BUTTON_CLASS, 144 .ids = button_device_ids, 145 .ops = { 146 .add = acpi_button_add, 147 .remove = acpi_button_remove, 148 .notify = acpi_button_notify, 149 }, 150 .drv.pm = &acpi_button_pm, 151 }; 152 153 struct acpi_button { 154 unsigned int type; 155 struct input_dev *input; 156 char phys[32]; /* for input device */ 157 unsigned long pushed; 158 int last_state; 159 ktime_t last_time; 160 bool suspended; 161 }; 162 163 static struct acpi_device *lid_device; 164 static long lid_init_state = -1; 165 166 static unsigned long lid_report_interval __read_mostly = 500; 167 module_param(lid_report_interval, ulong, 0644); 168 MODULE_PARM_DESC(lid_report_interval, "Interval (ms) between lid key events"); 169 170 /* -------------------------------------------------------------------------- 171 FS Interface (/proc) 172 -------------------------------------------------------------------------- */ 173 174 static struct proc_dir_entry *acpi_button_dir; 175 static struct proc_dir_entry *acpi_lid_dir; 176 177 static int acpi_lid_evaluate_state(struct acpi_device *device) 178 { 179 unsigned long long lid_state; 180 acpi_status status; 181 182 status = acpi_evaluate_integer(device->handle, "_LID", NULL, &lid_state); 183 if (ACPI_FAILURE(status)) 184 return -ENODEV; 185 186 return lid_state ? 1 : 0; 187 } 188 189 static int acpi_lid_notify_state(struct acpi_device *device, int state) 190 { 191 struct acpi_button *button = acpi_driver_data(device); 192 ktime_t next_report; 193 bool do_update; 194 195 /* 196 * In lid_init_state=ignore mode, if user opens/closes lid 197 * frequently with "open" missing, and "last_time" is also updated 198 * frequently, "close" cannot be delivered to the userspace. 199 * So "last_time" is only updated after a timeout or an actual 200 * switch. 201 */ 202 if (lid_init_state != ACPI_BUTTON_LID_INIT_IGNORE || 203 button->last_state != !!state) 204 do_update = true; 205 else 206 do_update = false; 207 208 next_report = ktime_add(button->last_time, 209 ms_to_ktime(lid_report_interval)); 210 if (button->last_state == !!state && 211 ktime_after(ktime_get(), next_report)) { 212 /* Complain the buggy firmware */ 213 pr_warn_once("The lid device is not compliant to SW_LID.\n"); 214 215 /* 216 * Send the unreliable complement switch event: 217 * 218 * On most platforms, the lid device is reliable. However 219 * there are exceptions: 220 * 1. Platforms returning initial lid state as "close" by 221 * default after booting/resuming: 222 * https://bugzilla.kernel.org/show_bug.cgi?id=89211 223 * https://bugzilla.kernel.org/show_bug.cgi?id=106151 224 * 2. Platforms never reporting "open" events: 225 * https://bugzilla.kernel.org/show_bug.cgi?id=106941 226 * On these buggy platforms, the usage model of the ACPI 227 * lid device actually is: 228 * 1. The initial returning value of _LID may not be 229 * reliable. 230 * 2. The open event may not be reliable. 231 * 3. The close event is reliable. 232 * 233 * But SW_LID is typed as input switch event, the input 234 * layer checks if the event is redundant. Hence if the 235 * state is not switched, the userspace cannot see this 236 * platform triggered reliable event. By inserting a 237 * complement switch event, it then is guaranteed that the 238 * platform triggered reliable one can always be seen by 239 * the userspace. 240 */ 241 if (lid_init_state == ACPI_BUTTON_LID_INIT_IGNORE) { 242 do_update = true; 243 /* 244 * Do generate complement switch event for "close" 245 * as "close" is reliable and wrong "open" won't 246 * trigger unexpected behaviors. 247 * Do not generate complement switch event for 248 * "open" as "open" is not reliable and wrong 249 * "close" will trigger unexpected behaviors. 250 */ 251 if (!state) { 252 input_report_switch(button->input, 253 SW_LID, state); 254 input_sync(button->input); 255 } 256 } 257 } 258 /* Send the platform triggered reliable event */ 259 if (do_update) { 260 acpi_handle_debug(device->handle, "ACPI LID %s\n", 261 state ? "open" : "closed"); 262 input_report_switch(button->input, SW_LID, !state); 263 input_sync(button->input); 264 button->last_state = !!state; 265 button->last_time = ktime_get(); 266 } 267 268 return 0; 269 } 270 271 static int __maybe_unused acpi_button_state_seq_show(struct seq_file *seq, 272 void *offset) 273 { 274 struct acpi_device *device = seq->private; 275 int state; 276 277 state = acpi_lid_evaluate_state(device); 278 seq_printf(seq, "state: %s\n", 279 state < 0 ? "unsupported" : (state ? "open" : "closed")); 280 return 0; 281 } 282 283 static int acpi_button_add_fs(struct acpi_device *device) 284 { 285 struct acpi_button *button = acpi_driver_data(device); 286 struct proc_dir_entry *entry = NULL; 287 int ret = 0; 288 289 /* procfs I/F for ACPI lid device only */ 290 if (button->type != ACPI_BUTTON_TYPE_LID) 291 return 0; 292 293 if (acpi_button_dir || acpi_lid_dir) { 294 printk(KERN_ERR PREFIX "More than one Lid device found!\n"); 295 return -EEXIST; 296 } 297 298 /* create /proc/acpi/button */ 299 acpi_button_dir = proc_mkdir(ACPI_BUTTON_CLASS, acpi_root_dir); 300 if (!acpi_button_dir) 301 return -ENODEV; 302 303 /* create /proc/acpi/button/lid */ 304 acpi_lid_dir = proc_mkdir(ACPI_BUTTON_SUBCLASS_LID, acpi_button_dir); 305 if (!acpi_lid_dir) { 306 ret = -ENODEV; 307 goto remove_button_dir; 308 } 309 310 /* create /proc/acpi/button/lid/LID/ */ 311 acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), acpi_lid_dir); 312 if (!acpi_device_dir(device)) { 313 ret = -ENODEV; 314 goto remove_lid_dir; 315 } 316 317 /* create /proc/acpi/button/lid/LID/state */ 318 entry = proc_create_single_data(ACPI_BUTTON_FILE_STATE, S_IRUGO, 319 acpi_device_dir(device), acpi_button_state_seq_show, 320 device); 321 if (!entry) { 322 ret = -ENODEV; 323 goto remove_dev_dir; 324 } 325 326 done: 327 return ret; 328 329 remove_dev_dir: 330 remove_proc_entry(acpi_device_bid(device), 331 acpi_lid_dir); 332 acpi_device_dir(device) = NULL; 333 remove_lid_dir: 334 remove_proc_entry(ACPI_BUTTON_SUBCLASS_LID, acpi_button_dir); 335 acpi_lid_dir = NULL; 336 remove_button_dir: 337 remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir); 338 acpi_button_dir = NULL; 339 goto done; 340 } 341 342 static int acpi_button_remove_fs(struct acpi_device *device) 343 { 344 struct acpi_button *button = acpi_driver_data(device); 345 346 if (button->type != ACPI_BUTTON_TYPE_LID) 347 return 0; 348 349 remove_proc_entry(ACPI_BUTTON_FILE_STATE, 350 acpi_device_dir(device)); 351 remove_proc_entry(acpi_device_bid(device), 352 acpi_lid_dir); 353 acpi_device_dir(device) = NULL; 354 remove_proc_entry(ACPI_BUTTON_SUBCLASS_LID, acpi_button_dir); 355 acpi_lid_dir = NULL; 356 remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir); 357 acpi_button_dir = NULL; 358 359 return 0; 360 } 361 362 /* -------------------------------------------------------------------------- 363 Driver Interface 364 -------------------------------------------------------------------------- */ 365 int acpi_lid_open(void) 366 { 367 if (!lid_device) 368 return -ENODEV; 369 370 return acpi_lid_evaluate_state(lid_device); 371 } 372 EXPORT_SYMBOL(acpi_lid_open); 373 374 static int acpi_lid_update_state(struct acpi_device *device, 375 bool signal_wakeup) 376 { 377 int state; 378 379 state = acpi_lid_evaluate_state(device); 380 if (state < 0) 381 return state; 382 383 if (state && signal_wakeup) 384 acpi_pm_wakeup_event(&device->dev); 385 386 return acpi_lid_notify_state(device, state); 387 } 388 389 static void acpi_lid_initialize_state(struct acpi_device *device) 390 { 391 switch (lid_init_state) { 392 case ACPI_BUTTON_LID_INIT_OPEN: 393 (void)acpi_lid_notify_state(device, 1); 394 break; 395 case ACPI_BUTTON_LID_INIT_METHOD: 396 (void)acpi_lid_update_state(device, false); 397 break; 398 case ACPI_BUTTON_LID_INIT_IGNORE: 399 default: 400 break; 401 } 402 } 403 404 static void acpi_button_notify(struct acpi_device *device, u32 event) 405 { 406 struct acpi_button *button = acpi_driver_data(device); 407 struct input_dev *input; 408 int users; 409 410 switch (event) { 411 case ACPI_FIXED_HARDWARE_EVENT: 412 event = ACPI_BUTTON_NOTIFY_STATUS; 413 /* fall through */ 414 case ACPI_BUTTON_NOTIFY_STATUS: 415 input = button->input; 416 if (button->type == ACPI_BUTTON_TYPE_LID) { 417 mutex_lock(&button->input->mutex); 418 users = button->input->users; 419 mutex_unlock(&button->input->mutex); 420 if (users) 421 acpi_lid_update_state(device, true); 422 } else { 423 int keycode; 424 425 acpi_pm_wakeup_event(&device->dev); 426 if (button->suspended) 427 break; 428 429 keycode = test_bit(KEY_SLEEP, input->keybit) ? 430 KEY_SLEEP : KEY_POWER; 431 input_report_key(input, keycode, 1); 432 input_sync(input); 433 input_report_key(input, keycode, 0); 434 input_sync(input); 435 436 acpi_bus_generate_netlink_event( 437 device->pnp.device_class, 438 dev_name(&device->dev), 439 event, ++button->pushed); 440 } 441 break; 442 default: 443 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 444 "Unsupported event [0x%x]\n", event)); 445 break; 446 } 447 } 448 449 #ifdef CONFIG_PM_SLEEP 450 static int acpi_button_suspend(struct device *dev) 451 { 452 struct acpi_device *device = to_acpi_device(dev); 453 struct acpi_button *button = acpi_driver_data(device); 454 455 button->suspended = true; 456 return 0; 457 } 458 459 static int acpi_button_resume(struct device *dev) 460 { 461 struct acpi_device *device = to_acpi_device(dev); 462 struct acpi_button *button = acpi_driver_data(device); 463 464 button->suspended = false; 465 if (button->type == ACPI_BUTTON_TYPE_LID && button->input->users) { 466 button->last_state = !!acpi_lid_evaluate_state(device); 467 button->last_time = ktime_get(); 468 acpi_lid_initialize_state(device); 469 } 470 return 0; 471 } 472 #endif 473 474 static int acpi_lid_input_open(struct input_dev *input) 475 { 476 struct acpi_device *device = input_get_drvdata(input); 477 struct acpi_button *button = acpi_driver_data(device); 478 479 button->last_state = !!acpi_lid_evaluate_state(device); 480 button->last_time = ktime_get(); 481 acpi_lid_initialize_state(device); 482 483 return 0; 484 } 485 486 static int acpi_button_add(struct acpi_device *device) 487 { 488 struct acpi_button *button; 489 struct input_dev *input; 490 const char *hid = acpi_device_hid(device); 491 char *name, *class; 492 int error; 493 494 if (!strcmp(hid, ACPI_BUTTON_HID_LID) && 495 lid_init_state == ACPI_BUTTON_LID_INIT_DISABLED) 496 return -ENODEV; 497 498 button = kzalloc(sizeof(struct acpi_button), GFP_KERNEL); 499 if (!button) 500 return -ENOMEM; 501 502 device->driver_data = button; 503 504 button->input = input = input_allocate_device(); 505 if (!input) { 506 error = -ENOMEM; 507 goto err_free_button; 508 } 509 510 name = acpi_device_name(device); 511 class = acpi_device_class(device); 512 513 if (!strcmp(hid, ACPI_BUTTON_HID_POWER) || 514 !strcmp(hid, ACPI_BUTTON_HID_POWERF)) { 515 button->type = ACPI_BUTTON_TYPE_POWER; 516 strcpy(name, ACPI_BUTTON_DEVICE_NAME_POWER); 517 sprintf(class, "%s/%s", 518 ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_POWER); 519 } else if (!strcmp(hid, ACPI_BUTTON_HID_SLEEP) || 520 !strcmp(hid, ACPI_BUTTON_HID_SLEEPF)) { 521 button->type = ACPI_BUTTON_TYPE_SLEEP; 522 strcpy(name, ACPI_BUTTON_DEVICE_NAME_SLEEP); 523 sprintf(class, "%s/%s", 524 ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_SLEEP); 525 } else if (!strcmp(hid, ACPI_BUTTON_HID_LID)) { 526 button->type = ACPI_BUTTON_TYPE_LID; 527 strcpy(name, ACPI_BUTTON_DEVICE_NAME_LID); 528 sprintf(class, "%s/%s", 529 ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_LID); 530 input->open = acpi_lid_input_open; 531 } else { 532 printk(KERN_ERR PREFIX "Unsupported hid [%s]\n", hid); 533 error = -ENODEV; 534 goto err_free_input; 535 } 536 537 error = acpi_button_add_fs(device); 538 if (error) 539 goto err_free_input; 540 541 snprintf(button->phys, sizeof(button->phys), "%s/button/input0", hid); 542 543 input->name = name; 544 input->phys = button->phys; 545 input->id.bustype = BUS_HOST; 546 input->id.product = button->type; 547 input->dev.parent = &device->dev; 548 549 switch (button->type) { 550 case ACPI_BUTTON_TYPE_POWER: 551 input_set_capability(input, EV_KEY, KEY_POWER); 552 break; 553 554 case ACPI_BUTTON_TYPE_SLEEP: 555 input_set_capability(input, EV_KEY, KEY_SLEEP); 556 break; 557 558 case ACPI_BUTTON_TYPE_LID: 559 input_set_capability(input, EV_SW, SW_LID); 560 break; 561 } 562 563 input_set_drvdata(input, device); 564 error = input_register_device(input); 565 if (error) 566 goto err_remove_fs; 567 if (button->type == ACPI_BUTTON_TYPE_LID) { 568 /* 569 * This assumes there's only one lid device, or if there are 570 * more we only care about the last one... 571 */ 572 lid_device = device; 573 } 574 575 device_init_wakeup(&device->dev, true); 576 printk(KERN_INFO PREFIX "%s [%s]\n", name, acpi_device_bid(device)); 577 return 0; 578 579 err_remove_fs: 580 acpi_button_remove_fs(device); 581 err_free_input: 582 input_free_device(input); 583 err_free_button: 584 kfree(button); 585 return error; 586 } 587 588 static int acpi_button_remove(struct acpi_device *device) 589 { 590 struct acpi_button *button = acpi_driver_data(device); 591 592 acpi_button_remove_fs(device); 593 input_unregister_device(button->input); 594 kfree(button); 595 return 0; 596 } 597 598 static int param_set_lid_init_state(const char *val, 599 const struct kernel_param *kp) 600 { 601 int i; 602 603 i = sysfs_match_string(lid_init_state_str, val); 604 if (i < 0) 605 return i; 606 607 lid_init_state = i; 608 pr_info("Initial lid state set to '%s'\n", lid_init_state_str[i]); 609 return 0; 610 } 611 612 static int param_get_lid_init_state(char *buf, const struct kernel_param *kp) 613 { 614 int i, c = 0; 615 616 for (i = 0; i < ARRAY_SIZE(lid_init_state_str); i++) 617 if (i == lid_init_state) 618 c += sprintf(buf + c, "[%s] ", lid_init_state_str[i]); 619 else 620 c += sprintf(buf + c, "%s ", lid_init_state_str[i]); 621 622 buf[c - 1] = '\n'; /* Replace the final space with a newline */ 623 624 return c; 625 } 626 627 module_param_call(lid_init_state, 628 param_set_lid_init_state, param_get_lid_init_state, 629 NULL, 0644); 630 MODULE_PARM_DESC(lid_init_state, "Behavior for reporting LID initial state"); 631 632 static int acpi_button_register_driver(struct acpi_driver *driver) 633 { 634 const struct dmi_system_id *dmi_id; 635 636 if (lid_init_state == -1) { 637 dmi_id = dmi_first_match(dmi_lid_quirks); 638 if (dmi_id) 639 lid_init_state = (long)dmi_id->driver_data; 640 else 641 lid_init_state = ACPI_BUTTON_LID_INIT_METHOD; 642 } 643 644 /* 645 * Modules such as nouveau.ko and i915.ko have a link time dependency 646 * on acpi_lid_open(), and would therefore not be loadable on ACPI 647 * capable kernels booted in non-ACPI mode if the return value of 648 * acpi_bus_register_driver() is returned from here with ACPI disabled 649 * when this driver is built as a module. 650 */ 651 if (acpi_disabled) 652 return 0; 653 654 return acpi_bus_register_driver(driver); 655 } 656 657 static void acpi_button_unregister_driver(struct acpi_driver *driver) 658 { 659 if (!acpi_disabled) 660 acpi_bus_unregister_driver(driver); 661 } 662 663 module_driver(acpi_button_driver, acpi_button_register_driver, 664 acpi_button_unregister_driver); 665