drm/nouveau/therm: use workqueue to shutdown the machine
authorMarcin Slusarz <marcin.slusarz@gmail.com>
Sun, 3 Feb 2013 18:28:14 +0000 (19:28 +0100)
committerBen Skeggs <bskeggs@redhat.com>
Wed, 20 Feb 2013 06:00:42 +0000 (16:00 +1000)
orderly_poweroff cannot be called from atomic context.

Signed-off-by: Marcin Slusarz <marcin.slusarz@gmail.com>
Acked-by: Martin Peres <martin.peres@labri.fr>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/core/subdev/therm/temp.c

index 8f27b44db4daae4cda836e687707a31a887d990c..b37624af82977543142f7035a2f2ba7b8a89cc63 100644 (file)
@@ -90,6 +90,13 @@ nouveau_therm_sensor_get_threshold_state(struct nouveau_therm *therm,
        return priv->sensor.alarm_state[thrs];
 }
 
+static void
+nv_poweroff_work(struct work_struct *work)
+{
+       orderly_poweroff(true);
+       kfree(work);
+}
+
 void nouveau_therm_sensor_event(struct nouveau_therm *therm,
                                enum nouveau_therm_thrs thrs,
                                enum nouveau_therm_thrs_direction dir)
@@ -128,8 +135,15 @@ void nouveau_therm_sensor_event(struct nouveau_therm *therm,
                        priv->emergency.pause(therm, active);
                break;
        case NOUVEAU_THERM_THRS_SHUTDOWN:
-               if (active)
-                       orderly_poweroff(true);
+               if (active) {
+                       struct work_struct *work;
+
+                       work = kmalloc(sizeof(*work), GFP_ATOMIC);
+                       if (work) {
+                               INIT_WORK(work, nv_poweroff_work);
+                               schedule_work(work);
+                       }
+               }
                break;
        case NOUVEAU_THERM_THRS_NR:
                break;