Beispiel #1
0
int
nouveau_therm_attr_set(struct nouveau_therm *therm,
                       enum nouveau_therm_attr_type type, int value)
{
    struct nouveau_therm_priv *priv = (void *)therm;

    switch (type) {
    case NOUVEAU_THERM_ATTR_FAN_MIN_DUTY:
        if (value < 0)
            value = 0;
        if (value > priv->fan->bios.max_duty)
            value = priv->fan->bios.max_duty;
        priv->fan->bios.min_duty = value;
        return 0;
    case NOUVEAU_THERM_ATTR_FAN_MAX_DUTY:
        if (value < 0)
            value = 0;
        if (value < priv->fan->bios.min_duty)
            value = priv->fan->bios.min_duty;
        priv->fan->bios.max_duty = value;
        return 0;
    case NOUVEAU_THERM_ATTR_FAN_MODE:
        return nouveau_therm_fan_mode(therm, value);
    case NOUVEAU_THERM_ATTR_THRS_FAN_BOOST:
        priv->bios_sensor.thrs_fan_boost.temp = value;
        priv->sensor.program_alarms(therm);
        return 0;
    case NOUVEAU_THERM_ATTR_THRS_FAN_BOOST_HYST:
        priv->bios_sensor.thrs_fan_boost.hysteresis = value;
        priv->sensor.program_alarms(therm);
        return 0;
    case NOUVEAU_THERM_ATTR_THRS_DOWN_CLK:
        priv->bios_sensor.thrs_down_clock.temp = value;
        priv->sensor.program_alarms(therm);
        return 0;
    case NOUVEAU_THERM_ATTR_THRS_DOWN_CLK_HYST:
        priv->bios_sensor.thrs_down_clock.hysteresis = value;
        priv->sensor.program_alarms(therm);
        return 0;
    case NOUVEAU_THERM_ATTR_THRS_CRITICAL:
        priv->bios_sensor.thrs_critical.temp = value;
        priv->sensor.program_alarms(therm);
        return 0;
    case NOUVEAU_THERM_ATTR_THRS_CRITICAL_HYST:
        priv->bios_sensor.thrs_critical.hysteresis = value;
        priv->sensor.program_alarms(therm);
        return 0;
    case NOUVEAU_THERM_ATTR_THRS_SHUTDOWN:
        priv->bios_sensor.thrs_shutdown.temp = value;
        priv->sensor.program_alarms(therm);
        return 0;
    case NOUVEAU_THERM_ATTR_THRS_SHUTDOWN_HYST:
        priv->bios_sensor.thrs_shutdown.hysteresis = value;
        priv->sensor.program_alarms(therm);
        return 0;
    }

    return -EINVAL;
}
Beispiel #2
0
int
nouveau_therm_preinit(struct nouveau_therm *therm)
{
    nouveau_therm_sensor_ctor(therm);
    nouveau_therm_ic_ctor(therm);
    nouveau_therm_fan_ctor(therm);

    nouveau_therm_fan_mode(therm, NOUVEAU_THERM_CTRL_NONE);
    nouveau_therm_sensor_preinit(therm);
    return 0;
}
Beispiel #3
0
void nouveau_therm_sensor_event(struct nouveau_therm *therm,
			        enum nouveau_therm_thrs thrs,
			        enum nouveau_therm_thrs_direction dir)
{
	struct nouveau_therm_priv *priv = (void *)therm;
	bool active;
	const char *thresolds[] = {
		"fanboost", "downclock", "critical", "shutdown"
	};
	int temperature = therm->temp_get(therm);

	if (thrs < 0 || thrs > 3)
		return;

	if (dir == NOUVEAU_THERM_THRS_FALLING)
		nv_info(therm, "temperature (%i C) went below the '%s' threshold\n",
			temperature, thresolds[thrs]);
	else
		nv_info(therm, "temperature (%i C) hit the '%s' threshold\n",
			temperature, thresolds[thrs]);

	active = (dir == NOUVEAU_THERM_THRS_RISING);
	switch (thrs) {
	case NOUVEAU_THERM_THRS_FANBOOST:
		if (active) {
			nouveau_therm_fan_set(therm, true, 100);
			nouveau_therm_fan_mode(therm, NOUVEAU_THERM_CTRL_AUTO);
		}
		break;
	case NOUVEAU_THERM_THRS_DOWNCLOCK:
		if (priv->emergency.downclock)
			priv->emergency.downclock(therm, active);
		break;
	case NOUVEAU_THERM_THRS_CRITICAL:
		if (priv->emergency.pause)
			priv->emergency.pause(therm, active);
		break;
	case NOUVEAU_THERM_THRS_SHUTDOWN:
		if (active) {
			struct work_struct *work;

			work = kmalloc(sizeof(*work), GFP_ATOMIC);
			if (work) {
				INIT_WORK(work, nv_poweroff_work);
				schedule_work(work);
			}
		}
		break;
	case NOUVEAU_THERM_THRS_NR:
		break;
	}

}
Beispiel #4
0
int
_nouveau_therm_init(struct nouveau_object *object)
{
    struct nouveau_therm *therm = (void *)object;
    struct nouveau_therm_priv *priv = (void *)therm;
    int ret;

    ret = nouveau_subdev_init(&therm->base);
    if (ret)
        return ret;

    if (priv->suspend >= 0) {
        /* restore the pwm value only when on manual or auto mode */
        if (priv->suspend > 0)
            nouveau_therm_fan_set(therm, true, priv->fan->percent);

        nouveau_therm_fan_mode(therm, priv->suspend);
    }
    nouveau_therm_sensor_init(therm);
    nouveau_therm_fan_init(therm);
    return 0;
}