summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/nouveau/core/subdev/therm/base.c
diff options
context:
space:
mode:
authorMartin Peres <martin.peres@labri.fr>2013-08-12 02:48:52 (GMT)
committerBen Skeggs <bskeggs@redhat.com>2013-09-04 03:46:52 (GMT)
commitc4a62a766062c268d08c1aacf2e18e057e277db4 (patch)
tree381ecbe9bcdc9c009e359720a281b235c78e8760 /drivers/gpu/drm/nouveau/core/subdev/therm/base.c
parentb925a75d6729cec8debd0c378b354d8c228b36aa (diff)
downloadlinux-fsl-qoriq-c4a62a766062c268d08c1aacf2e18e057e277db4.tar.xz
drm/nouveau/therm: survive to suspend/resume cycles
Therm uses 3 ptimer alarms. Two to drive the fan and one for polling the temperature. When suspending/resuming, alarms will never be fired. As we are checking if there isn't an alarm pending before rescheduling another one, we end up never checking temperature or updating the fan speed. This commit also adds debug messages to be able to spot more easily if this case happens again in the future. Sorry for the spam if you activate the debug level though. Tested-by: Dash Four <mr.dash.four@googlemail.com> v2: - fix temperature polling too Signed-off-by: Martin Peres <martin.peres@labri.fr> Tested-by: Martin Peres <martin.peres@labri.fr> Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/core/subdev/therm/base.c')
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/therm/base.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/base.c b/drivers/gpu/drm/nouveau/core/subdev/therm/base.c
index 2ada3d7..f1de7a9 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/therm/base.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/therm/base.c
@@ -95,12 +95,14 @@ nouveau_therm_update(struct nouveau_therm *therm, int mode)
int duty;
spin_lock_irqsave(&priv->lock, flags);
+ nv_debug(therm, "FAN speed check\n");
if (mode < 0)
mode = priv->mode;
priv->mode = mode;
switch (mode) {
case NOUVEAU_THERM_CTRL_MANUAL:
+ ptimer->alarm_cancel(ptimer, &priv->alarm);
duty = nouveau_therm_fan_get(therm);
if (duty < 0)
duty = 100;
@@ -113,6 +115,7 @@ nouveau_therm_update(struct nouveau_therm *therm, int mode)
break;
case NOUVEAU_THERM_CTRL_NONE:
default:
+ ptimer->alarm_cancel(ptimer, &priv->alarm);
goto done;
}
@@ -122,6 +125,8 @@ nouveau_therm_update(struct nouveau_therm *therm, int mode)
done:
if (list_empty(&priv->alarm.head) && (mode == NOUVEAU_THERM_CTRL_AUTO))
ptimer->alarm(ptimer, 1000000000ULL, &priv->alarm);
+ else if (!list_empty(&priv->alarm.head))
+ nv_debug(therm, "therm fan alarm list is not empty\n");
spin_unlock_irqrestore(&priv->lock, flags);
}
@@ -274,7 +279,8 @@ _nouveau_therm_init(struct nouveau_object *object)
nouveau_therm_fan_mode(therm, priv->suspend);
}
- priv->sensor.program_alarms(therm);
+ nouveau_therm_sensor_init(therm);
+ nouveau_therm_fan_init(therm);
return 0;
}
@@ -284,6 +290,8 @@ _nouveau_therm_fini(struct nouveau_object *object, bool suspend)
struct nouveau_therm *therm = (void *)object;
struct nouveau_therm_priv *priv = (void *)therm;
+ nouveau_therm_fan_fini(therm, suspend);
+ nouveau_therm_sensor_fini(therm, suspend);
if (suspend) {
priv->suspend = priv->mode;
priv->mode = NOUVEAU_THERM_CTRL_NONE;