Skip to content

Commit

Permalink
drm: Fix sysfs device confusion.
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Thomas Hellstrom authored and Dave Airlie committed Aug 21, 2009
1 parent e3b2415 commit 08e4d53
Showing 1 changed file with 29 additions and 22 deletions.
51 changes: 29 additions & 22 deletions drivers/gpu/drm/drm_sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,44 +22,50 @@
#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;
}

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit 08e4d53

Please sign in to comment.