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 64 ACPI_MODULE_NAME("button"); 65 66 MODULE_AUTHOR("Paul Diefenbaugh"); 67 MODULE_DESCRIPTION("ACPI Button Driver"); 68 MODULE_LICENSE("GPL"); 69 70 static 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 }; 78 MODULE_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 */ 84 static 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 96 static int acpi_button_add(struct acpi_device *device); 97 static int acpi_button_remove(struct acpi_device *device); 98 static void acpi_button_notify(struct acpi_device *device, u32 event); 99 100 #ifdef CONFIG_PM_SLEEP 101 static int acpi_button_suspend(struct device *dev); 102 static int acpi_button_resume(struct device *dev); 103 #else 104 #define acpi_button_suspend NULL 105 #define acpi_button_resume NULL 106 #endif 107 static SIMPLE_DEV_PM_OPS(acpi_button_pm, acpi_button_suspend, acpi_button_resume); 108 109 static 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 121 struct 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 131 static BLOCKING_NOTIFIER_HEAD(acpi_lid_notifier); 132 static struct acpi_device *lid_device; 133 static u8 lid_init_state = ACPI_BUTTON_LID_INIT_METHOD; 134 135 static unsigned long lid_report_interval __read_mostly = 500; 136 module_param(lid_report_interval, ulong, 0644); 137 MODULE_PARM_DESC(lid_report_interval, "Interval (ms) between lid key events"); 138 139 /* -------------------------------------------------------------------------- 140 FS Interface (/proc) 141 -------------------------------------------------------------------------- */ 142 143 static struct proc_dir_entry *acpi_button_dir; 144 static struct proc_dir_entry *acpi_lid_dir; 145 146 static 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 158 static 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 255 static 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 266 static int acpi_button_state_open_fs(struct inode *inode, struct file *file) 267 { 268 return single_open(file, acpi_button_state_seq_show, PDE_DATA(inode)); 269 } 270 271 static const struct file_operations acpi_button_state_fops = { 272 .owner = THIS_MODULE, 273 .open = acpi_button_state_open_fs, 274 .read = seq_read, 275 .llseek = seq_lseek, 276 .release = single_release, 277 }; 278 279 static int acpi_button_add_fs(struct acpi_device *device) 280 { 281 struct acpi_button *button = acpi_driver_data(device); 282 struct proc_dir_entry *entry = NULL; 283 int ret = 0; 284 285 /* procfs I/F for ACPI lid device only */ 286 if (button->type != ACPI_BUTTON_TYPE_LID) 287 return 0; 288 289 if (acpi_button_dir || acpi_lid_dir) { 290 printk(KERN_ERR PREFIX "More than one Lid device found!\n"); 291 return -EEXIST; 292 } 293 294 /* create /proc/acpi/button */ 295 acpi_button_dir = proc_mkdir(ACPI_BUTTON_CLASS, acpi_root_dir); 296 if (!acpi_button_dir) 297 return -ENODEV; 298 299 /* create /proc/acpi/button/lid */ 300 acpi_lid_dir = proc_mkdir(ACPI_BUTTON_SUBCLASS_LID, acpi_button_dir); 301 if (!acpi_lid_dir) { 302 ret = -ENODEV; 303 goto remove_button_dir; 304 } 305 306 /* create /proc/acpi/button/lid/LID/ */ 307 acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), acpi_lid_dir); 308 if (!acpi_device_dir(device)) { 309 ret = -ENODEV; 310 goto remove_lid_dir; 311 } 312 313 /* create /proc/acpi/button/lid/LID/state */ 314 entry = proc_create_data(ACPI_BUTTON_FILE_STATE, 315 S_IRUGO, acpi_device_dir(device), 316 &acpi_button_state_fops, device); 317 if (!entry) { 318 ret = -ENODEV; 319 goto remove_dev_dir; 320 } 321 322 done: 323 return ret; 324 325 remove_dev_dir: 326 remove_proc_entry(acpi_device_bid(device), 327 acpi_lid_dir); 328 acpi_device_dir(device) = NULL; 329 remove_lid_dir: 330 remove_proc_entry(ACPI_BUTTON_SUBCLASS_LID, acpi_button_dir); 331 acpi_lid_dir = NULL; 332 remove_button_dir: 333 remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir); 334 acpi_button_dir = NULL; 335 goto done; 336 } 337 338 static int acpi_button_remove_fs(struct acpi_device *device) 339 { 340 struct acpi_button *button = acpi_driver_data(device); 341 342 if (button->type != ACPI_BUTTON_TYPE_LID) 343 return 0; 344 345 remove_proc_entry(ACPI_BUTTON_FILE_STATE, 346 acpi_device_dir(device)); 347 remove_proc_entry(acpi_device_bid(device), 348 acpi_lid_dir); 349 acpi_device_dir(device) = NULL; 350 remove_proc_entry(ACPI_BUTTON_SUBCLASS_LID, acpi_button_dir); 351 acpi_lid_dir = NULL; 352 remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir); 353 acpi_button_dir = NULL; 354 355 return 0; 356 } 357 358 /* -------------------------------------------------------------------------- 359 Driver Interface 360 -------------------------------------------------------------------------- */ 361 int acpi_lid_notifier_register(struct notifier_block *nb) 362 { 363 return blocking_notifier_chain_register(&acpi_lid_notifier, nb); 364 } 365 EXPORT_SYMBOL(acpi_lid_notifier_register); 366 367 int acpi_lid_notifier_unregister(struct notifier_block *nb) 368 { 369 return blocking_notifier_chain_unregister(&acpi_lid_notifier, nb); 370 } 371 EXPORT_SYMBOL(acpi_lid_notifier_unregister); 372 373 int acpi_lid_open(void) 374 { 375 if (!lid_device) 376 return -ENODEV; 377 378 return acpi_lid_evaluate_state(lid_device); 379 } 380 EXPORT_SYMBOL(acpi_lid_open); 381 382 static int acpi_lid_update_state(struct acpi_device *device) 383 { 384 int state; 385 386 state = acpi_lid_evaluate_state(device); 387 if (state < 0) 388 return state; 389 390 return acpi_lid_notify_state(device, state); 391 } 392 393 static void acpi_lid_initialize_state(struct acpi_device *device) 394 { 395 switch (lid_init_state) { 396 case ACPI_BUTTON_LID_INIT_OPEN: 397 (void)acpi_lid_notify_state(device, 1); 398 break; 399 case ACPI_BUTTON_LID_INIT_METHOD: 400 (void)acpi_lid_update_state(device); 401 break; 402 case ACPI_BUTTON_LID_INIT_IGNORE: 403 default: 404 break; 405 } 406 } 407 408 static void acpi_button_notify(struct acpi_device *device, u32 event) 409 { 410 struct acpi_button *button = acpi_driver_data(device); 411 struct input_dev *input; 412 int users; 413 414 switch (event) { 415 case ACPI_FIXED_HARDWARE_EVENT: 416 event = ACPI_BUTTON_NOTIFY_STATUS; 417 /* fall through */ 418 case ACPI_BUTTON_NOTIFY_STATUS: 419 input = button->input; 420 if (button->type == ACPI_BUTTON_TYPE_LID) { 421 mutex_lock(&button->input->mutex); 422 users = button->input->users; 423 mutex_unlock(&button->input->mutex); 424 if (users) 425 acpi_lid_update_state(device); 426 } else { 427 int keycode; 428 429 acpi_pm_wakeup_event(&device->dev); 430 if (button->suspended) 431 break; 432 433 keycode = test_bit(KEY_SLEEP, input->keybit) ? 434 KEY_SLEEP : KEY_POWER; 435 input_report_key(input, keycode, 1); 436 input_sync(input); 437 input_report_key(input, keycode, 0); 438 input_sync(input); 439 440 acpi_bus_generate_netlink_event( 441 device->pnp.device_class, 442 dev_name(&device->dev), 443 event, ++button->pushed); 444 } 445 break; 446 default: 447 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 448 "Unsupported event [0x%x]\n", event)); 449 break; 450 } 451 } 452 453 #ifdef CONFIG_PM_SLEEP 454 static int acpi_button_suspend(struct device *dev) 455 { 456 struct acpi_device *device = to_acpi_device(dev); 457 struct acpi_button *button = acpi_driver_data(device); 458 459 button->suspended = true; 460 return 0; 461 } 462 463 static int acpi_button_resume(struct device *dev) 464 { 465 struct acpi_device *device = to_acpi_device(dev); 466 struct acpi_button *button = acpi_driver_data(device); 467 468 button->suspended = false; 469 if (button->type == ACPI_BUTTON_TYPE_LID && button->input->users) 470 acpi_lid_initialize_state(device); 471 return 0; 472 } 473 #endif 474 475 static int acpi_lid_input_open(struct input_dev *input) 476 { 477 struct acpi_device *device = input_get_drvdata(input); 478 struct acpi_button *button = acpi_driver_data(device); 479 480 button->last_state = !!acpi_lid_evaluate_state(device); 481 button->last_time = ktime_get(); 482 acpi_lid_initialize_state(device); 483 484 return 0; 485 } 486 487 static int acpi_button_add(struct acpi_device *device) 488 { 489 struct acpi_button *button; 490 struct input_dev *input; 491 const char *hid = acpi_device_hid(device); 492 char *name, *class; 493 int error; 494 495 if (!strcmp(hid, ACPI_BUTTON_HID_LID) && dmi_check_system(lid_blacklst)) 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 result = 0; 602 603 if (!strncmp(val, "open", sizeof("open") - 1)) { 604 lid_init_state = ACPI_BUTTON_LID_INIT_OPEN; 605 pr_info("Notify initial lid state as open\n"); 606 } else if (!strncmp(val, "method", sizeof("method") - 1)) { 607 lid_init_state = ACPI_BUTTON_LID_INIT_METHOD; 608 pr_info("Notify initial lid state with _LID return value\n"); 609 } else if (!strncmp(val, "ignore", sizeof("ignore") - 1)) { 610 lid_init_state = ACPI_BUTTON_LID_INIT_IGNORE; 611 pr_info("Do not notify initial lid state\n"); 612 } else 613 result = -EINVAL; 614 return result; 615 } 616 617 static int param_get_lid_init_state(char *buffer, 618 const struct kernel_param *kp) 619 { 620 switch (lid_init_state) { 621 case ACPI_BUTTON_LID_INIT_OPEN: 622 return sprintf(buffer, "open"); 623 case ACPI_BUTTON_LID_INIT_METHOD: 624 return sprintf(buffer, "method"); 625 case ACPI_BUTTON_LID_INIT_IGNORE: 626 return sprintf(buffer, "ignore"); 627 default: 628 return sprintf(buffer, "invalid"); 629 } 630 return 0; 631 } 632 633 module_param_call(lid_init_state, 634 param_set_lid_init_state, param_get_lid_init_state, 635 NULL, 0644); 636 MODULE_PARM_DESC(lid_init_state, "Behavior for reporting LID initial state"); 637 638 module_acpi_driver(acpi_button_driver); 639