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

[ACPI] Allow return to active cooling mode once passive mode is entered

http://bugzilla.kernel.org/show_bug.cgi?id=3410
https://bugzilla.novell.com/show_bug.cgi?id=131543

Signed-off-by: Thomas Renninger <trenn@suse.de>
Signed-off-by: Konstantin Karasyov <konstantin.a.karasyov@intel.com>
Signed-off-by: Alexey Starikovskiy <alexey.y.starikovskiy@intel.com>
Signed-off-by: Yu Luming <luming.yu@gmail.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>

authored by

Thomas Renninger and committed by
Len Brown
1cbf4c56 d2149b54

+108 -93
+23 -15
drivers/acpi/processor_thermal.c
··· 101 101 static int cpu_has_cpufreq(unsigned int cpu) 102 102 { 103 103 struct cpufreq_policy policy; 104 - if (!acpi_thermal_cpufreq_is_init) 105 - return -ENODEV; 106 - if (!cpufreq_get_policy(&policy, cpu)) 104 + if (!acpi_thermal_cpufreq_is_init || cpufreq_get_policy(&policy, cpu)) 107 105 return -ENODEV; 108 106 return 0; 109 107 } ··· 125 127 if (!cpu_has_cpufreq(cpu)) 126 128 return -ENODEV; 127 129 128 - if (cpufreq_thermal_reduction_pctg[cpu] >= 20) { 130 + if (cpufreq_thermal_reduction_pctg[cpu] > 20) 129 131 cpufreq_thermal_reduction_pctg[cpu] -= 20; 130 - cpufreq_update_policy(cpu); 131 - return 0; 132 - } 133 - 134 - return -ERANGE; 132 + else 133 + cpufreq_thermal_reduction_pctg[cpu] = 0; 134 + cpufreq_update_policy(cpu); 135 + /* We reached max freq again and can leave passive mode */ 136 + return !cpufreq_thermal_reduction_pctg[cpu]; 135 137 } 136 138 137 139 static int acpi_thermal_cpufreq_notifier(struct notifier_block *nb, ··· 198 200 int result = 0; 199 201 struct acpi_processor *pr = NULL; 200 202 struct acpi_device *device = NULL; 201 - int tx = 0; 203 + int tx = 0, max_tx_px = 0; 202 204 203 205 ACPI_FUNCTION_TRACE("acpi_processor_set_thermal_limit"); 204 206 ··· 257 259 /* if going down: T-states first, P-states later */ 258 260 259 261 if (pr->flags.throttling) { 260 - if (tx == 0) 262 + if (tx == 0) { 263 + max_tx_px = 1; 261 264 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 262 265 "At minimum throttling state\n")); 263 - else { 266 + } else { 264 267 tx--; 265 268 goto end; 266 269 } 267 270 } 268 271 269 272 result = acpi_thermal_cpufreq_decrease(pr->id); 270 - if (result == -ERANGE) 273 + if (result) { 274 + /* 275 + * We only could get -ERANGE, 1 or 0. 276 + * In the first two cases we reached max freq again. 277 + */ 271 278 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 272 279 "At minimum performance state\n")); 280 + max_tx_px = 1; 281 + } else 282 + max_tx_px = 0; 273 283 274 284 break; 275 285 } ··· 296 290 pr->limit.thermal.px, pr->limit.thermal.tx)); 297 291 } else 298 292 result = 0; 299 - 300 - return_VALUE(result); 293 + if (max_tx_px) 294 + return_VALUE(1); 295 + else 296 + return_VALUE(result); 301 297 } 302 298 303 299 int acpi_processor_get_limit_info(struct acpi_processor *pr)
+85 -78
drivers/acpi/thermal.c
··· 72 72 #define _COMPONENT ACPI_THERMAL_COMPONENT 73 73 ACPI_MODULE_NAME("acpi_thermal") 74 74 75 - MODULE_AUTHOR("Paul Diefenbaugh"); 75 + MODULE_AUTHOR("Paul Diefenbaugh"); 76 76 MODULE_DESCRIPTION(ACPI_THERMAL_DRIVER_NAME); 77 77 MODULE_LICENSE("GPL"); 78 78 ··· 517 517 return_VALUE(0); 518 518 } 519 519 520 - static int acpi_thermal_passive(struct acpi_thermal *tz) 520 + static void acpi_thermal_passive(struct acpi_thermal *tz) 521 521 { 522 - int result = 0; 522 + int result = 1; 523 523 struct acpi_thermal_passive *passive = NULL; 524 524 int trend = 0; 525 525 int i = 0; ··· 527 527 ACPI_FUNCTION_TRACE("acpi_thermal_passive"); 528 528 529 529 if (!tz || !tz->trips.passive.flags.valid) 530 - return_VALUE(-EINVAL); 530 + return; 531 531 532 532 passive = &(tz->trips.passive); 533 533 ··· 547 547 trend, passive->tc1, tz->temperature, 548 548 tz->last_temperature, passive->tc2, 549 549 tz->temperature, passive->temperature)); 550 - tz->trips.passive.flags.enabled = 1; 550 + passive->flags.enabled = 1; 551 551 /* Heating up? */ 552 552 if (trend > 0) 553 553 for (i = 0; i < passive->devices.count; i++) ··· 556 556 handles[i], 557 557 ACPI_PROCESSOR_LIMIT_INCREMENT); 558 558 /* Cooling off? */ 559 - else if (trend < 0) 559 + else if (trend < 0) { 560 560 for (i = 0; i < passive->devices.count; i++) 561 - acpi_processor_set_thermal_limit(passive-> 562 - devices. 563 - handles[i], 564 - ACPI_PROCESSOR_LIMIT_DECREMENT); 561 + /* 562 + * assume that we are on highest 563 + * freq/lowest thrott and can leave 564 + * passive mode, even in error case 565 + */ 566 + if (!acpi_processor_set_thermal_limit 567 + (passive->devices.handles[i], 568 + ACPI_PROCESSOR_LIMIT_DECREMENT)) 569 + result = 0; 570 + /* 571 + * Leave cooling mode, even if the temp might 572 + * higher than trip point This is because some 573 + * machines might have long thermal polling 574 + * frequencies (tsp) defined. We will fall back 575 + * into passive mode in next cycle (probably quicker) 576 + */ 577 + if (result) { 578 + passive->flags.enabled = 0; 579 + ACPI_DEBUG_PRINT((ACPI_DB_INFO, 580 + "Disabling passive cooling, still above threshold," 581 + " but we are cooling down\n")); 582 + } 583 + } 584 + return; 565 585 } 566 586 567 587 /* ··· 591 571 * and avoid thrashing around the passive trip point. Note that we 592 572 * assume symmetry. 593 573 */ 594 - else if (tz->trips.passive.flags.enabled) { 595 - for (i = 0; i < passive->devices.count; i++) 596 - result = 597 - acpi_processor_set_thermal_limit(passive->devices. 598 - handles[i], 599 - ACPI_PROCESSOR_LIMIT_DECREMENT); 600 - if (result == 1) { 601 - tz->trips.passive.flags.enabled = 0; 602 - ACPI_DEBUG_PRINT((ACPI_DB_INFO, 603 - "Disabling passive cooling (zone is cool)\n")); 604 - } 574 + if (!passive->flags.enabled) 575 + return; 576 + for (i = 0; i < passive->devices.count; i++) 577 + if (!acpi_processor_set_thermal_limit 578 + (passive->devices.handles[i], 579 + ACPI_PROCESSOR_LIMIT_DECREMENT)) 580 + result = 0; 581 + if (result) { 582 + passive->flags.enabled = 0; 583 + ACPI_DEBUG_PRINT((ACPI_DB_INFO, 584 + "Disabling passive cooling (zone is cool)\n")); 605 585 } 606 - 607 - return_VALUE(0); 608 586 } 609 587 610 - static int acpi_thermal_active(struct acpi_thermal *tz) 588 + static void acpi_thermal_active(struct acpi_thermal *tz) 611 589 { 612 590 int result = 0; 613 591 struct acpi_thermal_active *active = NULL; ··· 616 598 ACPI_FUNCTION_TRACE("acpi_thermal_active"); 617 599 618 600 if (!tz) 619 - return_VALUE(-EINVAL); 601 + return; 620 602 621 603 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { 622 - 623 604 active = &(tz->trips.active[i]); 624 605 if (!active || !active->flags.valid) 625 606 break; 626 - 627 - /* 628 - * Above Threshold? 629 - * ---------------- 630 - * If not already enabled, turn ON all cooling devices 631 - * associated with this active threshold. 632 - */ 633 607 if (tz->temperature >= active->temperature) { 608 + /* 609 + * Above Threshold? 610 + * ---------------- 611 + * If not already enabled, turn ON all cooling devices 612 + * associated with this active threshold. 613 + */ 634 614 if (active->temperature > maxtemp) 635 - tz->state.active_index = i, maxtemp = 636 - active->temperature; 637 - if (!active->flags.enabled) { 638 - for (j = 0; j < active->devices.count; j++) { 639 - result = 640 - acpi_bus_set_power(active->devices. 641 - handles[j], 642 - ACPI_STATE_D0); 643 - if (result) { 644 - ACPI_DEBUG_PRINT((ACPI_DB_WARN, 645 - "Unable to turn cooling device [%p] 'on'\n", 646 - active-> 647 - devices. 648 - handles[j])); 649 - continue; 650 - } 651 - active->flags.enabled = 1; 652 - ACPI_DEBUG_PRINT((ACPI_DB_INFO, 653 - "Cooling device [%p] now 'on'\n", 615 + tz->state.active_index = i; 616 + maxtemp = active->temperature; 617 + if (active->flags.enabled) 618 + continue; 619 + for (j = 0; j < active->devices.count; j++) { 620 + result = 621 + acpi_bus_set_power(active->devices. 622 + handles[j], 623 + ACPI_STATE_D0); 624 + if (result) { 625 + ACPI_DEBUG_PRINT((ACPI_DB_WARN, 626 + "Unable to turn cooling device [%p] 'on'\n", 654 627 active->devices. 655 628 handles[j])); 629 + continue; 656 630 } 631 + active->flags.enabled = 1; 632 + ACPI_DEBUG_PRINT((ACPI_DB_INFO, 633 + "Cooling device [%p] now 'on'\n", 634 + active->devices.handles[j])); 657 635 } 636 + continue; 658 637 } 638 + if (!active->flags.enabled) 639 + continue; 659 640 /* 660 641 * Below Threshold? 661 642 * ---------------- 662 643 * Turn OFF all cooling devices associated with this 663 644 * threshold. 664 645 */ 665 - else if (active->flags.enabled) { 666 - for (j = 0; j < active->devices.count; j++) { 667 - result = 668 - acpi_bus_set_power(active->devices. 669 - handles[j], 670 - ACPI_STATE_D3); 671 - if (result) { 672 - ACPI_DEBUG_PRINT((ACPI_DB_WARN, 673 - "Unable to turn cooling device [%p] 'off'\n", 674 - active->devices. 675 - handles[j])); 676 - continue; 677 - } 678 - active->flags.enabled = 0; 679 - ACPI_DEBUG_PRINT((ACPI_DB_INFO, 680 - "Cooling device [%p] now 'off'\n", 646 + for (j = 0; j < active->devices.count; j++) { 647 + result = acpi_bus_set_power(active->devices.handles[j], 648 + ACPI_STATE_D3); 649 + if (result) { 650 + ACPI_DEBUG_PRINT((ACPI_DB_WARN, 651 + "Unable to turn cooling device [%p] 'off'\n", 681 652 active->devices.handles[j])); 653 + continue; 682 654 } 655 + active->flags.enabled = 0; 656 + ACPI_DEBUG_PRINT((ACPI_DB_INFO, 657 + "Cooling device [%p] now 'off'\n", 658 + active->devices.handles[j])); 683 659 } 684 660 } 685 - 686 - return_VALUE(0); 687 661 } 688 662 689 663 static void acpi_thermal_check(void *context); ··· 754 744 * Again, separated from the above two to allow independent policy 755 745 * decisions. 756 746 */ 757 - if (tz->trips.critical.flags.enabled) 758 - tz->state.critical = 1; 759 - if (tz->trips.hot.flags.enabled) 760 - tz->state.hot = 1; 761 - if (tz->trips.passive.flags.enabled) 762 - tz->state.passive = 1; 747 + tz->state.critical = tz->trips.critical.flags.enabled; 748 + tz->state.hot = tz->trips.hot.flags.enabled; 749 + tz->state.passive = tz->trips.passive.flags.enabled; 750 + tz->state.active = 0; 763 751 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) 764 - if (tz->trips.active[i].flags.enabled) 765 - tz->state.active = 1; 752 + tz->state.active |= tz->trips.active[i].flags.enabled; 766 753 767 754 /* 768 755 * Calculate Sleep Time