aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_stub.c
diff options
context:
space:
mode:
authorDavid Herrmann <dh.herrmann@gmail.com>2014-01-29 06:43:56 -0500
committerDavid Herrmann <dh.herrmann@gmail.com>2014-03-16 07:25:18 -0400
commit05b701f6f60201c9906167351cce50db2e9db7ae (patch)
tree10ad0205a30fe9a13392cddc5e5d6c8f790f97d6 /drivers/gpu/drm/drm_stub.c
parent1616c525b98deb34b8f4b02eccf0ae3a1310fa27 (diff)
drm: allocate minors early
Instead of waiting for device-registration, we now allocate minor-objects during device allocation. The minors are not registered or assigned an ID. This is still postponed to device-registration. While at it, remove the superfluous output-parameter in drm_get_minor(). The reason for this early allocation is to make dev->primary/control/render available atomically. So once the device is alive, all of them are already set and we never have the situation where one of them is set after another (they're either NULL or set, but never changed). This will eventually allow us to reduce minor-ID allocation to one base-ID instead of a single ID for each. Signed-off-by: David Herrmann <dh.herrmann@gmail.com> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/drm_stub.c')
-rw-r--r--drivers/gpu/drm/drm_stub.c110
1 files changed, 71 insertions, 39 deletions
diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c
index 269048215e82..b595b64291a2 100644
--- a/drivers/gpu/drm/drm_stub.c
+++ b/drivers/gpu/drm/drm_stub.c
@@ -260,21 +260,49 @@ int drm_dropmaster_ioctl(struct drm_device *dev, void *data,
260 return 0; 260 return 0;
261} 261}
262 262
263static struct drm_minor **drm_minor_get_slot(struct drm_device *dev,
264 unsigned int type)
265{
266 switch (type) {
267 case DRM_MINOR_LEGACY:
268 return &dev->primary;
269 case DRM_MINOR_RENDER:
270 return &dev->render;
271 case DRM_MINOR_CONTROL:
272 return &dev->control;
273 default:
274 return NULL;
275 }
276}
277
278static int drm_minor_alloc(struct drm_device *dev, unsigned int type)
279{
280 struct drm_minor *minor;
281
282 minor = kzalloc(sizeof(*minor), GFP_KERNEL);
283 if (!minor)
284 return -ENOMEM;
285
286 minor->type = type;
287 minor->dev = dev;
288 INIT_LIST_HEAD(&minor->master_list);
289
290 *drm_minor_get_slot(dev, type) = minor;
291 return 0;
292}
293
263/** 294/**
264 * drm_get_minor - Allocate and register new DRM minor 295 * drm_get_minor - Register DRM minor
265 * @dev: DRM device 296 * @dev: DRM device
266 * @minor: Pointer to where new minor is stored
267 * @type: Type of minor 297 * @type: Type of minor
268 * 298 *
269 * Allocate a new minor of the given type and register it. A pointer to the new 299 * Register minor of given type.
270 * minor is returned in @minor.
271 * Caller must hold the global DRM mutex. 300 * Caller must hold the global DRM mutex.
272 * 301 *
273 * RETURNS: 302 * RETURNS:
274 * 0 on success, negative error code on failure. 303 * 0 on success, negative error code on failure.
275 */ 304 */
276static int drm_get_minor(struct drm_device *dev, struct drm_minor **minor, 305static int drm_get_minor(struct drm_device *dev, unsigned int type)
277 int type)
278{ 306{
279 struct drm_minor *new_minor; 307 struct drm_minor *new_minor;
280 int ret; 308 int ret;
@@ -282,21 +310,16 @@ static int drm_get_minor(struct drm_device *dev, struct drm_minor **minor,
282 310
283 DRM_DEBUG("\n"); 311 DRM_DEBUG("\n");
284 312
313 new_minor = *drm_minor_get_slot(dev, type);
314 if (!new_minor)
315 return 0;
316
285 minor_id = drm_minor_get_id(dev, type); 317 minor_id = drm_minor_get_id(dev, type);
286 if (minor_id < 0) 318 if (minor_id < 0)
287 return minor_id; 319 return minor_id;
288 320
289 new_minor = kzalloc(sizeof(struct drm_minor), GFP_KERNEL);
290 if (!new_minor) {
291 ret = -ENOMEM;
292 goto err_idr;
293 }
294
295 new_minor->type = type;
296 new_minor->device = MKDEV(DRM_MAJOR, minor_id); 321 new_minor->device = MKDEV(DRM_MAJOR, minor_id);
297 new_minor->dev = dev;
298 new_minor->index = minor_id; 322 new_minor->index = minor_id;
299 INIT_LIST_HEAD(&new_minor->master_list);
300 323
301 idr_replace(&drm_minors_idr, new_minor, minor_id); 324 idr_replace(&drm_minors_idr, new_minor, minor_id);
302 325
@@ -314,7 +337,6 @@ static int drm_get_minor(struct drm_device *dev, struct drm_minor **minor,
314 "DRM: Error sysfs_device_add.\n"); 337 "DRM: Error sysfs_device_add.\n");
315 goto err_debugfs; 338 goto err_debugfs;
316 } 339 }
317 *minor = new_minor;
318 340
319 DRM_DEBUG("new minor assigned %d\n", minor_id); 341 DRM_DEBUG("new minor assigned %d\n", minor_id);
320 return 0; 342 return 0;
@@ -325,10 +347,7 @@ err_debugfs:
325 drm_debugfs_cleanup(new_minor); 347 drm_debugfs_cleanup(new_minor);
326err_mem: 348err_mem:
327#endif 349#endif
328 kfree(new_minor);
329err_idr:
330 idr_remove(&drm_minors_idr, minor_id); 350 idr_remove(&drm_minors_idr, minor_id);
331 *minor = NULL;
332 return ret; 351 return ret;
333} 352}
334 353
@@ -495,8 +514,24 @@ struct drm_device *drm_dev_alloc(struct drm_driver *driver,
495 mutex_init(&dev->struct_mutex); 514 mutex_init(&dev->struct_mutex);
496 mutex_init(&dev->ctxlist_mutex); 515 mutex_init(&dev->ctxlist_mutex);
497 516
517 if (drm_core_check_feature(dev, DRIVER_MODESET)) {
518 ret = drm_minor_alloc(dev, DRM_MINOR_CONTROL);
519 if (ret)
520 goto err_minors;
521 }
522
523 if (drm_core_check_feature(dev, DRIVER_RENDER) && drm_rnodes) {
524 ret = drm_minor_alloc(dev, DRM_MINOR_RENDER);
525 if (ret)
526 goto err_minors;
527 }
528
529 ret = drm_minor_alloc(dev, DRM_MINOR_LEGACY);
530 if (ret)
531 goto err_minors;
532
498 if (drm_ht_create(&dev->map_hash, 12)) 533 if (drm_ht_create(&dev->map_hash, 12))
499 goto err_free; 534 goto err_minors;
500 535
501 ret = drm_ctxbitmap_init(dev); 536 ret = drm_ctxbitmap_init(dev);
502 if (ret) { 537 if (ret) {
@@ -518,7 +553,10 @@ err_ctxbitmap:
518 drm_ctxbitmap_cleanup(dev); 553 drm_ctxbitmap_cleanup(dev);
519err_ht: 554err_ht:
520 drm_ht_remove(&dev->map_hash); 555 drm_ht_remove(&dev->map_hash);
521err_free: 556err_minors:
557 drm_put_minor(dev->control);
558 drm_put_minor(dev->render);
559 drm_put_minor(dev->primary);
522 kfree(dev); 560 kfree(dev);
523 return NULL; 561 return NULL;
524} 562}
@@ -594,26 +632,22 @@ int drm_dev_register(struct drm_device *dev, unsigned long flags)
594 632
595 mutex_lock(&drm_global_mutex); 633 mutex_lock(&drm_global_mutex);
596 634
597 if (drm_core_check_feature(dev, DRIVER_MODESET)) { 635 ret = drm_get_minor(dev, DRM_MINOR_CONTROL);
598 ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL); 636 if (ret)
599 if (ret) 637 goto err_minors;
600 goto out_unlock;
601 }
602 638
603 if (drm_core_check_feature(dev, DRIVER_RENDER) && drm_rnodes) { 639 ret = drm_get_minor(dev, DRM_MINOR_RENDER);
604 ret = drm_get_minor(dev, &dev->render, DRM_MINOR_RENDER); 640 if (ret)
605 if (ret) 641 goto err_minors;
606 goto err_control_node;
607 }
608 642
609 ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY); 643 ret = drm_get_minor(dev, DRM_MINOR_LEGACY);
610 if (ret) 644 if (ret)
611 goto err_render_node; 645 goto err_minors;
612 646
613 if (dev->driver->load) { 647 if (dev->driver->load) {
614 ret = dev->driver->load(dev, flags); 648 ret = dev->driver->load(dev, flags);
615 if (ret) 649 if (ret)
616 goto err_primary_node; 650 goto err_minors;
617 } 651 }
618 652
619 /* setup grouping for legacy outputs */ 653 /* setup grouping for legacy outputs */
@@ -630,12 +664,10 @@ int drm_dev_register(struct drm_device *dev, unsigned long flags)
630err_unload: 664err_unload:
631 if (dev->driver->unload) 665 if (dev->driver->unload)
632 dev->driver->unload(dev); 666 dev->driver->unload(dev);
633err_primary_node: 667err_minors:
634 drm_unplug_minor(dev->primary);
635err_render_node:
636 drm_unplug_minor(dev->render);
637err_control_node:
638 drm_unplug_minor(dev->control); 668 drm_unplug_minor(dev->control);
669 drm_unplug_minor(dev->render);
670 drm_unplug_minor(dev->primary);
639out_unlock: 671out_unlock:
640 mutex_unlock(&drm_global_mutex); 672 mutex_unlock(&drm_global_mutex);
641 return ret; 673 return ret;