Commit 4bb297113433048169c30a32c1e58b6a1b61b621

Authored by Aaro Koskinen
Committed by Benjamin Herrenschmidt
1 parent 9bf41be673

powerpc/windfarm: Fix overtemperature clearing

With pm81/pm91/pm121, when the overtemperature state is entered, and
when it remains on after skipped ticks, the driver will try to leave
it too soon (immediately on the next tick). This is because the active
FAILURE_OVERTEMP state is not visible in "new_failure" variable of the
current tick. Furthermore, the driver will keep trying to clear condition
in subsequent ticks as FAILURE_OVERTEMP remains set in the "last_failure"
variable. These will start to trigger WARNINGS from windfarm core:

[  100.082735] windfarm: Clamping CPU frequency to minimum !
[  100.108132] windfarm: Overtemp condition detected !
[  101.952908] windfarm: Overtemp condition cleared !
[...]
[  102.980388] WARNING: at drivers/macintosh/windfarm_core.c:463
[...]
[  103.982227] WARNING: at drivers/macintosh/windfarm_core.c:463
[...]
[  105.030494] WARNING: at drivers/macintosh/windfarm_core.c:463
[...]
[  105.973666] WARNING: at drivers/macintosh/windfarm_core.c:463
[...]
[  106.977913] WARNING: at drivers/macintosh/windfarm_core.c:463

Fix by adding a helper global variable. We leave the overtemp state only
after all failure bits have been cleared.

I saw this error on iMac G5 iSight (pm121). Also pm81/pm91 are fixed
based on the observation that these are almost identical/copy-pasted code.

Signed-off-by: Aaro Koskinen <aaro.koskinen@iki.fi>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>

Showing 3 changed files with 15 additions and 3 deletions Side-by-side Diff

drivers/macintosh/windfarm_pm121.c
... ... @@ -276,6 +276,7 @@
276 276  
277 277 static unsigned int pm121_failure_state;
278 278 static int pm121_readjust, pm121_skipping;
  279 +static bool pm121_overtemp;
279 280 static s32 average_power;
280 281  
281 282 struct pm121_correction {
... ... @@ -847,6 +848,7 @@
847 848 if (new_failure & FAILURE_OVERTEMP) {
848 849 wf_set_overtemp();
849 850 pm121_skipping = 2;
  851 + pm121_overtemp = true;
850 852 }
851 853  
852 854 /* We only clear the overtemp condition if overtemp is cleared
853 855  
... ... @@ -855,8 +857,10 @@
855 857 * the control loop levels, but we don't want to keep it clear
856 858 * here in this case
857 859 */
858   - if (new_failure == 0 && last_failure & FAILURE_OVERTEMP)
  860 + if (!pm121_failure_state && pm121_overtemp) {
859 861 wf_clear_overtemp();
  862 + pm121_overtemp = false;
  863 + }
860 864 }
861 865  
862 866  
drivers/macintosh/windfarm_pm81.c
... ... @@ -149,6 +149,7 @@
149 149  
150 150 static unsigned int wf_smu_failure_state;
151 151 static int wf_smu_readjust, wf_smu_skipping;
  152 +static bool wf_smu_overtemp;
152 153  
153 154 /*
154 155 * ****** System Fans Control Loop ******
... ... @@ -593,6 +594,7 @@
593 594 if (new_failure & FAILURE_OVERTEMP) {
594 595 wf_set_overtemp();
595 596 wf_smu_skipping = 2;
  597 + wf_smu_overtemp = true;
596 598 }
597 599  
598 600 /* We only clear the overtemp condition if overtemp is cleared
599 601  
... ... @@ -601,8 +603,10 @@
601 603 * the control loop levels, but we don't want to keep it clear
602 604 * here in this case
603 605 */
604   - if (new_failure == 0 && last_failure & FAILURE_OVERTEMP)
  606 + if (!wf_smu_failure_state && wf_smu_overtemp) {
605 607 wf_clear_overtemp();
  608 + wf_smu_overtemp = false;
  609 + }
606 610 }
607 611  
608 612 static void wf_smu_new_control(struct wf_control *ct)
drivers/macintosh/windfarm_pm91.c
... ... @@ -76,6 +76,7 @@
76 76  
77 77 /* Set to kick the control loop into life */
78 78 static int wf_smu_all_controls_ok, wf_smu_all_sensors_ok, wf_smu_started;
  79 +static bool wf_smu_overtemp;
79 80  
80 81 /* Failure handling.. could be nicer */
81 82 #define FAILURE_FAN 0x01
... ... @@ -517,6 +518,7 @@
517 518 if (new_failure & FAILURE_OVERTEMP) {
518 519 wf_set_overtemp();
519 520 wf_smu_skipping = 2;
  521 + wf_smu_overtemp = true;
520 522 }
521 523  
522 524 /* We only clear the overtemp condition if overtemp is cleared
523 525  
... ... @@ -525,8 +527,10 @@
525 527 * the control loop levels, but we don't want to keep it clear
526 528 * here in this case
527 529 */
528   - if (new_failure == 0 && last_failure & FAILURE_OVERTEMP)
  530 + if (!wf_smu_failure_state && wf_smu_overtemp) {
529 531 wf_clear_overtemp();
  532 + wf_smu_overtemp = false;
  533 + }
530 534 }
531 535  
532 536