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@gmail.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>

authored by David Herrmann and committed by Dave Airlie 760c960b c3bddbda

Changed files
+33 -7
drivers
gpu
+33 -7
drivers/gpu/drm/drm_sysfs.c
··· 489 489 } 490 490 EXPORT_SYMBOL(drm_sysfs_hotplug_event); 491 491 492 + static void drm_sysfs_release(struct device *dev) 493 + { 494 + kfree(dev); 495 + } 496 + 492 497 /** 493 498 * drm_sysfs_device_add - adds a class device to sysfs for a character driver 494 499 * @dev: DRM device to be added ··· 506 501 int drm_sysfs_device_add(struct drm_minor *minor) 507 502 { 508 503 char *minor_str; 504 + int r; 509 505 510 506 if (minor->type == DRM_MINOR_CONTROL) 511 507 minor_str = "controlD%d"; ··· 515 509 else 516 510 minor_str = "card%d"; 517 511 518 - minor->kdev = device_create(drm_class, minor->dev->dev, 519 - MKDEV(DRM_MAJOR, minor->index), 520 - minor, minor_str, minor->index); 521 - if (IS_ERR(minor->kdev)) { 522 - DRM_ERROR("device create failed %ld\n", PTR_ERR(minor->kdev)); 523 - return PTR_ERR(minor->kdev); 512 + minor->kdev = kzalloc(sizeof(*minor->kdev), GFP_KERNEL); 513 + if (!minor->dev) { 514 + r = -ENOMEM; 515 + goto error; 524 516 } 517 + 518 + device_initialize(minor->kdev); 519 + minor->kdev->devt = MKDEV(DRM_MAJOR, minor->index); 520 + minor->kdev->class = drm_class; 521 + minor->kdev->type = &drm_sysfs_device_minor; 522 + minor->kdev->parent = minor->dev->dev; 523 + minor->kdev->release = drm_sysfs_release; 524 + dev_set_drvdata(minor->kdev, minor); 525 + 526 + r = dev_set_name(minor->kdev, minor_str, minor->index); 527 + if (r < 0) 528 + goto error; 529 + 530 + r = device_add(minor->kdev); 531 + if (r < 0) 532 + goto error; 533 + 525 534 return 0; 535 + 536 + error: 537 + DRM_ERROR("device create failed %d\n", r); 538 + put_device(minor->kdev); 539 + return r; 526 540 } 527 541 528 542 /** ··· 555 529 void drm_sysfs_device_remove(struct drm_minor *minor) 556 530 { 557 531 if (minor->kdev) 558 - device_destroy(drm_class, MKDEV(DRM_MAJOR, minor->index)); 532 + device_unregister(minor->kdev); 559 533 minor->kdev = NULL; 560 534 } 561 535