drm: Fix sysfs device confusion.
authorThomas Hellstrom <thellstrom@vmware.com>
Thu, 20 Aug 2009 09:02:31 +0000 (19:02 +1000)
committerDave Airlie <airlied@redhat.com>
Fri, 21 Aug 2009 00:01:59 +0000 (10:01 +1000)
The drm sysfs class suspend / resume methods could not distinguish
between different device types wich could lead to illegal type casts.

Use struct device_type and make sure the class suspend / resume callbacks
are aware of those. There is no per device-type suspend / resume. Only
new-style PM.

Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Dave Airlie <airlied@redhat.com>
drivers/gpu/drm/drm_sysfs.c

index 85ec31b..f7a615b 100644 (file)
 #define to_drm_minor(d) container_of(d, struct drm_minor, kdev)
 #define to_drm_connector(d) container_of(d, struct drm_connector, kdev)
 
+static struct device_type drm_sysfs_device_minor = {
+       .name = "drm_minor"
+};
+
 /**
- * drm_sysfs_suspend - DRM class suspend hook
+ * drm_class_suspend - DRM class suspend hook
  * @dev: Linux device to suspend
  * @state: power state to enter
  *
  * Just figures out what the actual struct drm_device associated with
  * @dev is and calls its suspend hook, if present.
  */
-static int drm_sysfs_suspend(struct device *dev, pm_message_t state)
+static int drm_class_suspend(struct device *dev, pm_message_t state)
 {
-       struct drm_minor *drm_minor = to_drm_minor(dev);
-       struct drm_device *drm_dev = drm_minor->dev;
-
-       if (drm_minor->type == DRM_MINOR_LEGACY &&
-           !drm_core_check_feature(drm_dev, DRIVER_MODESET) &&
-           drm_dev->driver->suspend)
-               return drm_dev->driver->suspend(drm_dev, state);
-
+       if (dev->type == &drm_sysfs_device_minor) {
+               struct drm_minor *drm_minor = to_drm_minor(dev);
+               struct drm_device *drm_dev = drm_minor->dev;
+
+               if (drm_minor->type == DRM_MINOR_LEGACY &&
+                   !drm_core_check_feature(drm_dev, DRIVER_MODESET) &&
+                   drm_dev->driver->suspend)
+                       return drm_dev->driver->suspend(drm_dev, state);
+       }
        return 0;
 }
 
 /**
- * drm_sysfs_resume - DRM class resume hook
+ * drm_class_resume - DRM class resume hook
  * @dev: Linux device to resume
  *
  * Just figures out what the actual struct drm_device associated with
  * @dev is and calls its resume hook, if present.
  */
-static int drm_sysfs_resume(struct device *dev)
+static int drm_class_resume(struct device *dev)
 {
-       struct drm_minor *drm_minor = to_drm_minor(dev);
-       struct drm_device *drm_dev = drm_minor->dev;
-
-       if (drm_minor->type == DRM_MINOR_LEGACY &&
-           !drm_core_check_feature(drm_dev, DRIVER_MODESET) &&
-           drm_dev->driver->resume)
-               return drm_dev->driver->resume(drm_dev);
-
+       if (dev->type == &drm_sysfs_device_minor) {
+               struct drm_minor *drm_minor = to_drm_minor(dev);
+               struct drm_device *drm_dev = drm_minor->dev;
+
+               if (drm_minor->type == DRM_MINOR_LEGACY &&
+                   !drm_core_check_feature(drm_dev, DRIVER_MODESET) &&
+                   drm_dev->driver->resume)
+                       return drm_dev->driver->resume(drm_dev);
+       }
        return 0;
 }
 
@@ -99,8 +105,8 @@ struct class *drm_sysfs_create(struct module *owner, char *name)
                goto err_out;
        }
 
-       class->suspend = drm_sysfs_suspend;
-       class->resume = drm_sysfs_resume;
+       class->suspend = drm_class_suspend;
+       class->resume = drm_class_resume;
 
        err = class_create_file(class, &class_attr_version);
        if (err)
@@ -480,6 +486,7 @@ int drm_sysfs_device_add(struct drm_minor *minor)
        minor->kdev.class = drm_class;
        minor->kdev.release = drm_sysfs_device_release;
        minor->kdev.devt = minor->device;
+       minor->kdev.type = &drm_sysfs_device_minor;
        if (minor->type == DRM_MINOR_CONTROL)
                minor_str = "controlD%d";
         else if (minor->type == DRM_MINOR_RENDER)