From cefc57d946fae202d4a1ad732be4fb3bb28998a7 Mon Sep 17 00:00:00 2001 From: Gianni Vialetto Date: Tue, 8 Jul 2014 13:08:57 +0200 Subject: [PATCH 1/2] Expose LINEAR_MIN and LINEAR_MAX as hwmon sysfs properties Signed-off-by: Gianni Vialetto --- .../gpu/drm/nouveau/core/include/subdev/therm.h | 2 + drivers/gpu/drm/nouveau/core/subdev/therm/base.c | 14 ++++ drivers/gpu/drm/nouveau/nouveau_sysfs.c | 81 +++++++++++++++++++++- 3 files changed, 95 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/therm.h b/drivers/gpu/drm/nouveau/core/include/subdev/therm.h index d4a6817..29ccf23 100644 --- a/drivers/gpu/drm/nouveau/core/include/subdev/therm.h +++ b/drivers/gpu/drm/nouveau/core/include/subdev/therm.h @@ -23,6 +23,8 @@ enum nouveau_therm_attr_type { NOUVEAU_THERM_ATTR_THRS_CRITICAL_HYST = 15, NOUVEAU_THERM_ATTR_THRS_SHUTDOWN = 16, NOUVEAU_THERM_ATTR_THRS_SHUTDOWN_HYST = 17, + NOUVEAU_THERM_ATTR_THRS_LINEAR_MIN = 18, + NOUVEAU_THERM_ATTR_THRS_LINEAR_MAX = 19, }; struct nouveau_therm { diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/base.c b/drivers/gpu/drm/nouveau/core/subdev/therm/base.c index 9ad01da..a56018f 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/therm/base.c +++ b/drivers/gpu/drm/nouveau/core/subdev/therm/base.c @@ -221,6 +221,10 @@ nouveau_therm_attr_get(struct nouveau_therm *therm, return priv->bios_sensor.thrs_shutdown.temp; case NOUVEAU_THERM_ATTR_THRS_SHUTDOWN_HYST: return priv->bios_sensor.thrs_shutdown.hysteresis; + case NOUVEAU_THERM_ATTR_THRS_LINEAR_MIN: + return priv->fan->bios.linear_min_temp; + case NOUVEAU_THERM_ATTR_THRS_LINEAR_MAX: + return priv->fan->bios.linear_max_temp; } return -EINVAL; @@ -281,6 +285,16 @@ nouveau_therm_attr_set(struct nouveau_therm *therm, priv->bios_sensor.thrs_shutdown.hysteresis = value; priv->sensor.program_alarms(therm); return 0; + case NOUVEAU_THERM_ATTR_THRS_LINEAR_MIN: + if (value < 0) + value = 0; + priv->fan->bios.linear_min_temp = value; + return 0; + case NOUVEAU_THERM_ATTR_THRS_LINEAR_MAX: + if (value < 0) + value = 0; + priv->fan->bios.linear_max_temp = value; + return 0; } return -EINVAL; diff --git a/drivers/gpu/drm/nouveau/nouveau_sysfs.c b/drivers/gpu/drm/nouveau/nouveau_sysfs.c index 75dda2b..0c8b499 100644 --- a/drivers/gpu/drm/nouveau/nouveau_sysfs.c +++ b/drivers/gpu/drm/nouveau/nouveau_sysfs.c @@ -123,10 +123,78 @@ nouveau_sysfs_pstate_set(struct device *d, struct device_attribute *a, return count; } - static DEVICE_ATTR(pstate, S_IRUGO | S_IWUSR, nouveau_sysfs_pstate_get, nouveau_sysfs_pstate_set); +static ssize_t +nouveau_sysfs_temp1_fan_linear_min_get(struct device *d, + struct device_attribute *a, + char *buf) +{ + struct drm_device *dev = dev_get_drvdata(d); + struct nouveau_drm *drm = nouveau_drm(dev); + struct nouveau_therm *therm = nouveau_therm(drm->device); + + return snprintf(buf, PAGE_SIZE, "%d\n", + therm->attr_get(therm, NOUVEAU_THERM_ATTR_THRS_LINEAR_MIN)); +} +static ssize_t +nouveau_sysfs_temp1_fan_linear_min_set(struct device *d, + struct device_attribute *a, + const char *buf, + size_t count) +{ + struct drm_device *dev = dev_get_drvdata(d); + struct nouveau_drm *drm = nouveau_drm(dev); + struct nouveau_therm *therm = nouveau_therm(drm->device); + long value; + + if (kstrtol(buf, 10, &value) == -EINVAL) + return count; + + therm->attr_set(therm, NOUVEAU_THERM_ATTR_THRS_LINEAR_MIN, value); + + return count; +} +static DEVICE_ATTR(temp1_fan_linear_min, S_IRUGO | S_IWUSR, + nouveau_sysfs_temp1_fan_linear_min_get, + nouveau_sysfs_temp1_fan_linear_min_set); + +static ssize_t +nouveau_sysfs_temp1_fan_linear_max_get(struct device *d, + struct device_attribute *a, + char *buf) +{ + struct drm_device *dev = dev_get_drvdata(d); + struct nouveau_drm *drm = nouveau_drm(dev); + struct nouveau_therm *therm = nouveau_therm(drm->device); + + return snprintf(buf, PAGE_SIZE, "%d\n", + therm->attr_get(therm, NOUVEAU_THERM_ATTR_THRS_LINEAR_MAX)); +} +static ssize_t +nouveau_sysfs_temp1_fan_linear_max_set(struct device *d, + struct device_attribute *a, + const char *buf, + size_t count) +{ + struct drm_device *dev = dev_get_drvdata(d); + struct nouveau_drm *drm = nouveau_drm(dev); + struct nouveau_therm *therm = nouveau_therm(drm->device); + long value; + + if (kstrtol(buf, 10, &value) == -EINVAL) + return count; + + therm->attr_set(therm, + NOUVEAU_THERM_ATTR_THRS_LINEAR_MAX, value / 1000); + + return count; +} +static DEVICE_ATTR(temp1_fan_linear_max, S_IRUGO | S_IWUSR, + nouveau_sysfs_temp1_fan_linear_max_get, + nouveau_sysfs_temp1_fan_linear_max_set); + void nouveau_sysfs_fini(struct drm_device *dev) { @@ -136,6 +204,10 @@ nouveau_sysfs_fini(struct drm_device *dev) if (sysfs->ctrl) { device_remove_file(nv_device_base(device), &dev_attr_pstate); + device_remove_file(nv_device_base(device), + &dev_attr_temp1_fan_linear_min); + device_remove_file(nv_device_base(device), + &dev_attr_temp1_fan_linear_max); nouveau_object_del(nv_object(drm), NVDRM_DEVICE, NVDRM_CONTROL); } @@ -157,8 +229,13 @@ nouveau_sysfs_init(struct drm_device *dev) ret = nouveau_object_new(nv_object(drm), NVDRM_DEVICE, NVDRM_CONTROL, NV_CONTROL_CLASS, NULL, 0, &sysfs->ctrl); - if (ret == 0) + if (ret == 0) { device_create_file(nv_device_base(device), &dev_attr_pstate); + device_create_file(nv_device_base(device), + &dev_attr_temp1_fan_linear_min); + device_create_file(nv_device_base(device), + &dev_attr_temp1_fan_linear_max); + } return 0; } -- 2.0.1