in windfarm_pm112.c [266:342]
static void cpu_fans_tick(void)
{
int err, cpu;
s32 greatest_delta = 0;
s32 temp, power, t_max = 0;
int i, t, target = 0;
struct wf_sensor *sr;
struct wf_control *ct;
struct wf_cpu_pid_state *sp;
DBG_LOTS(KERN_DEBUG);
for (cpu = 0; cpu < nr_cores; ++cpu) {
/* Get CPU core temperature */
sr = sens_cpu_temp[cpu];
err = sr->ops->get_value(sr, &temp);
if (err) {
DBG("\n");
printk(KERN_WARNING "windfarm: CPU %d temperature "
"sensor error %d\n", cpu, err);
failure_state |= FAILURE_SENSOR;
cpu_max_all_fans();
return;
}
/* Keep track of highest temp */
t_max = max(t_max, temp);
/* Get CPU power */
sr = sens_cpu_power[cpu];
err = sr->ops->get_value(sr, &power);
if (err) {
DBG("\n");
printk(KERN_WARNING "windfarm: CPU %d power "
"sensor error %d\n", cpu, err);
failure_state |= FAILURE_SENSOR;
cpu_max_all_fans();
return;
}
/* Run PID */
sp = &cpu_pid[cpu];
t = wf_cpu_pid_run(sp, power, temp);
if (cpu == 0 || sp->last_delta > greatest_delta) {
greatest_delta = sp->last_delta;
target = t;
}
DBG_LOTS("[%d] P=%d.%.3d T=%d.%.3d ",
cpu, FIX32TOPRINT(power), FIX32TOPRINT(temp));
}
DBG_LOTS("fans = %d, t_max = %d.%03d\n", target, FIX32TOPRINT(t_max));
/* Darwin limits decrease to 20 per iteration */
if (target < (cpu_last_target - 20))
target = cpu_last_target - 20;
cpu_last_target = target;
for (cpu = 0; cpu < nr_cores; ++cpu)
cpu_pid[cpu].target = target;
/* Handle possible overtemps */
if (cpu_check_overtemp(t_max))
return;
/* Set fans */
for (i = 0; i < NR_CPU_FANS; ++i) {
ct = cpu_fans[i];
if (ct == NULL)
continue;
err = ct->ops->set_value(ct, target * cpu_fan_scale[i] / 100);
if (err) {
printk(KERN_WARNING "windfarm: fan %s reports "
"error %d\n", ct->name, err);
failure_state |= FAILURE_FAN;
break;
}
}
}