aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_stub.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/drm_stub.c')
-rw-r--r--drivers/gpu/drm/drm_stub.c362
1 files changed, 242 insertions, 120 deletions
diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c
index 39d864576be4..c200136a5d8e 100644
--- a/drivers/gpu/drm/drm_stub.c
+++ b/drivers/gpu/drm/drm_stub.c
@@ -254,81 +254,21 @@ int drm_dropmaster_ioctl(struct drm_device *dev, void *data,
254 return 0; 254 return 0;
255} 255}
256 256
257int drm_fill_in_dev(struct drm_device *dev,
258 const struct pci_device_id *ent,
259 struct drm_driver *driver)
260{
261 int retcode;
262
263 INIT_LIST_HEAD(&dev->filelist);
264 INIT_LIST_HEAD(&dev->ctxlist);
265 INIT_LIST_HEAD(&dev->vmalist);
266 INIT_LIST_HEAD(&dev->maplist);
267 INIT_LIST_HEAD(&dev->vblank_event_list);
268
269 spin_lock_init(&dev->count_lock);
270 spin_lock_init(&dev->event_lock);
271 mutex_init(&dev->struct_mutex);
272 mutex_init(&dev->ctxlist_mutex);
273
274 if (drm_ht_create(&dev->map_hash, 12)) {
275 return -ENOMEM;
276 }
277
278 /* the DRM has 6 basic counters */
279 dev->counters = 6;
280 dev->types[0] = _DRM_STAT_LOCK;
281 dev->types[1] = _DRM_STAT_OPENS;
282 dev->types[2] = _DRM_STAT_CLOSES;
283 dev->types[3] = _DRM_STAT_IOCTLS;
284 dev->types[4] = _DRM_STAT_LOCKS;
285 dev->types[5] = _DRM_STAT_UNLOCKS;
286
287 dev->driver = driver;
288
289 if (dev->driver->bus->agp_init) {
290 retcode = dev->driver->bus->agp_init(dev);
291 if (retcode)
292 goto error_out_unreg;
293 }
294
295
296
297 retcode = drm_ctxbitmap_init(dev);
298 if (retcode) {
299 DRM_ERROR("Cannot allocate memory for context bitmap.\n");
300 goto error_out_unreg;
301 }
302
303 if (driver->driver_features & DRIVER_GEM) {
304 retcode = drm_gem_init(dev);
305 if (retcode) {
306 DRM_ERROR("Cannot initialize graphics execution "
307 "manager (GEM)\n");
308 goto error_out_unreg;
309 }
310 }
311
312 return 0;
313
314 error_out_unreg:
315 drm_lastclose(dev);
316 return retcode;
317}
318EXPORT_SYMBOL(drm_fill_in_dev);
319
320
321/** 257/**
322 * Get a secondary minor number. 258 * drm_get_minor - Allocate and register new DRM minor
259 * @dev: DRM device
260 * @minor: Pointer to where new minor is stored
261 * @type: Type of minor
323 * 262 *
324 * \param dev device data structure 263 * Allocate a new minor of the given type and register it. A pointer to the new
325 * \param sec-minor structure to hold the assigned minor 264 * minor is returned in @minor.
326 * \return negative number on failure. 265 * Caller must hold the global DRM mutex.
327 * 266 *
328 * Search an empty entry and initialize it to the given parameters. This 267 * RETURNS:
329 * routines assigns minor numbers to secondary heads of multi-headed cards 268 * 0 on success, negative error code on failure.
330 */ 269 */
331int drm_get_minor(struct drm_device *dev, struct drm_minor **minor, int type) 270static int drm_get_minor(struct drm_device *dev, struct drm_minor **minor,
271 int type)
332{ 272{
333 struct drm_minor *new_minor; 273 struct drm_minor *new_minor;
334 int ret; 274 int ret;
@@ -385,37 +325,48 @@ err_idr:
385 *minor = NULL; 325 *minor = NULL;
386 return ret; 326 return ret;
387} 327}
388EXPORT_SYMBOL(drm_get_minor);
389 328
390/** 329/**
391 * Put a secondary minor number. 330 * drm_unplug_minor - Unplug DRM minor
331 * @minor: Minor to unplug
392 * 332 *
393 * \param sec_minor - structure to be released 333 * Unplugs the given DRM minor but keeps the object. So after this returns,
394 * \return always zero 334 * minor->dev is still valid so existing open-files can still access it to get
335 * device information from their drm_file ojects.
336 * If the minor is already unplugged or if @minor is NULL, nothing is done.
337 * The global DRM mutex must be held by the caller.
395 */ 338 */
396int drm_put_minor(struct drm_minor **minor_p) 339static void drm_unplug_minor(struct drm_minor *minor)
397{ 340{
398 struct drm_minor *minor = *minor_p; 341 if (!minor || !device_is_registered(minor->kdev))
399 342 return;
400 DRM_DEBUG("release secondary minor %d\n", minor->index);
401 343
402#if defined(CONFIG_DEBUG_FS) 344#if defined(CONFIG_DEBUG_FS)
403 drm_debugfs_cleanup(minor); 345 drm_debugfs_cleanup(minor);
404#endif 346#endif
405 347
406 drm_sysfs_device_remove(minor); 348 drm_sysfs_device_remove(minor);
407
408 idr_remove(&drm_minors_idr, minor->index); 349 idr_remove(&drm_minors_idr, minor->index);
409
410 kfree(minor);
411 *minor_p = NULL;
412 return 0;
413} 350}
414EXPORT_SYMBOL(drm_put_minor);
415 351
416static void drm_unplug_minor(struct drm_minor *minor) 352/**
353 * drm_put_minor - Destroy DRM minor
354 * @minor: Minor to destroy
355 *
356 * This calls drm_unplug_minor() on the given minor and then frees it. Nothing
357 * is done if @minor is NULL. It is fine to call this on already unplugged
358 * minors.
359 * The global DRM mutex must be held by the caller.
360 */
361static void drm_put_minor(struct drm_minor *minor)
417{ 362{
418 drm_sysfs_device_remove(minor); 363 if (!minor)
364 return;
365
366 DRM_DEBUG("release secondary minor %d\n", minor->index);
367
368 drm_unplug_minor(minor);
369 kfree(minor);
419} 370}
420 371
421/** 372/**
@@ -427,66 +378,237 @@ static void drm_unplug_minor(struct drm_minor *minor)
427 */ 378 */
428void drm_put_dev(struct drm_device *dev) 379void drm_put_dev(struct drm_device *dev)
429{ 380{
430 struct drm_driver *driver;
431 struct drm_map_list *r_list, *list_temp;
432
433 DRM_DEBUG("\n"); 381 DRM_DEBUG("\n");
434 382
435 if (!dev) { 383 if (!dev) {
436 DRM_ERROR("cleanup called no dev\n"); 384 DRM_ERROR("cleanup called no dev\n");
437 return; 385 return;
438 } 386 }
439 driver = dev->driver;
440 387
441 drm_lastclose(dev); 388 drm_dev_unregister(dev);
389 drm_dev_free(dev);
390}
391EXPORT_SYMBOL(drm_put_dev);
442 392
443 if (dev->driver->unload) 393void drm_unplug_dev(struct drm_device *dev)
444 dev->driver->unload(dev); 394{
395 /* for a USB device */
396 if (drm_core_check_feature(dev, DRIVER_MODESET))
397 drm_unplug_minor(dev->control);
398 if (dev->render)
399 drm_unplug_minor(dev->render);
400 drm_unplug_minor(dev->primary);
445 401
446 if (dev->driver->bus->agp_destroy) 402 mutex_lock(&drm_global_mutex);
447 dev->driver->bus->agp_destroy(dev);
448 403
449 drm_vblank_cleanup(dev); 404 drm_device_set_unplugged(dev);
450 405
451 list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head) 406 if (dev->open_count == 0) {
452 drm_rmmap(dev, r_list->map); 407 drm_put_dev(dev);
453 drm_ht_remove(&dev->map_hash); 408 }
409 mutex_unlock(&drm_global_mutex);
410}
411EXPORT_SYMBOL(drm_unplug_dev);
454 412
455 drm_ctxbitmap_cleanup(dev); 413/**
414 * drm_dev_alloc - Allocate new drm device
415 * @driver: DRM driver to allocate device for
416 * @parent: Parent device object
417 *
418 * Allocate and initialize a new DRM device. No device registration is done.
419 * Call drm_dev_register() to advertice the device to user space and register it
420 * with other core subsystems.
421 *
422 * RETURNS:
423 * Pointer to new DRM device, or NULL if out of memory.
424 */
425struct drm_device *drm_dev_alloc(struct drm_driver *driver,
426 struct device *parent)
427{
428 struct drm_device *dev;
429 int ret;
456 430
457 if (drm_core_check_feature(dev, DRIVER_MODESET)) 431 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
458 drm_put_minor(&dev->control); 432 if (!dev)
433 return NULL;
459 434
460 if (dev->render) 435 dev->dev = parent;
461 drm_put_minor(&dev->render); 436 dev->driver = driver;
462 437
463 if (driver->driver_features & DRIVER_GEM) 438 INIT_LIST_HEAD(&dev->filelist);
439 INIT_LIST_HEAD(&dev->ctxlist);
440 INIT_LIST_HEAD(&dev->vmalist);
441 INIT_LIST_HEAD(&dev->maplist);
442 INIT_LIST_HEAD(&dev->vblank_event_list);
443
444 spin_lock_init(&dev->count_lock);
445 spin_lock_init(&dev->event_lock);
446 mutex_init(&dev->struct_mutex);
447 mutex_init(&dev->ctxlist_mutex);
448
449 if (drm_ht_create(&dev->map_hash, 12))
450 goto err_free;
451
452 ret = drm_ctxbitmap_init(dev);
453 if (ret) {
454 DRM_ERROR("Cannot allocate memory for context bitmap.\n");
455 goto err_ht;
456 }
457
458 if (driver->driver_features & DRIVER_GEM) {
459 ret = drm_gem_init(dev);
460 if (ret) {
461 DRM_ERROR("Cannot initialize graphics execution manager (GEM)\n");
462 goto err_ctxbitmap;
463 }
464 }
465
466 return dev;
467
468err_ctxbitmap:
469 drm_ctxbitmap_cleanup(dev);
470err_ht:
471 drm_ht_remove(&dev->map_hash);
472err_free:
473 kfree(dev);
474 return NULL;
475}
476EXPORT_SYMBOL(drm_dev_alloc);
477
478/**
479 * drm_dev_free - Free DRM device
480 * @dev: DRM device to free
481 *
482 * Free a DRM device that has previously been allocated via drm_dev_alloc().
483 * You must not use kfree() instead or you will leak memory.
484 *
485 * This must not be called once the device got registered. Use drm_put_dev()
486 * instead, which then calls drm_dev_free().
487 */
488void drm_dev_free(struct drm_device *dev)
489{
490 drm_put_minor(dev->control);
491 drm_put_minor(dev->render);
492 drm_put_minor(dev->primary);
493
494 if (dev->driver->driver_features & DRIVER_GEM)
464 drm_gem_destroy(dev); 495 drm_gem_destroy(dev);
465 496
466 drm_put_minor(&dev->primary); 497 drm_ctxbitmap_cleanup(dev);
498 drm_ht_remove(&dev->map_hash);
467 499
468 list_del(&dev->driver_item);
469 kfree(dev->devname); 500 kfree(dev->devname);
470 kfree(dev); 501 kfree(dev);
471} 502}
472EXPORT_SYMBOL(drm_put_dev); 503EXPORT_SYMBOL(drm_dev_free);
473 504
474void drm_unplug_dev(struct drm_device *dev) 505/**
506 * drm_dev_register - Register DRM device
507 * @dev: Device to register
508 *
509 * Register the DRM device @dev with the system, advertise device to user-space
510 * and start normal device operation. @dev must be allocated via drm_dev_alloc()
511 * previously.
512 *
513 * Never call this twice on any device!
514 *
515 * RETURNS:
516 * 0 on success, negative error code on failure.
517 */
518int drm_dev_register(struct drm_device *dev, unsigned long flags)
475{ 519{
476 /* for a USB device */ 520 int ret;
477 if (drm_core_check_feature(dev, DRIVER_MODESET))
478 drm_unplug_minor(dev->control);
479 if (dev->render)
480 drm_unplug_minor(dev->render);
481 drm_unplug_minor(dev->primary);
482 521
483 mutex_lock(&drm_global_mutex); 522 mutex_lock(&drm_global_mutex);
484 523
485 drm_device_set_unplugged(dev); 524 if (dev->driver->bus->agp_init) {
525 ret = dev->driver->bus->agp_init(dev);
526 if (ret)
527 goto out_unlock;
528 }
486 529
487 if (dev->open_count == 0) { 530 if (drm_core_check_feature(dev, DRIVER_MODESET)) {
488 drm_put_dev(dev); 531 ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL);
532 if (ret)
533 goto err_agp;
534 }
535
536 if (drm_core_check_feature(dev, DRIVER_RENDER) && drm_rnodes) {
537 ret = drm_get_minor(dev, &dev->render, DRM_MINOR_RENDER);
538 if (ret)
539 goto err_control_node;
540 }
541
542 ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY);
543 if (ret)
544 goto err_render_node;
545
546 if (dev->driver->load) {
547 ret = dev->driver->load(dev, flags);
548 if (ret)
549 goto err_primary_node;
489 } 550 }
551
552 /* setup grouping for legacy outputs */
553 if (drm_core_check_feature(dev, DRIVER_MODESET)) {
554 ret = drm_mode_group_init_legacy_group(dev,
555 &dev->primary->mode_group);
556 if (ret)
557 goto err_unload;
558 }
559
560 list_add_tail(&dev->driver_item, &dev->driver->device_list);
561
562 ret = 0;
563 goto out_unlock;
564
565err_unload:
566 if (dev->driver->unload)
567 dev->driver->unload(dev);
568err_primary_node:
569 drm_put_minor(dev->primary);
570err_render_node:
571 drm_put_minor(dev->render);
572err_control_node:
573 drm_put_minor(dev->control);
574err_agp:
575 if (dev->driver->bus->agp_destroy)
576 dev->driver->bus->agp_destroy(dev);
577out_unlock:
490 mutex_unlock(&drm_global_mutex); 578 mutex_unlock(&drm_global_mutex);
579 return ret;
491} 580}
492EXPORT_SYMBOL(drm_unplug_dev); 581EXPORT_SYMBOL(drm_dev_register);
582
583/**
584 * drm_dev_unregister - Unregister DRM device
585 * @dev: Device to unregister
586 *
587 * Unregister the DRM device from the system. This does the reverse of
588 * drm_dev_register() but does not deallocate the device. The caller must call
589 * drm_dev_free() to free all resources.
590 */
591void drm_dev_unregister(struct drm_device *dev)
592{
593 struct drm_map_list *r_list, *list_temp;
594
595 drm_lastclose(dev);
596
597 if (dev->driver->unload)
598 dev->driver->unload(dev);
599
600 if (dev->driver->bus->agp_destroy)
601 dev->driver->bus->agp_destroy(dev);
602
603 drm_vblank_cleanup(dev);
604
605 list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head)
606 drm_rmmap(dev, r_list->map);
607
608 drm_unplug_minor(dev->control);
609 drm_unplug_minor(dev->render);
610 drm_unplug_minor(dev->primary);
611
612 list_del(&dev->driver_item);
613}
614EXPORT_SYMBOL(drm_dev_unregister);