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