drm/sysfs: fix hotplug regression since lifetime changes

Linux-MTD Mailing List linux-mtd at lists.infradead.org
Fri Nov 22 17:59:11 EST 2013


Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=760c960bd6880cf22a57c0af9ff60c96250aad39
Commit:     760c960bd6880cf22a57c0af9ff60c96250aad39
Parent:     c3bddbda36a74225ad3d04aaa9600a25aff6b98b
Author:     David Herrmann <dh.herrmann at gmail.com>
AuthorDate: Thu Nov 21 20:50:50 2013 +1000
Committer:  Dave Airlie <airlied at gmail.com>
CommitDate: Thu Nov 21 21:10:00 2013 +1000

    drm/sysfs: fix hotplug regression since lifetime changes
    
    airlied:
    The lifetime changes introduced in 5bdebb183c9702a8c57a01dff09337be3de337a6
    tried to use device_create, however that led to the regression where dev->type
    wasn't getting set correctly. First attempt at fixing it would have led to
    a race, so this undoes the device_createa work and does it all manually
    making sure the dev->type is setup before we register the device.
    
    Signed-off-by: David Herrmann <dh.herrmann at gmail.com>
    Signed-off-by: Dave Airlie <airlied at redhat.com>
---
 drivers/gpu/drm/drm_sysfs.c | 40 +++++++++++++++++++++++++++++++++-------
 1 file changed, 33 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
index 1a35ea5..bd2bca3 100644
--- a/drivers/gpu/drm/drm_sysfs.c
+++ b/drivers/gpu/drm/drm_sysfs.c
@@ -489,6 +489,11 @@ void drm_sysfs_hotplug_event(struct drm_device *dev)
 }
 EXPORT_SYMBOL(drm_sysfs_hotplug_event);
 
+static void drm_sysfs_release(struct device *dev)
+{
+	kfree(dev);
+}
+
 /**
  * drm_sysfs_device_add - adds a class device to sysfs for a character driver
  * @dev: DRM device to be added
@@ -501,6 +506,7 @@ EXPORT_SYMBOL(drm_sysfs_hotplug_event);
 int drm_sysfs_device_add(struct drm_minor *minor)
 {
 	char *minor_str;
+	int r;
 
 	if (minor->type == DRM_MINOR_CONTROL)
 		minor_str = "controlD%d";
@@ -509,14 +515,34 @@ int drm_sysfs_device_add(struct drm_minor *minor)
         else
                 minor_str = "card%d";
 
-	minor->kdev = device_create(drm_class, minor->dev->dev,
-				    MKDEV(DRM_MAJOR, minor->index),
-				    minor, minor_str, minor->index);
-	if (IS_ERR(minor->kdev)) {
-		DRM_ERROR("device create failed %ld\n", PTR_ERR(minor->kdev));
-		return PTR_ERR(minor->kdev);
+	minor->kdev = kzalloc(sizeof(*minor->kdev), GFP_KERNEL);
+	if (!minor->dev) {
+		r = -ENOMEM;
+		goto error;
 	}
+
+	device_initialize(minor->kdev);
+	minor->kdev->devt = MKDEV(DRM_MAJOR, minor->index);
+	minor->kdev->class = drm_class;
+	minor->kdev->type = &drm_sysfs_device_minor;
+	minor->kdev->parent = minor->dev->dev;
+	minor->kdev->release = drm_sysfs_release;
+	dev_set_drvdata(minor->kdev, minor);
+
+	r = dev_set_name(minor->kdev, minor_str, minor->index);
+	if (r < 0)
+		goto error;
+
+	r = device_add(minor->kdev);
+	if (r < 0)
+		goto error;
+
 	return 0;
+
+error:
+	DRM_ERROR("device create failed %d\n", r);
+	put_device(minor->kdev);
+	return r;
 }
 
 /**
@@ -529,7 +555,7 @@ int drm_sysfs_device_add(struct drm_minor *minor)
 void drm_sysfs_device_remove(struct drm_minor *minor)
 {
 	if (minor->kdev)
-		device_destroy(drm_class, MKDEV(DRM_MAJOR, minor->index));
+		device_unregister(minor->kdev);
 	minor->kdev = NULL;
 }
 



More information about the linux-mtd-cvs mailing list