summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/nouveau
diff options
context:
space:
mode:
authorOscar Salvador <osalvador.vilardaga@gmail.com>2017-05-18 23:24:35 +0200
committerBen Skeggs <bskeggs@redhat.com>2017-06-16 14:05:02 +1000
commitdbddaaf083e255958eee9debb441fb49f3dfc0e9 (patch)
tree586a2c2f0185300f6af60e37de459f7eae57c45c /drivers/gpu/drm/nouveau
parent02e9722da85246c748894734961fbfe0e543c66d (diff)
drm/nouveau/hwmon: Add nouveau_hwmon_ops structure with .is_visible/.read_string
This patch introduces the nouveau_hwmon_ops structure, sets up .is_visible and .read_string operations and adds all the functions for these operations. This is also a preparation for the next patches, where most of the work is being done. This code doesn't interacture with the old one. It's just to make easier the review of all patches. Signed-off-by: Oscar Salvador <osalvador.vilardaga@gmail.com> Reviewed-by: Martin Peres <martin.peres@free.fr> Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_hwmon.c163
1 files changed, 163 insertions, 0 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_hwmon.c b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
index 24b40c5f0836..5ae3107d73df 100644
--- a/drivers/gpu/drm/nouveau/nouveau_hwmon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
@@ -764,6 +764,169 @@ static const struct hwmon_channel_info *nouveau_info[] = {
&nouveau_power,
NULL
};
+
+static umode_t
+nouveau_chip_is_visible(const void *data, u32 attr, int channel)
+{
+ switch (attr) {
+ case hwmon_chip_update_interval:
+ return 0444;
+ default:
+ return 0;
+ }
+}
+
+static umode_t
+nouveau_power_is_visible(const void *data, u32 attr, int channel)
+{
+ struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
+ struct nvkm_iccsense *iccsense = nvxx_iccsense(&drm->client.device);
+
+ if (!iccsense || !iccsense->data_valid || list_empty(&iccsense->rails))
+ return 0;
+
+ switch (attr) {
+ case hwmon_power_input:
+ return 0444;
+ case hwmon_power_max:
+ if (iccsense->power_w_max)
+ return 0444;
+ return 0;
+ case hwmon_power_crit:
+ if (iccsense->power_w_crit)
+ return 0444;
+ return 0;
+ default:
+ return 0;
+ }
+}
+
+static umode_t
+nouveau_temp_is_visible(const void *data, u32 attr, int channel)
+{
+ struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
+ struct nvkm_therm *therm = nvxx_therm(&drm->client.device);
+
+ if (therm && therm->attr_get && nvkm_therm_temp_get(therm) < 0)
+ return 0;
+
+ switch (attr) {
+ case hwmon_temp_input:
+ case hwmon_temp_max:
+ case hwmon_temp_max_hyst:
+ case hwmon_temp_crit:
+ case hwmon_temp_crit_hyst:
+ case hwmon_temp_emergency:
+ case hwmon_temp_emergency_hyst:
+ return 0444;
+ default:
+ return 0;
+ }
+}
+
+static umode_t
+nouveau_pwm_is_visible(const void *data, u32 attr, int channel)
+{
+ struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
+ struct nvkm_therm *therm = nvxx_therm(&drm->client.device);
+
+ if (therm && therm->attr_get && therm->fan_get &&
+ therm->fan_get(therm) < 0)
+ return 0;
+
+ switch (attr) {
+ case hwmon_pwm_enable:
+ case hwmon_pwm_input:
+ return 0644;
+ default:
+ return 0;
+ }
+}
+
+static umode_t
+nouveau_input_is_visible(const void *data, u32 attr, int channel)
+{
+ struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
+ struct nvkm_volt *volt = nvxx_volt(&drm->client.device);
+
+ if (!volt || nvkm_volt_get(volt) < 0)
+ return 0;
+
+ switch (attr) {
+ case hwmon_in_input:
+ case hwmon_in_label:
+ case hwmon_in_min:
+ case hwmon_in_max:
+ return 0444;
+ default:
+ return 0;
+ }
+}
+
+static umode_t
+nouveau_fan_is_visible(const void *data, u32 attr, int channel)
+{
+ struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
+ struct nvkm_therm *therm = nvxx_therm(&drm->client.device);
+
+ if (!therm || !therm->attr_get || nvkm_therm_fan_sense(therm) < 0)
+ return 0;
+
+ switch (attr) {
+ case hwmon_fan_input:
+ return 0444;
+ default:
+ return 0;
+ }
+}
+
+static umode_t
+nouveau_is_visible(const void *data, enum hwmon_sensor_types type, u32 attr,
+ int channel)
+{
+ switch (type) {
+ case hwmon_chip:
+ return nouveau_chip_is_visible(data, attr, channel);
+ case hwmon_temp:
+ return nouveau_temp_is_visible(data, attr, channel);
+ case hwmon_fan:
+ return nouveau_fan_is_visible(data, attr, channel);
+ case hwmon_in:
+ return nouveau_input_is_visible(data, attr, channel);
+ case hwmon_pwm:
+ return nouveau_pwm_is_visible(data, attr, channel);
+ case hwmon_power:
+ return nouveau_power_is_visible(data, attr, channel);
+ default:
+ return 0;
+ }
+}
+
+static const char input_label[] = "GPU core";
+
+static int
+nouveau_read_string(struct device *dev, enum hwmon_sensor_types type, u32 attr,
+ int channel, const char **buf)
+{
+ if (type == hwmon_in && attr == hwmon_in_label) {
+ *buf = input_label;
+ return 0;
+ }
+
+ return -EOPNOTSUPP;
+}
+
+static const struct hwmon_ops nouveau_hwmon_ops = {
+ .is_visible = nouveau_is_visible,
+ .read = NULL,
+ .read_string = nouveau_read_string,
+ .write = NULL,
+};
+
+static const struct hwmon_chip_info nouveau_chip_info = {
+ .ops = &nouveau_hwmon_ops,
+ .info = nouveau_info,
+};
#endif
int