aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIlia Mirkin <imirkin@alum.mit.edu>2018-04-22 17:47:12 -0400
committerBen Skeggs <bskeggs@redhat.com>2018-05-18 03:09:48 -0400
commit7a22c737faef99d6f75d7049c1a2f6f0fdefb1ec (patch)
tree8eeff3baea6bc61d55d48b73202a09d2496be3f7
parentf43cda5c76922777f4fe5026ee5984364ae5a918 (diff)
drm/nouveau: fix temp/pwm visibility, skip hwmon when no sensors exist
A NV34 GPU was seeing temp and pwm entries in hwmon, which would error out when read. These should not have been visible, but also the whole hwmon object should just not have been registered in the first place. Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu> Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_hwmon.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_hwmon.c b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
index 7c965648df80..44178b4c3599 100644
--- a/drivers/gpu/drm/nouveau/nouveau_hwmon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
@@ -327,7 +327,7 @@ nouveau_temp_is_visible(const void *data, u32 attr, int channel)
327 struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data); 327 struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
328 struct nvkm_therm *therm = nvxx_therm(&drm->client.device); 328 struct nvkm_therm *therm = nvxx_therm(&drm->client.device);
329 329
330 if (therm && therm->attr_get && nvkm_therm_temp_get(therm) < 0) 330 if (!therm || !therm->attr_get || nvkm_therm_temp_get(therm) < 0)
331 return 0; 331 return 0;
332 332
333 switch (attr) { 333 switch (attr) {
@@ -351,8 +351,8 @@ nouveau_pwm_is_visible(const void *data, u32 attr, int channel)
351 struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data); 351 struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
352 struct nvkm_therm *therm = nvxx_therm(&drm->client.device); 352 struct nvkm_therm *therm = nvxx_therm(&drm->client.device);
353 353
354 if (therm && therm->attr_get && therm->fan_get && 354 if (!therm || !therm->attr_get || !therm->fan_get ||
355 therm->fan_get(therm) < 0) 355 therm->fan_get(therm) < 0)
356 return 0; 356 return 0;
357 357
358 switch (attr) { 358 switch (attr) {
@@ -707,13 +707,20 @@ nouveau_hwmon_init(struct drm_device *dev)
707{ 707{
708#if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE)) 708#if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE))
709 struct nouveau_drm *drm = nouveau_drm(dev); 709 struct nouveau_drm *drm = nouveau_drm(dev);
710 struct nvkm_iccsense *iccsense = nvxx_iccsense(&drm->client.device);
710 struct nvkm_therm *therm = nvxx_therm(&drm->client.device); 711 struct nvkm_therm *therm = nvxx_therm(&drm->client.device);
712 struct nvkm_volt *volt = nvxx_volt(&drm->client.device);
711 const struct attribute_group *special_groups[N_ATTR_GROUPS]; 713 const struct attribute_group *special_groups[N_ATTR_GROUPS];
712 struct nouveau_hwmon *hwmon; 714 struct nouveau_hwmon *hwmon;
713 struct device *hwmon_dev; 715 struct device *hwmon_dev;
714 int ret = 0; 716 int ret = 0;
715 int i = 0; 717 int i = 0;
716 718
719 if (!iccsense && !therm && !volt) {
720 NV_DEBUG(drm, "Skipping hwmon registration\n");
721 return 0;
722 }
723
717 hwmon = drm->hwmon = kzalloc(sizeof(*hwmon), GFP_KERNEL); 724 hwmon = drm->hwmon = kzalloc(sizeof(*hwmon), GFP_KERNEL);
718 if (!hwmon) 725 if (!hwmon)
719 return -ENOMEM; 726 return -ENOMEM;
@@ -749,6 +756,9 @@ nouveau_hwmon_fini(struct drm_device *dev)
749#if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE)) 756#if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE))
750 struct nouveau_hwmon *hwmon = nouveau_hwmon(dev); 757 struct nouveau_hwmon *hwmon = nouveau_hwmon(dev);
751 758
759 if (!hwmon)
760 return;
761
752 if (hwmon->hwmon) 762 if (hwmon->hwmon)
753 hwmon_device_unregister(hwmon->hwmon); 763 hwmon_device_unregister(hwmon->hwmon);
754 764