aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAaro Koskinen <aaro.koskinen@iki.fi>2013-06-30 15:00:42 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2013-06-30 21:10:34 -0400
commit4bb297113433048169c30a32c1e58b6a1b61b621 (patch)
treee278a2fc4cea6f1151f0e11ee4dc4f492fdc7cfb
parent9bf41be6737327b7c06cd3f210a0cb599f4aa790 (diff)
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>
-rw-r--r--drivers/macintosh/windfarm_pm121.c6
-rw-r--r--drivers/macintosh/windfarm_pm81.c6
-rw-r--r--drivers/macintosh/windfarm_pm91.c6
3 files changed, 15 insertions, 3 deletions
diff --git a/drivers/macintosh/windfarm_pm121.c b/drivers/macintosh/windfarm_pm121.c
index af605e915d41..7fe58b0ae8b4 100644
--- a/drivers/macintosh/windfarm_pm121.c
+++ b/drivers/macintosh/windfarm_pm121.c
@@ -276,6 +276,7 @@ static const char *loop_names[N_LOOPS] = {
276 276
277static unsigned int pm121_failure_state; 277static unsigned int pm121_failure_state;
278static int pm121_readjust, pm121_skipping; 278static int pm121_readjust, pm121_skipping;
279static bool pm121_overtemp;
279static s32 average_power; 280static s32 average_power;
280 281
281struct pm121_correction { 282struct pm121_correction {
@@ -847,6 +848,7 @@ static void pm121_tick(void)
847 if (new_failure & FAILURE_OVERTEMP) { 848 if (new_failure & FAILURE_OVERTEMP) {
848 wf_set_overtemp(); 849 wf_set_overtemp();
849 pm121_skipping = 2; 850 pm121_skipping = 2;
851 pm121_overtemp = true;
850 } 852 }
851 853
852 /* We only clear the overtemp condition if overtemp is cleared 854 /* We only clear the overtemp condition if overtemp is cleared
@@ -855,8 +857,10 @@ static void pm121_tick(void)
855 * the control loop levels, but we don't want to keep it clear 857 * the control loop levels, but we don't want to keep it clear
856 * here in this case 858 * here in this case
857 */ 859 */
858 if (new_failure == 0 && last_failure & FAILURE_OVERTEMP) 860 if (!pm121_failure_state && pm121_overtemp) {
859 wf_clear_overtemp(); 861 wf_clear_overtemp();
862 pm121_overtemp = false;
863 }
860} 864}
861 865
862 866
diff --git a/drivers/macintosh/windfarm_pm81.c b/drivers/macintosh/windfarm_pm81.c
index f84933ff3298..2a5e1b15b1d2 100644
--- a/drivers/macintosh/windfarm_pm81.c
+++ b/drivers/macintosh/windfarm_pm81.c
@@ -149,6 +149,7 @@ static int wf_smu_all_controls_ok, wf_smu_all_sensors_ok, wf_smu_started;
149 149
150static unsigned int wf_smu_failure_state; 150static unsigned int wf_smu_failure_state;
151static int wf_smu_readjust, wf_smu_skipping; 151static int wf_smu_readjust, wf_smu_skipping;
152static bool wf_smu_overtemp;
152 153
153/* 154/*
154 * ****** System Fans Control Loop ****** 155 * ****** System Fans Control Loop ******
@@ -593,6 +594,7 @@ static void wf_smu_tick(void)
593 if (new_failure & FAILURE_OVERTEMP) { 594 if (new_failure & FAILURE_OVERTEMP) {
594 wf_set_overtemp(); 595 wf_set_overtemp();
595 wf_smu_skipping = 2; 596 wf_smu_skipping = 2;
597 wf_smu_overtemp = true;
596 } 598 }
597 599
598 /* We only clear the overtemp condition if overtemp is cleared 600 /* We only clear the overtemp condition if overtemp is cleared
@@ -601,8 +603,10 @@ static void wf_smu_tick(void)
601 * the control loop levels, but we don't want to keep it clear 603 * the control loop levels, but we don't want to keep it clear
602 * here in this case 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 wf_clear_overtemp(); 607 wf_clear_overtemp();
608 wf_smu_overtemp = false;
609 }
606} 610}
607 611
608static void wf_smu_new_control(struct wf_control *ct) 612static void wf_smu_new_control(struct wf_control *ct)
diff --git a/drivers/macintosh/windfarm_pm91.c b/drivers/macintosh/windfarm_pm91.c
index 2eb484f213c8..a8ac66cd3b13 100644
--- a/drivers/macintosh/windfarm_pm91.c
+++ b/drivers/macintosh/windfarm_pm91.c
@@ -76,6 +76,7 @@ static struct wf_control *cpufreq_clamp;
76 76
77/* Set to kick the control loop into life */ 77/* Set to kick the control loop into life */
78static int wf_smu_all_controls_ok, wf_smu_all_sensors_ok, wf_smu_started; 78static int wf_smu_all_controls_ok, wf_smu_all_sensors_ok, wf_smu_started;
79static bool wf_smu_overtemp;
79 80
80/* Failure handling.. could be nicer */ 81/* Failure handling.. could be nicer */
81#define FAILURE_FAN 0x01 82#define FAILURE_FAN 0x01
@@ -517,6 +518,7 @@ static void wf_smu_tick(void)
517 if (new_failure & FAILURE_OVERTEMP) { 518 if (new_failure & FAILURE_OVERTEMP) {
518 wf_set_overtemp(); 519 wf_set_overtemp();
519 wf_smu_skipping = 2; 520 wf_smu_skipping = 2;
521 wf_smu_overtemp = true;
520 } 522 }
521 523
522 /* We only clear the overtemp condition if overtemp is cleared 524 /* We only clear the overtemp condition if overtemp is cleared
@@ -525,8 +527,10 @@ static void wf_smu_tick(void)
525 * the control loop levels, but we don't want to keep it clear 527 * the control loop levels, but we don't want to keep it clear
526 * here in this case 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 wf_clear_overtemp(); 531 wf_clear_overtemp();
532 wf_smu_overtemp = false;
533 }
530} 534}
531 535
532 536