static void wf_smu_tick(void)
{
    unsigned int last_failure = wf_smu_failure_state;
    unsigned int new_failure;

    if (!wf_smu_started) {
        DBG("wf: creating control loops !\n");
        wf_smu_create_drive_fans();
        wf_smu_create_slots_fans();
        wf_smu_create_cpu_fans();
        wf_smu_started = 1;
    }

    /* Skipping ticks */
    if (wf_smu_skipping && --wf_smu_skipping)
        return;

    wf_smu_failure_state = 0;
    if (wf_smu_drive_fans)
        wf_smu_drive_fans_tick(wf_smu_drive_fans);
    if (wf_smu_slots_fans)
        wf_smu_slots_fans_tick(wf_smu_slots_fans);
    if (wf_smu_cpu_fans)
        wf_smu_cpu_fans_tick(wf_smu_cpu_fans);

    wf_smu_readjust = 0;
    new_failure = wf_smu_failure_state & ~last_failure;

    /* If entering failure mode, clamp cpufreq and ramp all
     * fans to full speed.
     */
    if (wf_smu_failure_state && !last_failure) {
        if (cpufreq_clamp)
            wf_control_set_max(cpufreq_clamp);
        if (fan_cpu_main)
            wf_control_set_max(fan_cpu_main);
        if (fan_cpu_second)
            wf_control_set_max(fan_cpu_second);
        if (fan_cpu_third)
            wf_control_set_max(fan_cpu_third);
        if (fan_hd)
            wf_control_set_max(fan_hd);
        if (fan_slots)
            wf_control_set_max(fan_slots);
    }

    /* If leaving failure mode, unclamp cpufreq and readjust
     * all fans on next iteration
     */
    if (!wf_smu_failure_state && last_failure) {
        if (cpufreq_clamp)
            wf_control_set_min(cpufreq_clamp);
        wf_smu_readjust = 1;
    }

    /* Overtemp condition detected, notify and start skipping a couple
     * ticks to let the temperature go down
     */
    if (new_failure & FAILURE_OVERTEMP) {
        wf_set_overtemp();
        wf_smu_skipping = 2;
    }

    /* We only clear the overtemp condition if overtemp is cleared
     * _and_ no other failure is present. Since a sensor error will
     * clear the overtemp condition (can't measure temperature) at
     * the control loop levels, but we don't want to keep it clear
     * here in this case
     */
    if (new_failure == 0 && last_failure & FAILURE_OVERTEMP)
        wf_clear_overtemp();
}
Esempio n. 2
0
static void wf_smu_tick(void)
{
	unsigned int last_failure = wf_smu_failure_state;
	unsigned int new_failure;

	if (!wf_smu_started) {
		DBG("wf: creating control loops !\n");
		wf_smu_create_drive_fans();
		wf_smu_create_slots_fans();
		wf_smu_create_cpu_fans();
		wf_smu_started = 1;
	}

	
	if (wf_smu_skipping && --wf_smu_skipping)
		return;

	wf_smu_failure_state = 0;
	if (wf_smu_drive_fans)
		wf_smu_drive_fans_tick(wf_smu_drive_fans);
	if (wf_smu_slots_fans)
		wf_smu_slots_fans_tick(wf_smu_slots_fans);
	if (wf_smu_cpu_fans)
		wf_smu_cpu_fans_tick(wf_smu_cpu_fans);

	wf_smu_readjust = 0;
	new_failure = wf_smu_failure_state & ~last_failure;

	
	if (wf_smu_failure_state && !last_failure) {
		if (cpufreq_clamp)
			wf_control_set_max(cpufreq_clamp);
		if (fan_cpu_main)
			wf_control_set_max(fan_cpu_main);
		if (fan_cpu_second)
			wf_control_set_max(fan_cpu_second);
		if (fan_cpu_third)
			wf_control_set_max(fan_cpu_third);
		if (fan_hd)
			wf_control_set_max(fan_hd);
		if (fan_slots)
			wf_control_set_max(fan_slots);
	}

	
	if (!wf_smu_failure_state && last_failure) {
		if (cpufreq_clamp)
			wf_control_set_min(cpufreq_clamp);
		wf_smu_readjust = 1;
	}

	
	if (new_failure & FAILURE_OVERTEMP) {
		wf_set_overtemp();
		wf_smu_skipping = 2;
	}

	
	if (new_failure == 0 && last_failure & FAILURE_OVERTEMP)
		wf_clear_overtemp();
}