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