Commit 1cbf4c563c0eaaf11c552a88b374e213181c6ddd

Authored by Thomas Renninger
Committed by Len Brown
1 parent d2149b5423

[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>

Showing 2 changed files with 108 additions and 93 deletions Side-by-side Diff

drivers/acpi/processor_thermal.c
... ... @@ -101,10 +101,8 @@
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)
  104 + if (!acpi_thermal_cpufreq_is_init || cpufreq_get_policy(&policy, cpu))
105 105 return -ENODEV;
106   - if (!cpufreq_get_policy(&policy, cpu))
107   - return -ENODEV;
108 106 return 0;
109 107 }
110 108  
111 109  
... ... @@ -127,13 +125,13 @@
127 125 if (!cpu_has_cpufreq(cpu))
128 126 return -ENODEV;
129 127  
130   - if (cpufreq_thermal_reduction_pctg[cpu] >= 20) {
  128 + if (cpufreq_thermal_reduction_pctg[cpu] > 20)
131 129 cpufreq_thermal_reduction_pctg[cpu] -= 20;
132   - cpufreq_update_policy(cpu);
133   - return 0;
134   - }
135   -
136   - return -ERANGE;
  130 + else
  131 + cpufreq_thermal_reduction_pctg[cpu] = 0;
  132 + cpufreq_update_policy(cpu);
  133 + /* We reached max freq again and can leave passive mode */
  134 + return !cpufreq_thermal_reduction_pctg[cpu];
137 135 }
138 136  
139 137 static int acpi_thermal_cpufreq_notifier(struct notifier_block *nb,
... ... @@ -200,7 +198,7 @@
200 198 int result = 0;
201 199 struct acpi_processor *pr = NULL;
202 200 struct acpi_device *device = NULL;
203   - int tx = 0;
  201 + int tx = 0, max_tx_px = 0;
204 202  
205 203 ACPI_FUNCTION_TRACE("acpi_processor_set_thermal_limit");
206 204  
207 205  
208 206  
209 207  
... ... @@ -259,19 +257,27 @@
259 257 /* if going down: T-states first, P-states later */
260 258  
261 259 if (pr->flags.throttling) {
262   - if (tx == 0)
  260 + if (tx == 0) {
  261 + max_tx_px = 1;
263 262 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
264 263 "At minimum throttling state\n"));
265   - else {
  264 + } else {
266 265 tx--;
267 266 goto end;
268 267 }
269 268 }
270 269  
271 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 276 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
274 277 "At minimum performance state\n"));
  278 + max_tx_px = 1;
  279 + } else
  280 + max_tx_px = 0;
275 281  
276 282 break;
277 283 }
... ... @@ -290,8 +296,10 @@
290 296 pr->limit.thermal.px, pr->limit.thermal.tx));
291 297 } else
292 298 result = 0;
293   -
294   - return_VALUE(result);
  299 + if (max_tx_px)
  300 + return_VALUE(1);
  301 + else
  302 + return_VALUE(result);
295 303 }
296 304  
297 305 int acpi_processor_get_limit_info(struct acpi_processor *pr)
drivers/acpi/thermal.c
... ... @@ -72,7 +72,7 @@
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  
79 79  
... ... @@ -517,9 +517,9 @@
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,7 +527,7 @@
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,7 +547,7 @@
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++)
554 554  
... ... @@ -556,12 +556,32 @@
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 /*
568 588  
569 589  
... ... @@ -571,23 +591,21 @@
571 591 * and avoid thrashing around the passive trip point. Note that we
572 592 * assume symmetry.
573 593 */
574   - else if (tz->trips.passive.flags.enabled) {
575   - for (i = 0; i < passive->devices.count; i++)
576   - result =
577   - acpi_processor_set_thermal_limit(passive->devices.
578   - handles[i],
579   - ACPI_PROCESSOR_LIMIT_DECREMENT);
580   - if (result == 1) {
581   - tz->trips.passive.flags.enabled = 0;
582   - ACPI_DEBUG_PRINT((ACPI_DB_INFO,
583   - "Disabling passive cooling (zone is cool)\n"));
584   - }
  594 + if (!passive->flags.enabled)
  595 + return;
  596 + for (i = 0; i < passive->devices.count; i++)
  597 + if (!acpi_processor_set_thermal_limit
  598 + (passive->devices.handles[i],
  599 + ACPI_PROCESSOR_LIMIT_DECREMENT))
  600 + result = 0;
  601 + if (result) {
  602 + passive->flags.enabled = 0;
  603 + ACPI_DEBUG_PRINT((ACPI_DB_INFO,
  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 610 int result = 0;
593 611 struct acpi_thermal_active *active = NULL;
594 612  
595 613  
596 614  
597 615  
598 616  
599 617  
600 618  
601 619  
602 620  
603 621  
604 622  
... ... @@ -598,74 +616,66 @@
598 616 ACPI_FUNCTION_TRACE("acpi_thermal_active");
599 617  
600 618 if (!tz)
601   - return_VALUE(-EINVAL);
  619 + return;
602 620  
603 621 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
604   -
605 622 active = &(tz->trips.active[i]);
606 623 if (!active || !active->flags.valid)
607 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 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 632 if (active->temperature > maxtemp)
617   - tz->state.active_index = i, maxtemp =
618   - active->temperature;
619   - if (!active->flags.enabled) {
620   - for (j = 0; j < active->devices.count; j++) {
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) {
  633 + tz->state.active_index = i;
  634 + maxtemp = active->temperature;
  635 + if (active->flags.enabled)
  636 + continue;
648 637 for (j = 0; j < active->devices.count; j++) {
649 638 result =
650 639 acpi_bus_set_power(active->devices.
651 640 handles[j],
652   - ACPI_STATE_D3);
  641 + ACPI_STATE_D0);
653 642 if (result) {
654 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 645 active->devices.
657 646 handles[j]));
658 647 continue;
659 648 }
660   - active->flags.enabled = 0;
  649 + active->flags.enabled = 1;
661 650 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
662   - "Cooling device [%p] now 'off'\n",
  651 + "Cooling device [%p] now 'on'\n",
663 652 active->devices.handles[j]));
664 653 }
  654 + continue;
665 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]));
  677 + }
666 678 }
667   -
668   - return_VALUE(0);
669 679 }
670 680  
671 681 static void acpi_thermal_check(void *context);
672 682  
... ... @@ -744,15 +754,12 @@
744 754 * Again, separated from the above two to allow independent policy
745 755 * decisions.
746 756 */
747   - if (tz->trips.critical.flags.enabled)
748   - tz->state.critical = 1;
749   - if (tz->trips.hot.flags.enabled)
750   - tz->state.hot = 1;
751   - if (tz->trips.passive.flags.enabled)
752   - tz->state.passive = 1;
  757 + tz->state.critical = tz->trips.critical.flags.enabled;
  758 + tz->state.hot = tz->trips.hot.flags.enabled;
  759 + tz->state.passive = tz->trips.passive.flags.enabled;
  760 + tz->state.active = 0;
753 761 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++)
754   - if (tz->trips.active[i].flags.enabled)
755   - tz->state.active = 1;
  762 + tz->state.active |= tz->trips.active[i].flags.enabled;
756 763  
757 764 /*
758 765 * Calculate Sleep Time