예제 #1
0
int
nouveau_therm_create_(struct nouveau_object *parent,
                      struct nouveau_object *engine,
                      struct nouveau_oclass *oclass,
                      int length, void **pobject)
{
    struct nouveau_therm_priv *priv;
    int ret;

    ret = nouveau_subdev_create_(parent, engine, oclass, 0, "PTHERM",
                                 "therm", length, pobject);
    priv = *pobject;
    if (ret)
        return ret;

    nouveau_alarm_init(&priv->alarm, nouveau_therm_alarm);
    spin_lock_init(&priv->lock);
    spin_lock_init(&priv->sensor.alarm_program_lock);

    priv->base.fan_get = nouveau_therm_fan_user_get;
    priv->base.fan_set = nouveau_therm_fan_user_set;
    priv->base.fan_sense = nouveau_therm_fan_sense;
    priv->base.attr_get = nouveau_therm_attr_get;
    priv->base.attr_set = nouveau_therm_attr_set;
    priv->mode = priv->suspend = -1; /* undefined */
    return 0;
}
예제 #2
0
파일: fan.c 프로젝트: 383530895/linux
int
nouveau_therm_fan_ctor(struct nouveau_therm *therm)
{
	struct nouveau_therm_priv *priv = (void *)therm;
	struct nouveau_gpio *gpio = nouveau_gpio(therm);
	struct nouveau_bios *bios = nouveau_bios(therm);
	struct dcb_gpio_func func;
	int ret;

	/* attempt to locate a drivable fan, and determine control method */
	ret = gpio->find(gpio, 0, DCB_GPIO_FAN, 0xff, &func);
	if (ret == 0) {
		/* FIXME: is this really the place to perform such checks ? */
		if (func.line != 16 && func.log[0] & DCB_GPIO_LOG_DIR_IN) {
			nv_debug(therm, "GPIO_FAN is in input mode\n");
			ret = -EINVAL;
		} else {
			ret = nouveau_fanpwm_create(therm, &func);
			if (ret != 0)
				ret = nouveau_fantog_create(therm, &func);
		}
	}

	/* no controllable fan found, create a dummy fan module */
	if (ret != 0) {
		ret = nouveau_fannil_create(therm);
		if (ret)
			return ret;
	}

	nv_info(therm, "FAN control: %s\n", priv->fan->type);

	/* read the current speed, it is useful when resuming */
	priv->fan->percent = nouveau_therm_fan_get(therm);

	/* attempt to detect a tachometer connection */
	ret = gpio->find(gpio, 0, DCB_GPIO_FAN_SENSE, 0xff, &priv->fan->tach);
	if (ret)
		priv->fan->tach.func = DCB_GPIO_UNUSED;

	/* initialise fan bump/slow update handling */
	priv->fan->parent = therm;
	nouveau_alarm_init(&priv->fan->alarm, nouveau_fan_alarm);
	spin_lock_init(&priv->fan->lock);

	/* other random init... */
	nouveau_therm_fan_set_defaults(therm);
	nvbios_perf_fan_parse(bios, &priv->fan->perf);
	if (!nvbios_fan_parse(bios, &priv->fan->bios)) {
		nv_debug(therm, "parsing the fan table failed\n");
		if (nvbios_therm_fan_parse(bios, &priv->fan->bios))
			nv_error(therm, "parsing both fan tables failed\n");
	}
	nouveau_therm_fan_safety_checks(therm);
	return 0;
}
예제 #3
0
파일: temp.c 프로젝트: 24hours/linux
int
nouveau_therm_sensor_ctor(struct nouveau_therm *therm)
{
	struct nouveau_therm_priv *priv = (void *)therm;
	struct nouveau_bios *bios = nouveau_bios(therm);

	nouveau_alarm_init(&priv->sensor.therm_poll_alarm, alarm_timer_callback);

	nouveau_therm_temp_set_defaults(therm);
	if (nvbios_therm_sensor_parse(bios, NVBIOS_THERM_DOMAIN_CORE,
				      &priv->bios_sensor))
		nv_error(therm, "nvbios_therm_sensor_parse failed\n");
	nouveau_therm_temp_safety_checks(therm);

	return 0;
}