button.c 20 KB

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