Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branches 'acpi-apei', 'acpi-wakeup', 'acpi-reboot' and 'acpi-thermal'

Merge additional APEI changes, ACPI updates related to device wakeup and
system restart and ACPI thermal driver cleanups for 6.1-rc1:

- Fix a memory leak in APEI by avoiding to add do not add task_work to
kernel threads running when an asynchronous error is detected (Shuai
Xue).

- Add ACPI support for handling system wakeups via GPIO wake capable
IRQs in addition to GPEs (Raul E Rangel).

- Make the system reboot code put ACPI-enabled systems into the S5
(system off) state which is necessary for some platforms to work as
expected (Kai-Heng Feng).

- Make the white space usage in the ACPI thermal driver more consistent
and drop redundant code from it (Rafael Wysocki).

* acpi-apei:
ACPI: APEI: do not add task_work to kernel thread to avoid memory leak

* acpi-wakeup:
ACPI: PM: Take wake IRQ into consideration when entering suspend-to-idle
i2c: acpi: Use ACPI wake capability bit to set wake_irq
ACPI: resources: Add wake_capable parameter to acpi_dev_irq_flags
gpiolib: acpi: Add wake_capable variants of acpi_dev_gpio_irq_get

* acpi-reboot:
PM: ACPI: reboot: Reinstate S5 for reboot
kernel/reboot: Add SYS_OFF_MODE_RESTART_PREPARE mode

* acpi-thermal:
ACPI: thermal: Drop some redundant code
ACPI: thermal: Drop redundant parens from expressions
ACPI: thermal: Use white space more consistently

+242 -143
+1 -1
drivers/acpi/apei/ghes.c
··· 985 985 ghes_estatus_cache_add(generic, estatus); 986 986 } 987 987 988 - if (task_work_pending && current->mm != &init_mm) { 988 + if (task_work_pending && current->mm) { 989 989 estatus_node->task_work.func = ghes_kick_task_work; 990 990 estatus_node->task_work_cpu = smp_processor_id(); 991 991 ret = task_work_add(current, &estatus_node->task_work,
+15
drivers/acpi/device_pm.c
··· 687 687 d_min = ret; 688 688 wakeup = device_may_wakeup(dev) && adev->wakeup.flags.valid 689 689 && adev->wakeup.sleep_state >= target_state; 690 + } else if (device_may_wakeup(dev) && dev->power.wakeirq) { 691 + /* 692 + * The ACPI subsystem doesn't manage the wake bit for IRQs 693 + * defined with ExclusiveAndWake and SharedAndWake. Instead we 694 + * expect them to be managed via the PM subsystem. Drivers 695 + * should call dev_pm_set_wake_irq to register an IRQ as a wake 696 + * source. 697 + * 698 + * If a device has a wake IRQ attached we need to check the 699 + * _S0W method to get the correct wake D-state. Otherwise we 700 + * end up putting the device into D3Cold which will more than 701 + * likely disable wake functionality. 702 + */ 703 + wakeup = true; 690 704 } else { 705 + /* ACPI GPE is specified in _PRW. */ 691 706 wakeup = adev->wakeup.flags.valid; 692 707 } 693 708
+5 -3
drivers/acpi/irq.c
··· 147 147 * @polarity: polarity attributes of hwirq 148 148 * @polarity: polarity attributes of hwirq 149 149 * @shareable: shareable attributes of hwirq 150 + * @wake_capable: wake capable attribute of hwirq 150 151 * @ctx: acpi_irq_parse_one_ctx updated by this function 151 152 * 152 153 * Description: ··· 157 156 static inline void acpi_irq_parse_one_match(struct fwnode_handle *fwnode, 158 157 u32 hwirq, u8 triggering, 159 158 u8 polarity, u8 shareable, 159 + u8 wake_capable, 160 160 struct acpi_irq_parse_one_ctx *ctx) 161 161 { 162 162 if (!fwnode) 163 163 return; 164 164 ctx->rc = 0; 165 - *ctx->res_flags = acpi_dev_irq_flags(triggering, polarity, shareable); 165 + *ctx->res_flags = acpi_dev_irq_flags(triggering, polarity, shareable, wake_capable); 166 166 ctx->fwspec->fwnode = fwnode; 167 167 ctx->fwspec->param[0] = hwirq; 168 168 ctx->fwspec->param[1] = acpi_dev_get_irq_type(triggering, polarity); ··· 206 204 fwnode = acpi_get_gsi_domain_id(irq->interrupts[ctx->index]); 207 205 acpi_irq_parse_one_match(fwnode, irq->interrupts[ctx->index], 208 206 irq->triggering, irq->polarity, 209 - irq->shareable, ctx); 207 + irq->shareable, irq->wake_capable, ctx); 210 208 return AE_CTRL_TERMINATE; 211 209 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: 212 210 eirq = &ares->data.extended_irq; ··· 220 218 eirq->interrupts[ctx->index]); 221 219 acpi_irq_parse_one_match(fwnode, eirq->interrupts[ctx->index], 222 220 eirq->triggering, eirq->polarity, 223 - eirq->shareable, ctx); 221 + eirq->shareable, eirq->wake_capable, ctx); 224 222 return AE_CTRL_TERMINATE; 225 223 } 226 224
+11 -5
drivers/acpi/resource.c
··· 336 336 * @triggering: Triggering type as provided by ACPI. 337 337 * @polarity: Interrupt polarity as provided by ACPI. 338 338 * @shareable: Whether or not the interrupt is shareable. 339 + * @wake_capable: Wake capability as provided by ACPI. 339 340 */ 340 - unsigned long acpi_dev_irq_flags(u8 triggering, u8 polarity, u8 shareable) 341 + unsigned long acpi_dev_irq_flags(u8 triggering, u8 polarity, u8 shareable, u8 wake_capable) 341 342 { 342 343 unsigned long flags; 343 344 ··· 351 350 352 351 if (shareable == ACPI_SHARED) 353 352 flags |= IORESOURCE_IRQ_SHAREABLE; 353 + 354 + if (wake_capable == ACPI_WAKE_CAPABLE) 355 + flags |= IORESOURCE_IRQ_WAKECAPABLE; 354 356 355 357 return flags | IORESOURCE_IRQ; 356 358 } ··· 472 468 473 469 static void acpi_dev_get_irqresource(struct resource *res, u32 gsi, 474 470 u8 triggering, u8 polarity, u8 shareable, 475 - bool check_override) 471 + u8 wake_capable, bool check_override) 476 472 { 477 473 int irq, p, t; 478 474 ··· 505 501 } 506 502 } 507 503 508 - res->flags = acpi_dev_irq_flags(triggering, polarity, shareable); 504 + res->flags = acpi_dev_irq_flags(triggering, polarity, shareable, wake_capable); 509 505 irq = acpi_register_gsi(NULL, gsi, triggering, polarity); 510 506 if (irq >= 0) { 511 507 res->start = irq; ··· 553 549 } 554 550 acpi_dev_get_irqresource(res, irq->interrupts[index], 555 551 irq->triggering, irq->polarity, 556 - irq->shareable, true); 552 + irq->shareable, irq->wake_capable, 553 + true); 557 554 break; 558 555 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: 559 556 ext_irq = &ares->data.extended_irq; ··· 565 560 if (is_gsi(ext_irq)) 566 561 acpi_dev_get_irqresource(res, ext_irq->interrupts[index], 567 562 ext_irq->triggering, ext_irq->polarity, 568 - ext_irq->shareable, false); 563 + ext_irq->shareable, ext_irq->wake_capable, 564 + false); 569 565 else 570 566 irqresource_disabled(res, 0); 571 567 break;
+8
drivers/acpi/sleep.c
··· 1088 1088 register_sys_off_handler(SYS_OFF_MODE_POWER_OFF, 1089 1089 SYS_OFF_PRIO_FIRMWARE, 1090 1090 acpi_power_off, NULL); 1091 + 1092 + /* 1093 + * Windows uses S5 for reboot, so some BIOSes depend on it to 1094 + * perform proper reboot. 1095 + */ 1096 + register_sys_off_handler(SYS_OFF_MODE_RESTART_PREPARE, 1097 + SYS_OFF_PRIO_FIRMWARE, 1098 + acpi_power_off_prepare, NULL); 1091 1099 } else { 1092 1100 acpi_no_s5 = true; 1093 1101 }
+102 -109
drivers/acpi/thermal.c
··· 158 158 }; 159 159 160 160 struct acpi_thermal { 161 - struct acpi_device * device; 161 + struct acpi_device *device; 162 162 acpi_bus_id name; 163 163 unsigned long temperature; 164 164 unsigned long last_temperature; ··· 262 262 263 263 static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) 264 264 { 265 - acpi_status status = AE_OK; 265 + acpi_status status; 266 266 unsigned long long tmp; 267 267 struct acpi_handle_list devices; 268 268 int valid = 0; ··· 270 270 271 271 /* Critical Shutdown */ 272 272 if (flag & ACPI_TRIPS_CRITICAL) { 273 - status = acpi_evaluate_integer(tz->device->handle, 274 - "_CRT", NULL, &tmp); 273 + status = acpi_evaluate_integer(tz->device->handle, "_CRT", NULL, &tmp); 275 274 tz->trips.critical.temperature = tmp; 276 275 /* 277 276 * Treat freezing temperatures as invalid as well; some ··· 283 284 acpi_handle_debug(tz->device->handle, 284 285 "No critical threshold\n"); 285 286 } else if (tmp <= 2732) { 286 - pr_info(FW_BUG "Invalid critical threshold (%llu)\n", 287 - tmp); 287 + pr_info(FW_BUG "Invalid critical threshold (%llu)\n", tmp); 288 288 tz->trips.critical.flags.valid = 0; 289 289 } else { 290 290 tz->trips.critical.flags.valid = 1; ··· 310 312 311 313 /* Critical Sleep (optional) */ 312 314 if (flag & ACPI_TRIPS_HOT) { 313 - status = acpi_evaluate_integer(tz->device->handle, 314 - "_HOT", NULL, &tmp); 315 + status = acpi_evaluate_integer(tz->device->handle, "_HOT", NULL, &tmp); 315 316 if (ACPI_FAILURE(status)) { 316 317 tz->trips.hot.flags.valid = 0; 317 318 acpi_handle_debug(tz->device->handle, ··· 326 329 327 330 /* Passive (optional) */ 328 331 if (((flag & ACPI_TRIPS_PASSIVE) && tz->trips.passive.flags.valid) || 329 - (flag == ACPI_TRIPS_INIT)) { 332 + flag == ACPI_TRIPS_INIT) { 330 333 valid = tz->trips.passive.flags.valid; 331 334 if (psv == -1) { 332 335 status = AE_SUPPORT; ··· 335 338 status = AE_OK; 336 339 } else { 337 340 status = acpi_evaluate_integer(tz->device->handle, 338 - "_PSV", NULL, &tmp); 341 + "_PSV", NULL, &tmp); 339 342 } 340 343 341 - if (ACPI_FAILURE(status)) 344 + if (ACPI_FAILURE(status)) { 342 345 tz->trips.passive.flags.valid = 0; 343 - else { 346 + } else { 344 347 tz->trips.passive.temperature = tmp; 345 348 tz->trips.passive.flags.valid = 1; 346 349 if (flag == ACPI_TRIPS_INIT) { 347 - status = acpi_evaluate_integer( 348 - tz->device->handle, "_TC1", 349 - NULL, &tmp); 350 + status = acpi_evaluate_integer(tz->device->handle, 351 + "_TC1", NULL, &tmp); 350 352 if (ACPI_FAILURE(status)) 351 353 tz->trips.passive.flags.valid = 0; 352 354 else 353 355 tz->trips.passive.tc1 = tmp; 354 - status = acpi_evaluate_integer( 355 - tz->device->handle, "_TC2", 356 - NULL, &tmp); 356 + 357 + status = acpi_evaluate_integer(tz->device->handle, 358 + "_TC2", NULL, &tmp); 357 359 if (ACPI_FAILURE(status)) 358 360 tz->trips.passive.flags.valid = 0; 359 361 else 360 362 tz->trips.passive.tc2 = tmp; 361 - status = acpi_evaluate_integer( 362 - tz->device->handle, "_TSP", 363 - NULL, &tmp); 363 + 364 + status = acpi_evaluate_integer(tz->device->handle, 365 + "_TSP", NULL, &tmp); 364 366 if (ACPI_FAILURE(status)) 365 367 tz->trips.passive.flags.valid = 0; 366 368 else ··· 370 374 if ((flag & ACPI_TRIPS_DEVICES) && tz->trips.passive.flags.valid) { 371 375 memset(&devices, 0, sizeof(struct acpi_handle_list)); 372 376 status = acpi_evaluate_reference(tz->device->handle, "_PSL", 373 - NULL, &devices); 377 + NULL, &devices); 374 378 if (ACPI_FAILURE(status)) { 375 379 acpi_handle_info(tz->device->handle, 376 380 "Invalid passive threshold\n"); 377 381 tz->trips.passive.flags.valid = 0; 378 - } 379 - else 382 + } else { 380 383 tz->trips.passive.flags.valid = 1; 384 + } 381 385 382 386 if (memcmp(&tz->trips.passive.devices, &devices, 383 - sizeof(struct acpi_handle_list))) { 387 + sizeof(struct acpi_handle_list))) { 384 388 memcpy(&tz->trips.passive.devices, &devices, 385 - sizeof(struct acpi_handle_list)); 389 + sizeof(struct acpi_handle_list)); 386 390 ACPI_THERMAL_TRIPS_EXCEPTION(flag, tz, "device"); 387 391 } 388 392 } 389 393 if ((flag & ACPI_TRIPS_PASSIVE) || (flag & ACPI_TRIPS_DEVICES)) { 390 394 if (valid != tz->trips.passive.flags.valid) 391 - ACPI_THERMAL_TRIPS_EXCEPTION(flag, tz, "state"); 395 + ACPI_THERMAL_TRIPS_EXCEPTION(flag, tz, "state"); 392 396 } 393 397 394 398 /* Active (optional) */ ··· 399 403 if (act == -1) 400 404 break; /* disable all active trip points */ 401 405 402 - if ((flag == ACPI_TRIPS_INIT) || ((flag & ACPI_TRIPS_ACTIVE) && 403 - tz->trips.active[i].flags.valid)) { 406 + if (flag == ACPI_TRIPS_INIT || ((flag & ACPI_TRIPS_ACTIVE) && 407 + tz->trips.active[i].flags.valid)) { 404 408 status = acpi_evaluate_integer(tz->device->handle, 405 - name, NULL, &tmp); 409 + name, NULL, &tmp); 406 410 if (ACPI_FAILURE(status)) { 407 411 tz->trips.active[i].flags.valid = 0; 408 412 if (i == 0) 409 413 break; 414 + 410 415 if (act <= 0) 411 416 break; 417 + 412 418 if (i == 1) 413 - tz->trips.active[0].temperature = 414 - celsius_to_deci_kelvin(act); 419 + tz->trips.active[0].temperature = celsius_to_deci_kelvin(act); 415 420 else 416 421 /* 417 422 * Don't allow override higher than 418 423 * the next higher trip point 419 424 */ 420 - tz->trips.active[i - 1].temperature = 421 - (tz->trips.active[i - 2].temperature < 425 + tz->trips.active[i-1].temperature = 426 + (tz->trips.active[i-2].temperature < 422 427 celsius_to_deci_kelvin(act) ? 423 - tz->trips.active[i - 2].temperature : 428 + tz->trips.active[i-2].temperature : 424 429 celsius_to_deci_kelvin(act)); 430 + 425 431 break; 426 432 } else { 427 433 tz->trips.active[i].temperature = tmp; ··· 432 434 } 433 435 434 436 name[2] = 'L'; 435 - if ((flag & ACPI_TRIPS_DEVICES) && tz->trips.active[i].flags.valid ) { 437 + if ((flag & ACPI_TRIPS_DEVICES) && tz->trips.active[i].flags.valid) { 436 438 memset(&devices, 0, sizeof(struct acpi_handle_list)); 437 439 status = acpi_evaluate_reference(tz->device->handle, 438 - name, NULL, &devices); 440 + name, NULL, &devices); 439 441 if (ACPI_FAILURE(status)) { 440 442 acpi_handle_info(tz->device->handle, 441 443 "Invalid active%d threshold\n", i); 442 444 tz->trips.active[i].flags.valid = 0; 443 - } 444 - else 445 + } else { 445 446 tz->trips.active[i].flags.valid = 1; 447 + } 446 448 447 449 if (memcmp(&tz->trips.active[i].devices, &devices, 448 - sizeof(struct acpi_handle_list))) { 450 + sizeof(struct acpi_handle_list))) { 449 451 memcpy(&tz->trips.active[i].devices, &devices, 450 - sizeof(struct acpi_handle_list)); 452 + sizeof(struct acpi_handle_list)); 451 453 ACPI_THERMAL_TRIPS_EXCEPTION(flag, tz, "device"); 452 454 } 453 455 } ··· 462 464 if (flag & ACPI_TRIPS_DEVICES) { 463 465 memset(&devices, 0, sizeof(devices)); 464 466 status = acpi_evaluate_reference(tz->device->handle, "_TZD", 465 - NULL, &devices); 466 - if (ACPI_SUCCESS(status) 467 - && memcmp(&tz->devices, &devices, sizeof(devices))) { 467 + NULL, &devices); 468 + if (ACPI_SUCCESS(status) && 469 + memcmp(&tz->devices, &devices, sizeof(devices))) { 468 470 tz->devices = devices; 469 471 ACPI_THERMAL_TRIPS_EXCEPTION(flag, tz, "device"); 470 472 } ··· 546 548 trip--; 547 549 } 548 550 549 - for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE && 550 - tz->trips.active[i].flags.valid; i++) { 551 + for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE && tz->trips.active[i].flags.valid; i++) { 551 552 if (!trip) { 552 553 *type = THERMAL_TRIP_ACTIVE; 553 554 return 0; ··· 569 572 if (tz->trips.critical.flags.valid) { 570 573 if (!trip) { 571 574 *temp = deci_kelvin_to_millicelsius_with_offset( 572 - tz->trips.critical.temperature, 573 - tz->kelvin_offset); 575 + tz->trips.critical.temperature, 576 + tz->kelvin_offset); 574 577 return 0; 575 578 } 576 579 trip--; ··· 579 582 if (tz->trips.hot.flags.valid) { 580 583 if (!trip) { 581 584 *temp = deci_kelvin_to_millicelsius_with_offset( 582 - tz->trips.hot.temperature, 583 - tz->kelvin_offset); 585 + tz->trips.hot.temperature, 586 + tz->kelvin_offset); 584 587 return 0; 585 588 } 586 589 trip--; ··· 589 592 if (tz->trips.passive.flags.valid) { 590 593 if (!trip) { 591 594 *temp = deci_kelvin_to_millicelsius_with_offset( 592 - tz->trips.passive.temperature, 593 - tz->kelvin_offset); 595 + tz->trips.passive.temperature, 596 + tz->kelvin_offset); 594 597 return 0; 595 598 } 596 599 trip--; ··· 600 603 tz->trips.active[i].flags.valid; i++) { 601 604 if (!trip) { 602 605 *temp = deci_kelvin_to_millicelsius_with_offset( 603 - tz->trips.active[i].temperature, 604 - tz->kelvin_offset); 606 + tz->trips.active[i].temperature, 607 + tz->kelvin_offset); 605 608 return 0; 606 609 } 607 610 trip--; ··· 617 620 618 621 if (tz->trips.critical.flags.valid) { 619 622 *temperature = deci_kelvin_to_millicelsius_with_offset( 620 - tz->trips.critical.temperature, 621 - tz->kelvin_offset); 623 + tz->trips.critical.temperature, 624 + tz->kelvin_offset); 622 625 return 0; 623 - } else 624 - return -EINVAL; 626 + } 627 + 628 + return -EINVAL; 625 629 } 626 630 627 631 static int thermal_get_trend(struct thermal_zone_device *thermal, 628 - int trip, enum thermal_trend *trend) 632 + int trip, enum thermal_trend *trend) 629 633 { 630 634 struct acpi_thermal *tz = thermal->devdata; 631 635 enum thermal_trip_type type; ··· 655 657 * tz->temperature has already been updated by generic thermal layer, 656 658 * before this callback being invoked 657 659 */ 658 - i = (tz->trips.passive.tc1 * (tz->temperature - tz->last_temperature)) 659 - + (tz->trips.passive.tc2 660 - * (tz->temperature - tz->trips.passive.temperature)); 660 + i = tz->trips.passive.tc1 * (tz->temperature - tz->last_temperature) + 661 + tz->trips.passive.tc2 * (tz->temperature - tz->trips.passive.temperature); 661 662 662 663 if (i > 0) 663 664 *trend = THERMAL_TREND_RAISING; ··· 664 667 *trend = THERMAL_TREND_DROPPING; 665 668 else 666 669 *trend = THERMAL_TREND_STABLE; 670 + 667 671 return 0; 668 672 } 669 673 ··· 689 691 } 690 692 691 693 static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal, 692 - struct thermal_cooling_device *cdev, 693 - bool bind) 694 + struct thermal_cooling_device *cdev, 695 + bool bind) 694 696 { 695 697 struct acpi_device *device = cdev->devdata; 696 698 struct acpi_thermal *tz = thermal->devdata; ··· 709 711 710 712 if (tz->trips.passive.flags.valid) { 711 713 trip++; 712 - for (i = 0; i < tz->trips.passive.devices.count; 713 - i++) { 714 + for (i = 0; i < tz->trips.passive.devices.count; i++) { 714 715 handle = tz->trips.passive.devices.handles[i]; 715 716 dev = acpi_fetch_acpi_dev(handle); 716 717 if (dev != device) 717 718 continue; 719 + 718 720 if (bind) 719 - result = 720 - thermal_zone_bind_cooling_device 721 - (thermal, trip, cdev, 722 - THERMAL_NO_LIMIT, THERMAL_NO_LIMIT, 723 - THERMAL_WEIGHT_DEFAULT); 721 + result = thermal_zone_bind_cooling_device( 722 + thermal, trip, cdev, 723 + THERMAL_NO_LIMIT, 724 + THERMAL_NO_LIMIT, 725 + THERMAL_WEIGHT_DEFAULT); 724 726 else 725 727 result = 726 - thermal_zone_unbind_cooling_device 727 - (thermal, trip, cdev); 728 + thermal_zone_unbind_cooling_device( 729 + thermal, trip, cdev); 730 + 728 731 if (result) 729 732 goto failed; 730 733 } ··· 734 735 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { 735 736 if (!tz->trips.active[i].flags.valid) 736 737 break; 738 + 737 739 trip++; 738 - for (j = 0; 739 - j < tz->trips.active[i].devices.count; 740 - j++) { 740 + for (j = 0; j < tz->trips.active[i].devices.count; j++) { 741 741 handle = tz->trips.active[i].devices.handles[j]; 742 742 dev = acpi_fetch_acpi_dev(handle); 743 743 if (dev != device) 744 744 continue; 745 + 745 746 if (bind) 746 - result = thermal_zone_bind_cooling_device 747 - (thermal, trip, cdev, 748 - THERMAL_NO_LIMIT, THERMAL_NO_LIMIT, 749 - THERMAL_WEIGHT_DEFAULT); 747 + result = thermal_zone_bind_cooling_device( 748 + thermal, trip, cdev, 749 + THERMAL_NO_LIMIT, 750 + THERMAL_NO_LIMIT, 751 + THERMAL_WEIGHT_DEFAULT); 750 752 else 751 - result = thermal_zone_unbind_cooling_device 752 - (thermal, trip, cdev); 753 + result = thermal_zone_unbind_cooling_device( 754 + thermal, trip, cdev); 755 + 753 756 if (result) 754 757 goto failed; 755 758 } ··· 763 762 764 763 static int 765 764 acpi_thermal_bind_cooling_device(struct thermal_zone_device *thermal, 766 - struct thermal_cooling_device *cdev) 765 + struct thermal_cooling_device *cdev) 767 766 { 768 767 return acpi_thermal_cooling_device_cb(thermal, cdev, true); 769 768 } 770 769 771 770 static int 772 771 acpi_thermal_unbind_cooling_device(struct thermal_zone_device *thermal, 773 - struct thermal_cooling_device *cdev) 772 + struct thermal_cooling_device *cdev) 774 773 { 775 774 return acpi_thermal_cooling_device_cb(thermal, cdev, false); 776 775 } ··· 803 802 if (tz->trips.passive.flags.valid) 804 803 trips++; 805 804 806 - for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE && 807 - tz->trips.active[i].flags.valid; i++, trips++); 805 + for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE && tz->trips.active[i].flags.valid; 806 + i++, trips++); 808 807 809 808 if (tz->trips.passive.flags.valid) 810 - tz->thermal_zone = 811 - thermal_zone_device_register("acpitz", trips, 0, tz, 812 - &acpi_thermal_zone_ops, NULL, 813 - tz->trips.passive.tsp*100, 814 - tz->polling_frequency*100); 809 + tz->thermal_zone = thermal_zone_device_register("acpitz", trips, 0, tz, 810 + &acpi_thermal_zone_ops, NULL, 811 + tz->trips.passive.tsp * 100, 812 + tz->polling_frequency * 100); 815 813 else 816 814 tz->thermal_zone = 817 815 thermal_zone_device_register("acpitz", trips, 0, tz, 818 - &acpi_thermal_zone_ops, NULL, 819 - 0, tz->polling_frequency*100); 816 + &acpi_thermal_zone_ops, NULL, 817 + 0, tz->polling_frequency * 100); 818 + 820 819 if (IS_ERR(tz->thermal_zone)) 821 820 return -ENODEV; 822 821 ··· 882 881 { 883 882 struct acpi_thermal *tz = acpi_driver_data(device); 884 883 885 - 886 884 if (!tz) 887 885 return; 888 886 ··· 893 893 acpi_thermal_trips_update(tz, ACPI_TRIPS_REFRESH_THRESHOLDS); 894 894 acpi_queue_thermal_check(tz); 895 895 acpi_bus_generate_netlink_event(device->pnp.device_class, 896 - dev_name(&device->dev), event, 0); 896 + dev_name(&device->dev), event, 0); 897 897 break; 898 898 case ACPI_THERMAL_NOTIFY_DEVICES: 899 899 acpi_thermal_trips_update(tz, ACPI_TRIPS_REFRESH_DEVICES); 900 900 acpi_queue_thermal_check(tz); 901 901 acpi_bus_generate_netlink_event(device->pnp.device_class, 902 - dev_name(&device->dev), event, 0); 902 + dev_name(&device->dev), event, 0); 903 903 break; 904 904 default: 905 905 acpi_handle_debug(device->handle, "Unsupported event [0x%x]\n", ··· 942 942 943 943 static int acpi_thermal_get_info(struct acpi_thermal *tz) 944 944 { 945 - int result = 0; 946 - 945 + int result; 947 946 948 947 if (!tz) 949 948 return -EINVAL; ··· 1019 1020 1020 1021 static int acpi_thermal_add(struct acpi_device *device) 1021 1022 { 1022 - int result = 0; 1023 - struct acpi_thermal *tz = NULL; 1024 - 1023 + struct acpi_thermal *tz; 1024 + int result; 1025 1025 1026 1026 if (!device) 1027 1027 return -EINVAL; ··· 1061 1063 1062 1064 static int acpi_thermal_remove(struct acpi_device *device) 1063 1065 { 1064 - struct acpi_thermal *tz = NULL; 1066 + struct acpi_thermal *tz; 1065 1067 1066 1068 if (!device || !acpi_driver_data(device)) 1067 1069 return -EINVAL; ··· 1097 1099 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { 1098 1100 if (!tz->trips.active[i].flags.valid) 1099 1101 break; 1102 + 1100 1103 tz->trips.active[i].flags.enabled = 1; 1101 1104 for (j = 0; j < tz->trips.active[i].devices.count; j++) { 1102 1105 result = acpi_bus_update_power( ··· 1118 1119 #endif 1119 1120 1120 1121 static int thermal_act(const struct dmi_system_id *d) { 1121 - 1122 1122 if (act == 0) { 1123 1123 pr_notice("%s detected: disabling all active thermal trip points\n", 1124 1124 d->ident); ··· 1126 1128 return 0; 1127 1129 } 1128 1130 static int thermal_nocrt(const struct dmi_system_id *d) { 1129 - 1130 1131 pr_notice("%s detected: disabling all critical thermal trip point actions.\n", 1131 1132 d->ident); 1132 1133 nocrt = 1; 1133 1134 return 0; 1134 1135 } 1135 1136 static int thermal_tzp(const struct dmi_system_id *d) { 1136 - 1137 1137 if (tzp == 0) { 1138 1138 pr_notice("%s detected: enabling thermal zone polling\n", 1139 1139 d->ident); ··· 1140 1144 return 0; 1141 1145 } 1142 1146 static int thermal_psv(const struct dmi_system_id *d) { 1143 - 1144 1147 if (psv == 0) { 1145 1148 pr_notice("%s detected: disabling all passive thermal trip points\n", 1146 1149 d->ident); ··· 1190 1195 1191 1196 static int __init acpi_thermal_init(void) 1192 1197 { 1193 - int result = 0; 1198 + int result; 1194 1199 1195 1200 dmi_check_system(thermal_dmi_table); 1196 1201 ··· 1217 1222 { 1218 1223 acpi_bus_unregister_driver(&acpi_thermal_driver); 1219 1224 destroy_workqueue(acpi_thermal_pm_queue); 1220 - 1221 - return; 1222 1225 } 1223 1226 1224 1227 module_init(acpi_thermal_init);
+12 -3
drivers/gpio/gpiolib-acpi.c
··· 741 741 lookup->info.pin_config = agpio->pin_config; 742 742 lookup->info.debounce = agpio->debounce_timeout; 743 743 lookup->info.gpioint = gpioint; 744 + lookup->info.wake_capable = agpio->wake_capable == ACPI_WAKE_CAPABLE; 744 745 745 746 /* 746 747 * Polarity and triggering are only specified for GpioInt ··· 988 987 } 989 988 990 989 /** 991 - * acpi_dev_gpio_irq_get_by() - Find GpioInt and translate it to Linux IRQ number 990 + * acpi_dev_gpio_irq_wake_get_by() - Find GpioInt and translate it to Linux IRQ number 992 991 * @adev: pointer to a ACPI device to get IRQ from 993 992 * @name: optional name of GpioInt resource 994 993 * @index: index of GpioInt resource (starting from %0) 994 + * @wake_capable: Set to true if the IRQ is wake capable 995 995 * 996 996 * If the device has one or more GpioInt resources, this function can be 997 997 * used to translate from the GPIO offset in the resource to the Linux IRQ ··· 1004 1002 * The function takes optional @name parameter. If the resource has a property 1005 1003 * name, then only those will be taken into account. 1006 1004 * 1005 + * The GPIO is considered wake capable if the GpioInt resource specifies 1006 + * SharedAndWake or ExclusiveAndWake. 1007 + * 1007 1008 * Return: Linux IRQ number (> %0) on success, negative errno on failure. 1008 1009 */ 1009 - int acpi_dev_gpio_irq_get_by(struct acpi_device *adev, const char *name, int index) 1010 + int acpi_dev_gpio_irq_wake_get_by(struct acpi_device *adev, const char *name, int index, 1011 + bool *wake_capable) 1010 1012 { 1011 1013 int idx, i; 1012 1014 unsigned int irq_flags; ··· 1067 1061 dev_dbg(&adev->dev, "IRQ %d already in use\n", irq); 1068 1062 } 1069 1063 1064 + if (wake_capable) 1065 + *wake_capable = info.wake_capable; 1066 + 1070 1067 return irq; 1071 1068 } 1072 1069 1073 1070 } 1074 1071 return -ENOENT; 1075 1072 } 1076 - EXPORT_SYMBOL_GPL(acpi_dev_gpio_irq_get_by); 1073 + EXPORT_SYMBOL_GPL(acpi_dev_gpio_irq_wake_get_by); 1077 1074 1078 1075 static acpi_status 1079 1076 acpi_gpio_adr_space_handler(u32 function, acpi_physical_address address,
+2
drivers/gpio/gpiolib-acpi.h
··· 18 18 * @pin_config: pin bias as provided by ACPI 19 19 * @polarity: interrupt polarity as provided by ACPI 20 20 * @triggering: triggering type as provided by ACPI 21 + * @wake_capable: wake capability as provided by ACPI 21 22 * @debounce: debounce timeout as provided by ACPI 22 23 * @quirks: Linux specific quirks as provided by struct acpi_gpio_mapping 23 24 */ ··· 29 28 int pin_config; 30 29 int polarity; 31 30 int triggering; 31 + bool wake_capable; 32 32 unsigned int debounce; 33 33 unsigned int quirks; 34 34 };
+30 -10
drivers/i2c/i2c-core-acpi.c
··· 137 137 {} 138 138 }; 139 139 140 + struct i2c_acpi_irq_context { 141 + int irq; 142 + bool wake_capable; 143 + }; 144 + 140 145 static int i2c_acpi_do_lookup(struct acpi_device *adev, 141 146 struct i2c_acpi_lookup *lookup) 142 147 { ··· 173 168 return 0; 174 169 } 175 170 176 - static int i2c_acpi_add_resource(struct acpi_resource *ares, void *data) 171 + static int i2c_acpi_add_irq_resource(struct acpi_resource *ares, void *data) 177 172 { 178 - int *irq = data; 173 + struct i2c_acpi_irq_context *irq_ctx = data; 179 174 struct resource r; 180 175 181 - if (*irq <= 0 && acpi_dev_resource_interrupt(ares, 0, &r)) 182 - *irq = i2c_dev_irq_from_resources(&r, 1); 176 + if (irq_ctx->irq > 0) 177 + return 1; 178 + 179 + if (!acpi_dev_resource_interrupt(ares, 0, &r)) 180 + return 1; 181 + 182 + irq_ctx->irq = i2c_dev_irq_from_resources(&r, 1); 183 + irq_ctx->wake_capable = r.flags & IORESOURCE_IRQ_WAKECAPABLE; 183 184 184 185 return 1; /* No need to add resource to the list */ 185 186 } ··· 193 182 /** 194 183 * i2c_acpi_get_irq - get device IRQ number from ACPI 195 184 * @client: Pointer to the I2C client device 185 + * @wake_capable: Set to true if the IRQ is wake capable 196 186 * 197 187 * Find the IRQ number used by a specific client device. 198 188 * 199 189 * Return: The IRQ number or an error code. 200 190 */ 201 - int i2c_acpi_get_irq(struct i2c_client *client) 191 + int i2c_acpi_get_irq(struct i2c_client *client, bool *wake_capable) 202 192 { 203 193 struct acpi_device *adev = ACPI_COMPANION(&client->dev); 204 194 struct list_head resource_list; 205 - int irq = -ENOENT; 195 + struct i2c_acpi_irq_context irq_ctx = { 196 + .irq = -ENOENT, 197 + }; 206 198 int ret; 207 199 208 200 INIT_LIST_HEAD(&resource_list); 209 201 210 202 ret = acpi_dev_get_resources(adev, &resource_list, 211 - i2c_acpi_add_resource, &irq); 203 + i2c_acpi_add_irq_resource, &irq_ctx); 212 204 if (ret < 0) 213 205 return ret; 214 206 215 207 acpi_dev_free_resource_list(&resource_list); 216 208 217 - if (irq == -ENOENT) 218 - irq = acpi_dev_gpio_irq_get(adev, 0); 209 + if (irq_ctx.irq == -ENOENT) 210 + irq_ctx.irq = acpi_dev_gpio_irq_wake_get(adev, 0, &irq_ctx.wake_capable); 219 211 220 - return irq; 212 + if (irq_ctx.irq < 0) 213 + return irq_ctx.irq; 214 + 215 + if (wake_capable) 216 + *wake_capable = irq_ctx.wake_capable; 217 + 218 + return irq_ctx.irq; 221 219 } 222 220 223 221 static int i2c_acpi_get_info(struct acpi_device *adev,
+5 -1
drivers/i2c/i2c-core-base.c
··· 487 487 if (irq == -EINVAL || irq == -ENODATA) 488 488 irq = of_irq_get(dev->of_node, 0); 489 489 } else if (ACPI_COMPANION(dev)) { 490 - irq = i2c_acpi_get_irq(client); 490 + bool wake_capable; 491 + 492 + irq = i2c_acpi_get_irq(client, &wake_capable); 493 + if (irq > 0 && wake_capable) 494 + client->flags |= I2C_CLIENT_WAKE; 491 495 } 492 496 if (irq == -EPROBE_DEFER) { 493 497 status = irq;
+2 -2
drivers/i2c/i2c-core.h
··· 61 61 #ifdef CONFIG_ACPI 62 62 void i2c_acpi_register_devices(struct i2c_adapter *adap); 63 63 64 - int i2c_acpi_get_irq(struct i2c_client *client); 64 + int i2c_acpi_get_irq(struct i2c_client *client, bool *wake_capable); 65 65 #else /* CONFIG_ACPI */ 66 66 static inline void i2c_acpi_register_devices(struct i2c_adapter *adap) { } 67 67 68 - static inline int i2c_acpi_get_irq(struct i2c_client *client) 68 + static inline int i2c_acpi_get_irq(struct i2c_client *client, bool *wake_capable) 69 69 { 70 70 return 0; 71 71 }
+4 -3
drivers/pnp/pnpacpi/rsparser.c
··· 206 206 if (i >= 0) { 207 207 flags = acpi_dev_irq_flags(gpio->triggering, 208 208 gpio->polarity, 209 - gpio->shareable); 209 + gpio->shareable, 210 + gpio->wake_capable); 210 211 } else { 211 212 flags = IORESOURCE_DISABLED; 212 213 } ··· 316 315 if (p->interrupts[i]) 317 316 __set_bit(p->interrupts[i], map.bits); 318 317 319 - flags = acpi_dev_irq_flags(p->triggering, p->polarity, p->shareable); 318 + flags = acpi_dev_irq_flags(p->triggering, p->polarity, p->shareable, p->wake_capable); 320 319 pnp_register_irq_resource(dev, option_flags, &map, flags); 321 320 } 322 321 ··· 340 339 } 341 340 } 342 341 343 - flags = acpi_dev_irq_flags(p->triggering, p->polarity, p->shareable); 342 + flags = acpi_dev_irq_flags(p->triggering, p->polarity, p->shareable, p->wake_capable); 344 343 pnp_register_irq_resource(dev, option_flags, &map, flags); 345 344 } 346 345
+18 -5
include/linux/acpi.h
··· 498 498 struct resource_win *win); 499 499 bool acpi_dev_resource_ext_address_space(struct acpi_resource *ares, 500 500 struct resource_win *win); 501 - unsigned long acpi_dev_irq_flags(u8 triggering, u8 polarity, u8 shareable); 501 + unsigned long acpi_dev_irq_flags(u8 triggering, u8 polarity, u8 shareable, u8 wake_capable); 502 502 unsigned int acpi_dev_get_irq_type(int triggering, int polarity); 503 503 bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index, 504 504 struct resource *res); ··· 1210 1210 struct acpi_resource_gpio **agpio); 1211 1211 bool acpi_gpio_get_io_resource(struct acpi_resource *ares, 1212 1212 struct acpi_resource_gpio **agpio); 1213 - int acpi_dev_gpio_irq_get_by(struct acpi_device *adev, const char *name, int index); 1213 + int acpi_dev_gpio_irq_wake_get_by(struct acpi_device *adev, const char *name, int index, 1214 + bool *wake_capable); 1214 1215 #else 1215 1216 static inline bool acpi_gpio_get_irq_resource(struct acpi_resource *ares, 1216 1217 struct acpi_resource_gpio **agpio) ··· 1223 1222 { 1224 1223 return false; 1225 1224 } 1226 - static inline int acpi_dev_gpio_irq_get_by(struct acpi_device *adev, 1227 - const char *name, int index) 1225 + static inline int acpi_dev_gpio_irq_wake_get_by(struct acpi_device *adev, const char *name, 1226 + int index, bool *wake_capable) 1228 1227 { 1229 1228 return -ENXIO; 1230 1229 } 1231 1230 #endif 1232 1231 1232 + static inline int acpi_dev_gpio_irq_wake_get(struct acpi_device *adev, int index, 1233 + bool *wake_capable) 1234 + { 1235 + return acpi_dev_gpio_irq_wake_get_by(adev, NULL, index, wake_capable); 1236 + } 1237 + 1238 + static inline int acpi_dev_gpio_irq_get_by(struct acpi_device *adev, const char *name, 1239 + int index) 1240 + { 1241 + return acpi_dev_gpio_irq_wake_get_by(adev, name, index, NULL); 1242 + } 1243 + 1233 1244 static inline int acpi_dev_gpio_irq_get(struct acpi_device *adev, int index) 1234 1245 { 1235 - return acpi_dev_gpio_irq_get_by(adev, NULL, index); 1246 + return acpi_dev_gpio_irq_wake_get_by(adev, NULL, index, NULL); 1236 1247 } 1237 1248 1238 1249 /* Device properties */
+2 -1
include/linux/ioport.h
··· 79 79 #define IORESOURCE_IRQ_HIGHLEVEL (1<<2) 80 80 #define IORESOURCE_IRQ_LOWLEVEL (1<<3) 81 81 #define IORESOURCE_IRQ_SHAREABLE (1<<4) 82 - #define IORESOURCE_IRQ_OPTIONAL (1<<5) 82 + #define IORESOURCE_IRQ_OPTIONAL (1<<5) 83 + #define IORESOURCE_IRQ_WAKECAPABLE (1<<6) 83 84 84 85 /* PnP DMA specific bits (IORESOURCE_BITS) */ 85 86 #define IORESOURCE_DMA_TYPE_MASK (3<<0)
+8
include/linux/reboot.h
··· 106 106 SYS_OFF_MODE_POWER_OFF, 107 107 108 108 /** 109 + * @SYS_OFF_MODE_RESTART_PREPARE: 110 + * 111 + * Handlers prepare system to be restarted. Handlers are 112 + * allowed to sleep. 113 + */ 114 + SYS_OFF_MODE_RESTART_PREPARE, 115 + 116 + /** 109 117 * @SYS_OFF_MODE_RESTART: 110 118 * 111 119 * Handlers restart system. Handlers are disallowed to sleep.
+17
kernel/reboot.c
··· 243 243 set_cpus_allowed_ptr(current, cpumask_of(cpu)); 244 244 } 245 245 246 + /* 247 + * Notifier list for kernel code which wants to be called 248 + * to prepare system for restart. 249 + */ 250 + static BLOCKING_NOTIFIER_HEAD(restart_prep_handler_list); 251 + 252 + static void do_kernel_restart_prepare(void) 253 + { 254 + blocking_notifier_call_chain(&restart_prep_handler_list, 0, NULL); 255 + } 256 + 246 257 /** 247 258 * kernel_restart - reboot the system 248 259 * @cmd: pointer to buffer containing command to execute for restart ··· 265 254 void kernel_restart(char *cmd) 266 255 { 267 256 kernel_restart_prepare(cmd); 257 + do_kernel_restart_prepare(); 268 258 migrate_to_reboot_cpu(); 269 259 syscore_shutdown(); 270 260 if (!cmd) ··· 406 394 407 395 case SYS_OFF_MODE_POWER_OFF: 408 396 handler->list = &power_off_handler_list; 397 + break; 398 + 399 + case SYS_OFF_MODE_RESTART_PREPARE: 400 + handler->list = &restart_prep_handler_list; 401 + handler->blocking = true; 409 402 break; 410 403 411 404 case SYS_OFF_MODE_RESTART: