static void cpu_fans_tick()

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;
		}
	}
}