summaryrefslogtreecommitdiff
path: root/drivers/gpu
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 17:09:48 +1000
commit7a22c737faef99d6f75d7049c1a2f6f0fdefb1ec (patch)
tree8eeff3baea6bc61d55d48b73202a09d2496be3f7 /drivers/gpu
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>
Diffstat (limited to 'drivers/gpu')
-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)
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)
+ if (!therm || !therm->attr_get || nvkm_therm_temp_get(therm) < 0)
return 0;
switch (attr) {
@@ -351,8 +351,8 @@ 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)
+ if (!therm || !therm->attr_get || !therm->fan_get ||
+ therm->fan_get(therm) < 0)
return 0;
switch (attr) {
@@ -707,13 +707,20 @@ nouveau_hwmon_init(struct drm_device *dev)
{
#if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE))
struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nvkm_iccsense *iccsense = nvxx_iccsense(&drm->client.device);
struct nvkm_therm *therm = nvxx_therm(&drm->client.device);
+ struct nvkm_volt *volt = nvxx_volt(&drm->client.device);
const struct attribute_group *special_groups[N_ATTR_GROUPS];
struct nouveau_hwmon *hwmon;
struct device *hwmon_dev;
int ret = 0;
int i = 0;
+ if (!iccsense && !therm && !volt) {
+ NV_DEBUG(drm, "Skipping hwmon registration\n");
+ return 0;
+ }
+
hwmon = drm->hwmon = kzalloc(sizeof(*hwmon), GFP_KERNEL);
if (!hwmon)
return -ENOMEM;
@@ -749,6 +756,9 @@ nouveau_hwmon_fini(struct drm_device *dev)
#if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE))
struct nouveau_hwmon *hwmon = nouveau_hwmon(dev);
+ if (!hwmon)
+ return;
+
if (hwmon->hwmon)
hwmon_device_unregister(hwmon->hwmon);