drm/i915: Hookup chip reset in error handler
authorBen Gamari <bgamari.foss@gmail.com>
Mon, 14 Sep 2009 21:48:46 +0000 (17:48 -0400)
committerJesse Barnes <jbarnes@virtuousgeek.org>
Thu, 17 Sep 2009 21:36:30 +0000 (14:36 -0700)
This patch uses the previously introduced chip reset logic to reset the
chip when an error event is detected.

Signed-off-by: Ben Gamari <bgamari.foss@gmail.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
drivers/gpu/drm/i915/i915_irq.c

index 2a042bc..8f52766 100644 (file)
@@ -302,12 +302,25 @@ static void i915_error_work_func(struct work_struct *work)
        drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t,
                                                    error_work);
        struct drm_device *dev = dev_priv->dev;
-       char *event_string = "ERROR=1";
-       char *envp[] = { event_string, NULL };
+       char *error_event[] = { "ERROR=1", NULL };
+       char *reset_event[] = { "RESET=1", NULL };
+       char *reset_done_event[] = { "ERROR=0", NULL };
 
        DRM_DEBUG("generating error event\n");
+       kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, error_event);
 
-       kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, envp);
+       if (dev_priv->mm.wedged) {
+               if (IS_I965G(dev)) {
+                       DRM_DEBUG("resetting chip\n");
+                       kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, reset_event);
+                       if (!i965_reset(dev, GDRST_RENDER)) {
+                               dev_priv->mm.wedged = 0;
+                               kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, reset_done_event);
+                       }
+               } else {
+                       printk("reboot required\n");
+               }
+       }
 }
 
 /**