|
53 | 53 | #define ACPI_BUTTON_DEVICE_NAME_LID "Lid Switch"
|
54 | 54 | #define ACPI_BUTTON_TYPE_LID 0x05
|
55 | 55 |
|
| 56 | +#define ACPI_BUTTON_LID_INIT_IGNORE 0x00 |
| 57 | +#define ACPI_BUTTON_LID_INIT_OPEN 0x01 |
| 58 | +#define ACPI_BUTTON_LID_INIT_METHOD 0x02 |
| 59 | + |
56 | 60 | #define _COMPONENT ACPI_BUTTON_COMPONENT
|
57 | 61 | ACPI_MODULE_NAME("button");
|
58 | 62 |
|
@@ -105,6 +109,7 @@ struct acpi_button {
|
105 | 109 |
|
106 | 110 | static BLOCKING_NOTIFIER_HEAD(acpi_lid_notifier);
|
107 | 111 | static struct acpi_device *lid_device;
|
| 112 | +static u8 lid_init_state = ACPI_BUTTON_LID_INIT_METHOD; |
108 | 113 |
|
109 | 114 | /* --------------------------------------------------------------------------
|
110 | 115 | FS Interface (/proc)
|
@@ -285,6 +290,21 @@ static int acpi_lid_update_state(struct acpi_device *device)
|
285 | 290 | return acpi_lid_notify_state(device, state);
|
286 | 291 | }
|
287 | 292 |
|
| 293 | +static void acpi_lid_initialize_state(struct acpi_device *device) |
| 294 | +{ |
| 295 | + switch (lid_init_state) { |
| 296 | + case ACPI_BUTTON_LID_INIT_OPEN: |
| 297 | + (void)acpi_lid_notify_state(device, 1); |
| 298 | + break; |
| 299 | + case ACPI_BUTTON_LID_INIT_METHOD: |
| 300 | + (void)acpi_lid_update_state(device); |
| 301 | + break; |
| 302 | + case ACPI_BUTTON_LID_INIT_IGNORE: |
| 303 | + default: |
| 304 | + break; |
| 305 | + } |
| 306 | +} |
| 307 | + |
288 | 308 | static void acpi_button_notify(struct acpi_device *device, u32 event)
|
289 | 309 | {
|
290 | 310 | struct acpi_button *button = acpi_driver_data(device);
|
@@ -341,6 +361,8 @@ static int acpi_button_resume(struct device *dev)
|
341 | 361 | struct acpi_button *button = acpi_driver_data(device);
|
342 | 362 |
|
343 | 363 | button->suspended = false;
|
| 364 | + if (button->type == ACPI_BUTTON_TYPE_LID) |
| 365 | + acpi_lid_initialize_state(device); |
344 | 366 | return 0;
|
345 | 367 | }
|
346 | 368 | #endif
|
@@ -421,6 +443,7 @@ static int acpi_button_add(struct acpi_device *device)
|
421 | 443 | if (error)
|
422 | 444 | goto err_remove_fs;
|
423 | 445 | if (button->type == ACPI_BUTTON_TYPE_LID) {
|
| 446 | + acpi_lid_initialize_state(device); |
424 | 447 | /*
|
425 | 448 | * This assumes there's only one lid device, or if there are
|
426 | 449 | * more we only care about the last one...
|
@@ -450,4 +473,42 @@ static int acpi_button_remove(struct acpi_device *device)
|
450 | 473 | return 0;
|
451 | 474 | }
|
452 | 475 |
|
| 476 | +static int param_set_lid_init_state(const char *val, struct kernel_param *kp) |
| 477 | +{ |
| 478 | + int result = 0; |
| 479 | + |
| 480 | + if (!strncmp(val, "open", sizeof("open") - 1)) { |
| 481 | + lid_init_state = ACPI_BUTTON_LID_INIT_OPEN; |
| 482 | + pr_info("Notify initial lid state as open\n"); |
| 483 | + } else if (!strncmp(val, "method", sizeof("method") - 1)) { |
| 484 | + lid_init_state = ACPI_BUTTON_LID_INIT_METHOD; |
| 485 | + pr_info("Notify initial lid state with _LID return value\n"); |
| 486 | + } else if (!strncmp(val, "ignore", sizeof("ignore") - 1)) { |
| 487 | + lid_init_state = ACPI_BUTTON_LID_INIT_IGNORE; |
| 488 | + pr_info("Do not notify initial lid state\n"); |
| 489 | + } else |
| 490 | + result = -EINVAL; |
| 491 | + return result; |
| 492 | +} |
| 493 | + |
| 494 | +static int param_get_lid_init_state(char *buffer, struct kernel_param *kp) |
| 495 | +{ |
| 496 | + switch (lid_init_state) { |
| 497 | + case ACPI_BUTTON_LID_INIT_OPEN: |
| 498 | + return sprintf(buffer, "open"); |
| 499 | + case ACPI_BUTTON_LID_INIT_METHOD: |
| 500 | + return sprintf(buffer, "method"); |
| 501 | + case ACPI_BUTTON_LID_INIT_IGNORE: |
| 502 | + return sprintf(buffer, "ignore"); |
| 503 | + default: |
| 504 | + return sprintf(buffer, "invalid"); |
| 505 | + } |
| 506 | + return 0; |
| 507 | +} |
| 508 | + |
| 509 | +module_param_call(lid_init_state, |
| 510 | + param_set_lid_init_state, param_get_lid_init_state, |
| 511 | + NULL, 0644); |
| 512 | +MODULE_PARM_DESC(lid_init_state, "Behavior for reporting LID initial state"); |
| 513 | + |
453 | 514 | module_acpi_driver(acpi_button_driver);
|
0 commit comments