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