Пример #1
0
int
nouveau_therm_fan_user_set(struct nouveau_therm *therm, int percent)
{
	struct nouveau_therm_priv *priv = (void *)therm;

	if (priv->mode != NOUVEAU_THERM_CTRL_MANUAL)
		return -EINVAL;

	return nouveau_therm_fan_set(therm, true, percent);
}
Пример #2
0
int
nouveau_therm_fan_user_set(struct nouveau_therm *therm, int percent)
{
	struct nouveau_therm_priv *priv = (void *)therm;

	if (priv->fan.mode != FAN_CONTROL_MANUAL)
		return -EINVAL;

	return nouveau_therm_fan_set(therm, percent);
}
static void
nouveau_therm_update(struct nouveau_therm *therm, int mode)
{
	struct nouveau_timer *ptimer = nouveau_timer(therm);
	struct nouveau_therm_priv *priv = (void *)therm;
	unsigned long flags;
	bool immd = true;
	bool poll = true;
	int duty = -1;

	spin_lock_irqsave(&priv->lock, flags);
	if (mode < 0)
		mode = priv->mode;
	priv->mode = mode;

	switch (mode) {
	case NOUVEAU_THERM_CTRL_MANUAL:
		ptimer->alarm_cancel(ptimer, &priv->alarm);
		duty = nouveau_therm_fan_get(therm);
		if (duty < 0)
			duty = 100;
		poll = false;
		break;
	case NOUVEAU_THERM_CTRL_AUTO:
		switch(priv->fan->bios.fan_mode) {
		case NVBIOS_THERM_FAN_TRIP:
			duty = nouveau_therm_update_trip(therm);
			break;
		case NVBIOS_THERM_FAN_LINEAR:
			duty = nouveau_therm_update_linear(therm);
			break;
		case NVBIOS_THERM_FAN_OTHER:
			if (priv->cstate)
				duty = priv->cstate;
			poll = false;
			break;
		}
		immd = false;
		break;
	case NOUVEAU_THERM_CTRL_NONE:
	default:
		ptimer->alarm_cancel(ptimer, &priv->alarm);
		poll = false;
	}

	if (list_empty(&priv->alarm.head) && poll)
		ptimer->alarm(ptimer, 1000000000ULL, &priv->alarm);
	spin_unlock_irqrestore(&priv->lock, flags);

	if (duty >= 0) {
		nv_debug(therm, "FAN target request: %d%%\n", duty);
		nouveau_therm_fan_set(therm, immd, duty);
	}
}
Пример #4
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;
	}

}
Пример #5
0
static void
nouveau_therm_update(struct nouveau_therm *therm, int mode)
{
    struct nouveau_timer *ptimer = nouveau_timer(therm);
    struct nouveau_therm_priv *priv = (void *)therm;
    unsigned long flags;
    int duty;

    spin_lock_irqsave(&priv->lock, flags);
    nv_debug(therm, "FAN speed check\n");
    if (mode < 0)
        mode = priv->mode;
    priv->mode = mode;

    switch (mode) {
    case NOUVEAU_THERM_CTRL_MANUAL:
        ptimer->alarm_cancel(ptimer, &priv->alarm);
        duty = nouveau_therm_fan_get(therm);
        if (duty < 0)
            duty = 100;
        break;
    case NOUVEAU_THERM_CTRL_AUTO:
        if (priv->fan->bios.nr_fan_trip)
            duty = nouveau_therm_update_trip(therm);
        else
            duty = nouveau_therm_update_linear(therm);
        break;
    case NOUVEAU_THERM_CTRL_NONE:
    default:
        ptimer->alarm_cancel(ptimer, &priv->alarm);
        goto done;
    }

    nv_debug(therm, "FAN target request: %d%%\n", duty);
    nouveau_therm_fan_set(therm, (mode != NOUVEAU_THERM_CTRL_AUTO), duty);

done:
    if (list_empty(&priv->alarm.head) && (mode == NOUVEAU_THERM_CTRL_AUTO))
        ptimer->alarm(ptimer, 1000000000ULL, &priv->alarm);
    else if (!list_empty(&priv->alarm.head))
        nv_debug(therm, "therm fan alarm list is not empty\n");
    spin_unlock_irqrestore(&priv->lock, flags);
}
Пример #6
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;
}