30 #include <linux/types.h>
31 #include <linux/errno.h>
32 #include <linux/kernel.h>
34 #include <linux/slab.h>
37 #include <linux/wait.h>
39 #include <linux/device.h>
42 #include <asm/machdep.h>
44 #include <asm/sections.h>
55 #define DBG(args...) printk(args)
57 #define DBG(args...) do { } while(0)
63 #undef HACKED_OVERTEMP
66 static struct wf_sensor *sensor_cpu_power;
69 static struct wf_sensor *sensor_slots_power;
78 static int wf_smu_all_controls_ok, wf_smu_all_sensors_ok, wf_smu_started;
81 #define FAILURE_FAN 0x01
82 #define FAILURE_SENSOR 0x02
83 #define FAILURE_OVERTEMP 0x04
85 static unsigned int wf_smu_failure_state;
86 static int wf_smu_readjust, wf_smu_skipping;
94 #define WF_SMU_CPU_FANS_INTERVAL 1
95 #define WF_SMU_CPU_FANS_MAX_HISTORY 16
141 static void wf_smu_create_cpu_fans(
void)
147 s32 tmax, tdelta, maxpow, powadj;
171 if (wf_smu_cpu_fans ==
NULL)
173 wf_smu_cpu_fans->
ticks = 1;
183 pid_param.gd = piddata->
gd;
184 pid_param.gp = piddata->
gp;
185 pid_param.gr = piddata->
gr / pid_param.history_len;
191 pid_param.tmax = tmax;
192 pid_param.ttarget = tmax - tdelta;
193 pid_param.pmaxadj = maxpow - powadj;
195 pid_param.min = wf_control_get_min(fan_cpu_main);
196 pid_param.max = wf_control_get_max(fan_cpu_main);
200 DBG(
"wf: CPU Fan control initialized.\n");
201 DBG(
" ttarged=%d.%03d, tmax=%d.%03d, min=%d RPM, max=%d RPM\n",
203 pid_param.min, pid_param.max);
209 "for this machine model, max fan speed\n");
212 wf_control_set_max(cpufreq_clamp);
214 wf_control_set_max(fan_cpu_main);
222 if (--st->
ticks != 0) {
229 rc = wf_sensor_get(sensor_cpu_temp, &temp);
237 rc = wf_sensor_get(sensor_cpu_power, &power);
245 DBG(
"wf_smu: CPU Fans tick ! CPU temp: %d.%03d, power: %d.%03d\n",
248 #ifdef HACKED_OVERTEMP
252 if (temp > st->
pid.param.tmax)
257 DBG(
"wf_smu: new_setpoint: %d RPM\n", (
int)new_setpoint);
263 if (fan_cpu_main && wf_smu_failure_state == 0) {
271 if (fan_cpu_second && wf_smu_failure_state == 0) {
279 if (fan_cpu_third && wf_smu_failure_state == 0) {
289 static void wf_smu_create_drive_fans(
void)
297 .itarget = 0x00200000,
303 if (wf_smu_drive_fans ==
NULL) {
308 wf_smu_drive_fans->
ticks = 1;
312 param.
min = wf_control_get_min(fan_hd);
313 param.
max = wf_control_get_max(fan_hd);
316 DBG(
"wf: Drive Fan control initialized.\n");
317 DBG(
" itarged=%d.%03d, min=%d RPM, max=%d RPM\n",
323 wf_control_set_max(fan_hd);
331 if (--st->
ticks != 0) {
338 rc = wf_sensor_get(sensor_hd_temp, &temp);
346 DBG(
"wf_smu: Drive Fans tick ! HD temp: %d.%03d\n",
349 if (temp > (st->
pid.param.itarget + 0x50000))
354 DBG(
"wf_smu: new_setpoint: %d\n", (
int)new_setpoint);
360 if (fan_hd && wf_smu_failure_state == 0) {
361 rc = wf_control_set(fan_hd, st->
setpoint);
370 static void wf_smu_create_slots_fans(
void)
378 .itarget = 0x00000000
384 if (wf_smu_slots_fans ==
NULL) {
389 wf_smu_slots_fans->
ticks = 1;
393 param.
min = wf_control_get_min(fan_slots);
394 param.
max = wf_control_get_max(fan_slots);
397 DBG(
"wf: Slots Fan control initialized.\n");
398 DBG(
" itarged=%d.%03d, min=%d RPM, max=%d RPM\n",
404 wf_control_set_max(fan_slots);
409 s32 new_setpoint, power;
412 if (--st->
ticks != 0) {
419 rc = wf_sensor_get(sensor_slots_power, &power);
427 DBG(
"wf_smu: Slots Fans tick ! Slots power: %d.%03d\n",
431 if (power > (st->
pid.param.itarget + 0x50000))
437 DBG(
"wf_smu: new_setpoint: %d\n", (
int)new_setpoint);
443 if (fan_slots && wf_smu_failure_state == 0) {
444 rc = wf_control_set(fan_slots, st->
setpoint);
459 static void wf_smu_tick(
void)
461 unsigned int last_failure = wf_smu_failure_state;
462 unsigned int new_failure;
464 if (!wf_smu_started) {
465 DBG(
"wf: creating control loops !\n");
466 wf_smu_create_drive_fans();
467 wf_smu_create_slots_fans();
468 wf_smu_create_cpu_fans();
473 if (wf_smu_skipping && --wf_smu_skipping)
476 wf_smu_failure_state = 0;
477 if (wf_smu_drive_fans)
478 wf_smu_drive_fans_tick(wf_smu_drive_fans);
479 if (wf_smu_slots_fans)
480 wf_smu_slots_fans_tick(wf_smu_slots_fans);
482 wf_smu_cpu_fans_tick(wf_smu_cpu_fans);
485 new_failure = wf_smu_failure_state & ~last_failure;
490 if (wf_smu_failure_state && !last_failure) {
492 wf_control_set_max(cpufreq_clamp);
494 wf_control_set_max(fan_cpu_main);
496 wf_control_set_max(fan_cpu_second);
498 wf_control_set_max(fan_cpu_third);
500 wf_control_set_max(fan_hd);
502 wf_control_set_max(fan_slots);
508 if (!wf_smu_failure_state && last_failure) {
510 wf_control_set_min(cpufreq_clamp);
528 if (new_failure == 0 && last_failure & FAILURE_OVERTEMP)
535 if (wf_smu_all_controls_ok)
538 if (fan_cpu_main ==
NULL && !
strcmp(ct->
name,
"cpu-rear-fan-0")) {
543 if (fan_cpu_second ==
NULL && !
strcmp(ct->
name,
"cpu-rear-fan-1")) {
548 if (fan_cpu_third ==
NULL && !
strcmp(ct->
name,
"cpu-front-fan-0")) {
553 if (cpufreq_clamp ==
NULL && !
strcmp(ct->
name,
"cpufreq-clamp")) {
568 if (fan_cpu_main && (fan_cpu_second || fan_cpu_third) && fan_hd &&
569 fan_slots && cpufreq_clamp)
570 wf_smu_all_controls_ok = 1;
573 static void wf_smu_new_sensor(
struct wf_sensor *
sr)
575 if (wf_smu_all_sensors_ok)
580 sensor_cpu_power =
sr;
585 sensor_cpu_temp =
sr;
593 if (sensor_slots_power ==
NULL && !
strcmp(sr->
name,
"slots-power")) {
595 sensor_slots_power =
sr;
598 if (sensor_cpu_power && sensor_cpu_temp &&
599 sensor_hd_temp && sensor_slots_power)
600 wf_smu_all_sensors_ok = 1;
609 DBG(
"wf: new control %s detected\n",
611 wf_smu_new_control(data);
615 DBG(
"wf: new sensor %s detected\n",
617 wf_smu_new_sensor(data);
620 if (wf_smu_all_controls_ok && wf_smu_all_sensors_ok)
628 .notifier_call = wf_smu_notify,
631 static int wf_init_pm(
void)
662 if (sensor_cpu_power)
668 if (sensor_slots_power)
686 kfree(wf_smu_slots_fans);
687 kfree(wf_smu_drive_fans);
688 kfree(wf_smu_cpu_fans);
694 .probe = wf_smu_probe,
703 static int __init wf_smu_init(
void)
712 request_module(
"windfarm_smu_controls");
713 request_module(
"windfarm_smu_sensors");
714 request_module(
"windfarm_lm75_sensor");
715 request_module(
"windfarm_cpufreq_clamp");
724 static void __exit wf_smu_exit(
void)