9 #include <linux/types.h>
10 #include <linux/errno.h>
11 #include <linux/kernel.h>
12 #include <linux/device.h>
14 #include <linux/reboot.h>
28 #define DBG(args...) printk(args)
30 #define DBG(args...) do { } while(0)
34 #define DBG_LOTS(args...) printk(args)
36 #define DBG_LOTS(args...) do { } while(0)
42 #undef HACKED_OVERTEMP
46 #define NR_CPU_FANS 3 * NR_CHIPS
62 #define CPU_TEMP_HIST_SIZE 180
68 static int cpu_thist_pt;
69 static s64 cpu_thist_total;
70 static s32 cpu_all_tmax = 100 << 16;
72 static int backside_tick;
74 static int slots_tick;
75 static int slots_speed;
77 static int dimms_output_clamp;
80 static bool have_all_controls;
81 static bool have_all_sensors;
84 static int failure_state;
85 #define FAILURE_SENSOR 1
87 #define FAILURE_PERM 4
88 #define FAILURE_LOW_OVERTEMP 8
89 #define FAILURE_HIGH_OVERTEMP 16
92 #define LOW_OVER_AVERAGE 0
93 #define LOW_OVER_IMMEDIATE (10 << 16)
94 #define LOW_OVER_CLEAR ((-10) << 16)
95 #define HIGH_OVER_IMMEDIATE (14 << 16)
96 #define HIGH_OVER_AVERAGE (10 << 16)
97 #define HIGH_OVER_IMMEDIATE (14 << 16)
100 static void cpu_max_all_fans(
void)
109 wf_control_set_max(cpufreq_clamp);
110 for (i = 0; i < nr_chips; i++) {
112 wf_control_set_max(cpu_fans[i][0]);
114 wf_control_set_max(cpu_fans[i][1]);
116 wf_control_set_max(cpu_fans[i][2]);
120 static int cpu_check_overtemp(
s32 temp)
124 static bool first =
true;
137 " immediate CPU temperature !\n");
150 cpu_thist_total +=
temp;
159 t_old = cpu_thist[cpu_thist_pt];
160 cpu_thist[cpu_thist_pt] =
temp;
162 cpu_thist_total -= t_old;
163 cpu_thist_total +=
temp;
166 DBG_LOTS(
" t_avg = %d.%03d (out: %d.%03d, in: %d.%03d)\n",
180 " average CPU temperature !\n");
191 if ((failure_state & new_state) != new_state)
197 failure_state &= ~FAILURE_LOW_OVERTEMP;
203 static int read_one_cpu_vals(
int cpu,
s32 *temp,
s32 *power)
205 s32 dtemp, volts, amps;
209 rc = wf_sensor_get(sens_cpu_temp[cpu], &dtemp);
211 DBG(
" CPU%d: temp reading error !\n", cpu);
218 rc = wf_sensor_get(sens_cpu_volts[cpu], &volts);
220 DBG(
" CPU%d, volts reading error !\n", cpu);
226 rc = wf_sensor_get(sens_cpu_amps[cpu], &s);
228 DBG(
" CPU%d, current reading error !\n", cpu);
238 *power = (((
u64)volts) * ((
u64)amps)) >> 16;
246 static void cpu_fans_tick(
void)
251 DBG_LOTS(
"* cpu fans_tick_split()\n");
253 for (cpu = 0; cpu < nr_chips; ++
cpu) {
257 wf_control_get(cpu_fans[cpu][0], &sp->
target);
259 err = read_one_cpu_vals(cpu, &temp, &power);
267 t_max =
max(t_max, temp);
270 if (cpu_check_overtemp(t_max))
279 speed =
max(sp->
target, dimms_output_clamp);
282 for (i = 0; i < 3; i++) {
283 err = wf_control_set(cpu_fans[cpu][i], speed);
285 pr_warning(
"wf_rm31: Fan %s reports error %d\n",
286 cpu_fans[cpu][i]->
name, err);
294 static int cpu_setup_pid(
int cpu)
299 int fmin, fmax,
hsize;
302 tmax = mpu->
tmax << 16;
306 DBG(
"wf_72: CPU%d ttarget = %d.%03d, tmax = %d.%03d\n",
310 if (tmax < cpu_all_tmax)
314 fmin = wf_control_get_min(cpu_fans[cpu][0]);
315 fmax = wf_control_get_max(cpu_fans[cpu][0]);
316 DBG(
"wf_72: CPU%d max RPM range = [%d..%d]\n", cpu, fmin, fmax);
320 DBG(
"wf_72: CPU%d history size = %d\n", cpu, hsize);
330 pid.pmaxadj = ptarget;
335 cpu_pid[
cpu].target = 4000;
366 static void backside_fan_tick(
void)
369 int speed, dspeed, fan_min;
372 if (!backside_fan || !backside_temp || !dimms_temp || !backside_tick)
374 if (--backside_tick > 0)
376 backside_tick = backside_pid.param.interval;
381 err = wf_control_get(backside_fan, &speed);
383 backside_pid.target = speed;
385 err = wf_sensor_get(backside_temp, &temp);
390 wf_control_set_max(backside_fan);
395 DBG_LOTS(
"backside PID temp=%d.%.3d speed=%d\n",
398 err = wf_sensor_get(dimms_temp, &dtemp);
403 wf_control_set_max(backside_fan);
407 dimms_output_clamp = dspeed;
409 fan_min = (dspeed * 100) / 14000;
410 fan_min =
max(fan_min, backside_param.
min);
411 speed =
max(speed, fan_min);
413 err = wf_control_set(backside_fan, speed);
420 static void backside_setup_pid(
void)
423 s32 fmin = wf_control_get_min(backside_fan);
424 s32 fmax = wf_control_get_max(backside_fan);
427 param = backside_param;
428 param.
min =
max(param.min, fmin);
429 param.max =
min(param.max, fmax);
437 pr_info(
"wf_rm31: Backside control loop started.\n");
453 static void slots_fan_tick(
void)
459 if (!slots_fan || !slots_temp || !slots_tick)
461 if (--slots_tick > 0)
463 slots_tick = slots_pid.param.interval;
467 err = wf_sensor_get(slots_temp, &temp);
469 pr_warning(
"wf_rm31: slots temp sensor error %d\n", err);
471 wf_control_set_max(slots_fan);
476 DBG_LOTS(
"slots PID temp=%d.%.3d speed=%d\n",
480 err = wf_control_set(slots_fan, speed);
487 static void slots_setup_pid(
void)
490 s32 fmin = wf_control_get_min(slots_fan);
491 s32 fmax = wf_control_get_max(slots_fan);
499 pr_info(
"wf_rm31: Slots control loop started.\n");
502 static void set_fail_state(
void)
507 wf_control_set_max(backside_fan);
509 wf_control_set_max(slots_fan);
512 static void rm31_tick(
void)
519 for (i = 0; i < nr_chips; ++
i) {
520 if (cpu_setup_pid(i) < 0) {
528 backside_setup_pid();
531 #ifdef HACKED_OVERTEMP
532 cpu_all_tmax = 60 << 16;
544 last_failure = failure_state;
554 DBG_LOTS(
" last_failure: 0x%x, failure_state: %x\n",
555 last_failure, failure_state);
558 if (failure_state && last_failure == 0 && cpufreq_clamp)
559 wf_control_set_max(cpufreq_clamp);
560 if (failure_state == 0 && last_failure && cpufreq_clamp)
561 wf_control_set_min(cpufreq_clamp);
602 have_all_controls = all_controls;
611 sens_cpu_temp[0] =
sr;
612 else if (!
strcmp(sr->
name,
"cpu-diode-temp-1"))
613 sens_cpu_temp[1] =
sr;
615 sens_cpu_volts[0] =
sr;
617 sens_cpu_volts[1] =
sr;
619 sens_cpu_amps[0] =
sr;
621 sens_cpu_amps[1] =
sr;
642 have_all_sensors = all_sensors;
650 rm31_new_sensor(data);
653 rm31_new_control(data);
656 if (have_all_controls && have_all_sensors)
663 .notifier_call = rm31_wf_notify,
681 .probe = wf_rm31_probe,
682 .remove = wf_rm31_remove,
689 static int __init wf_rm31_init(
void)
704 pr_info(
"windfarm: Initializing for desktop G5 with %d chips\n",
708 for (i = 0; i < nr_chips; i++) {
709 cpu_mpu_data[
i] = wf_get_mpu(i);
710 if (!cpu_mpu_data[i]) {
711 pr_err(
"wf_rm31: Failed to find MPU data for CPU %d\n", i);
717 request_module(
"windfarm_fcu_controls");
718 request_module(
"windfarm_lm75_sensor");
719 request_module(
"windfarm_lm87_sensor");
720 request_module(
"windfarm_ad7417_sensor");
721 request_module(
"windfarm_max6690_sensor");
722 request_module(
"windfarm_cpufreq_clamp");
729 static void __exit wf_rm31_exit(
void)