aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Herrmann <dh.herrmann@gmail.com>2013-10-02 05:23:35 -0400
committerDave Airlie <airlied@redhat.com>2013-10-09 01:54:31 -0400
commitc22f0ace1926da399d9a16dfaf09174c1b03594c (patch)
tree9c82626f939917cba7ab3626a22fe61d52940ec9
parent1bb72532ac260a2d3982b40bdd4c936d779d0d16 (diff)
drm: merge device setup into drm_dev_register()
All bus drivers do device setup themselves. This requires us to adjust all of them if we introduce new core features. Thus, merge all these into a uniform drm_dev_register() helper. Note that this removes the drm_lastclose() error path for AGP as it is horribly broken. Moreover, no bus driver called this in any other error path either. Instead, we use the recently introduced AGP cleanup helpers. We also keep a DRIVER_MODESET condition around pci_set_drvdata() to keep semantics. [airlied: keep passing flags through so drivers don't oops on load] Signed-off-by: David Herrmann <dh.herrmann@gmail.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r--drivers/gpu/drm/drm_pci.c56
-rw-r--r--drivers/gpu/drm/drm_platform.c54
-rw-r--r--drivers/gpu/drm/drm_stub.c101
-rw-r--r--drivers/gpu/drm/drm_usb.c48
-rw-r--r--include/drm/drmP.h4
5 files changed, 96 insertions, 167 deletions
diff --git a/drivers/gpu/drm/drm_pci.c b/drivers/gpu/drm/drm_pci.c
index d2758be37a93..743589dc47ce 100644
--- a/drivers/gpu/drm/drm_pci.c
+++ b/drivers/gpu/drm/drm_pci.c
@@ -328,7 +328,7 @@ int drm_get_pci_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
328 328
329 ret = pci_enable_device(pdev); 329 ret = pci_enable_device(pdev);
330 if (ret) 330 if (ret)
331 goto err_g1; 331 goto err_free;
332 332
333 dev->pdev = pdev; 333 dev->pdev = pdev;
334 dev->pci_device = pdev->device; 334 dev->pci_device = pdev->device;
@@ -338,65 +338,23 @@ int drm_get_pci_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
338 dev->hose = pdev->sysdata; 338 dev->hose = pdev->sysdata;
339#endif 339#endif
340 340
341 mutex_lock(&drm_global_mutex); 341 if (drm_core_check_feature(dev, DRIVER_MODESET))
342
343 if ((ret = drm_fill_in_dev(dev, ent, driver))) {
344 printk(KERN_ERR "DRM: Fill_in_dev failed.\n");
345 goto err_g2;
346 }
347
348 if (drm_core_check_feature(dev, DRIVER_MODESET)) {
349 pci_set_drvdata(pdev, dev); 342 pci_set_drvdata(pdev, dev);
350 ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL);
351 if (ret)
352 goto err_g2;
353 }
354
355 if (drm_core_check_feature(dev, DRIVER_RENDER) && drm_rnodes) {
356 ret = drm_get_minor(dev, &dev->render, DRM_MINOR_RENDER);
357 if (ret)
358 goto err_g21;
359 }
360 343
361 if ((ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY))) 344 ret = drm_dev_register(dev, ent->driver_data);
362 goto err_g3; 345 if (ret)
363 346 goto err_pci;
364 if (dev->driver->load) {
365 ret = dev->driver->load(dev, ent->driver_data);
366 if (ret)
367 goto err_g4;
368 }
369
370 /* setup the grouping for the legacy output */
371 if (drm_core_check_feature(dev, DRIVER_MODESET)) {
372 ret = drm_mode_group_init_legacy_group(dev,
373 &dev->primary->mode_group);
374 if (ret)
375 goto err_g4;
376 }
377
378 list_add_tail(&dev->driver_item, &driver->device_list);
379 347
380 DRM_INFO("Initialized %s %d.%d.%d %s for %s on minor %d\n", 348 DRM_INFO("Initialized %s %d.%d.%d %s for %s on minor %d\n",
381 driver->name, driver->major, driver->minor, driver->patchlevel, 349 driver->name, driver->major, driver->minor, driver->patchlevel,
382 driver->date, pci_name(pdev), dev->primary->index); 350 driver->date, pci_name(pdev), dev->primary->index);
383 351
384 mutex_unlock(&drm_global_mutex);
385 return 0; 352 return 0;
386 353
387err_g4: 354err_pci:
388 drm_put_minor(&dev->primary);
389err_g3:
390 if (dev->render)
391 drm_put_minor(&dev->render);
392err_g21:
393 if (drm_core_check_feature(dev, DRIVER_MODESET))
394 drm_put_minor(&dev->control);
395err_g2:
396 pci_disable_device(pdev); 355 pci_disable_device(pdev);
397err_g1: 356err_free:
398 kfree(dev); 357 kfree(dev);
399 mutex_unlock(&drm_global_mutex);
400 return ret; 358 return ret;
401} 359}
402EXPORT_SYMBOL(drm_get_pci_dev); 360EXPORT_SYMBOL(drm_get_pci_dev);
diff --git a/drivers/gpu/drm/drm_platform.c b/drivers/gpu/drm/drm_platform.c
index fb2721738a8a..a0f91f85651f 100644
--- a/drivers/gpu/drm/drm_platform.c
+++ b/drivers/gpu/drm/drm_platform.c
@@ -53,48 +53,9 @@ static int drm_get_platform_dev(struct platform_device *platdev,
53 53
54 dev->platformdev = platdev; 54 dev->platformdev = platdev;
55 55
56 mutex_lock(&drm_global_mutex); 56 ret = drm_dev_register(dev, 0);
57
58 ret = drm_fill_in_dev(dev, NULL, driver);
59
60 if (ret) {
61 printk(KERN_ERR "DRM: Fill_in_dev failed.\n");
62 goto err_g1;
63 }
64
65 if (drm_core_check_feature(dev, DRIVER_MODESET)) {
66 ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL);
67 if (ret)
68 goto err_g1;
69 }
70
71 if (drm_core_check_feature(dev, DRIVER_RENDER) && drm_rnodes) {
72 ret = drm_get_minor(dev, &dev->render, DRM_MINOR_RENDER);
73 if (ret)
74 goto err_g11;
75 }
76
77 ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY);
78 if (ret) 57 if (ret)
79 goto err_g2; 58 goto err_free;
80
81 if (dev->driver->load) {
82 ret = dev->driver->load(dev, 0);
83 if (ret)
84 goto err_g3;
85 }
86
87 /* setup the grouping for the legacy output */
88 if (drm_core_check_feature(dev, DRIVER_MODESET)) {
89 ret = drm_mode_group_init_legacy_group(dev,
90 &dev->primary->mode_group);
91 if (ret)
92 goto err_g3;
93 }
94
95 list_add_tail(&dev->driver_item, &driver->device_list);
96
97 mutex_unlock(&drm_global_mutex);
98 59
99 DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", 60 DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n",
100 driver->name, driver->major, driver->minor, driver->patchlevel, 61 driver->name, driver->major, driver->minor, driver->patchlevel,
@@ -102,17 +63,8 @@ static int drm_get_platform_dev(struct platform_device *platdev,
102 63
103 return 0; 64 return 0;
104 65
105err_g3: 66err_free:
106 drm_put_minor(&dev->primary);
107err_g2:
108 if (dev->render)
109 drm_put_minor(&dev->render);
110err_g11:
111 if (drm_core_check_feature(dev, DRIVER_MODESET))
112 drm_put_minor(&dev->control);
113err_g1:
114 kfree(dev); 67 kfree(dev);
115 mutex_unlock(&drm_global_mutex);
116 return ret; 68 return ret;
117} 69}
118 70
diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c
index 64bd52f13199..432994aafc3b 100644
--- a/drivers/gpu/drm/drm_stub.c
+++ b/drivers/gpu/drm/drm_stub.c
@@ -254,25 +254,6 @@ 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 if (dev->driver->bus->agp_init) {
264 retcode = dev->driver->bus->agp_init(dev);
265 if (retcode) {
266 drm_lastclose(dev);
267 return retcode;
268 }
269 }
270
271 return 0;
272}
273EXPORT_SYMBOL(drm_fill_in_dev);
274
275
276/** 257/**
277 * Get a secondary minor number. 258 * Get a secondary minor number.
278 * 259 *
@@ -452,6 +433,8 @@ EXPORT_SYMBOL(drm_unplug_dev);
452 * @parent: Parent device object 433 * @parent: Parent device object
453 * 434 *
454 * Allocate and initialize a new DRM device. No device registration is done. 435 * Allocate and initialize a new DRM device. No device registration is done.
436 * Call drm_dev_register() to advertice the device to user space and register it
437 * with other core subsystems.
455 * 438 *
456 * RETURNS: 439 * RETURNS:
457 * Pointer to new DRM device, or NULL if out of memory. 440 * Pointer to new DRM device, or NULL if out of memory.
@@ -517,3 +500,83 @@ err_free:
517 return NULL; 500 return NULL;
518} 501}
519EXPORT_SYMBOL(drm_dev_alloc); 502EXPORT_SYMBOL(drm_dev_alloc);
503
504/**
505 * drm_dev_register - Register DRM device
506 * @dev: Device to register
507 *
508 * Register the DRM device @dev with the system, advertise device to user-space
509 * and start normal device operation. @dev must be allocated via drm_dev_alloc()
510 * previously.
511 *
512 * Never call this twice on any device!
513 *
514 * RETURNS:
515 * 0 on success, negative error code on failure.
516 */
517int drm_dev_register(struct drm_device *dev, unsigned long flags)
518{
519 int ret;
520
521 mutex_lock(&drm_global_mutex);
522
523 if (dev->driver->bus->agp_init) {
524 ret = dev->driver->bus->agp_init(dev);
525 if (ret)
526 goto out_unlock;
527 }
528
529 if (drm_core_check_feature(dev, DRIVER_MODESET)) {
530 ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL);
531 if (ret)
532 goto err_agp;
533 }
534
535 if (drm_core_check_feature(dev, DRIVER_RENDER) && drm_rnodes) {
536 ret = drm_get_minor(dev, &dev->render, DRM_MINOR_RENDER);
537 if (ret)
538 goto err_control_node;
539 }
540
541 ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY);
542 if (ret)
543 goto err_render_node;
544
545 if (dev->driver->load) {
546 ret = dev->driver->load(dev, flags);
547 if (ret)
548 goto err_primary_node;
549 }
550
551 /* setup grouping for legacy outputs */
552 if (drm_core_check_feature(dev, DRIVER_MODESET)) {
553 ret = drm_mode_group_init_legacy_group(dev,
554 &dev->primary->mode_group);
555 if (ret)
556 goto err_unload;
557 }
558
559 list_add_tail(&dev->driver_item, &dev->driver->device_list);
560
561 ret = 0;
562 goto out_unlock;
563
564err_unload:
565 if (dev->driver->unload)
566 dev->driver->unload(dev);
567err_primary_node:
568 drm_put_minor(&dev->primary);
569err_render_node:
570 if (dev->render)
571 drm_put_minor(&dev->render);
572err_control_node:
573 if (dev->control)
574 drm_put_minor(&dev->control);
575err_agp:
576 if (dev->driver->bus->agp_destroy)
577 dev->driver->bus->agp_destroy(dev);
578out_unlock:
579 mutex_unlock(&drm_global_mutex);
580 return ret;
581}
582EXPORT_SYMBOL(drm_dev_register);
diff --git a/drivers/gpu/drm/drm_usb.c b/drivers/gpu/drm/drm_usb.c
index 34ad8edfe806..5ef353f77b5a 100644
--- a/drivers/gpu/drm/drm_usb.c
+++ b/drivers/gpu/drm/drm_usb.c
@@ -16,45 +16,11 @@ int drm_get_usb_dev(struct usb_interface *interface,
16 return -ENOMEM; 16 return -ENOMEM;
17 17
18 dev->usbdev = interface_to_usbdev(interface); 18 dev->usbdev = interface_to_usbdev(interface);
19
20 mutex_lock(&drm_global_mutex);
21
22 ret = drm_fill_in_dev(dev, NULL, driver);
23 if (ret) {
24 printk(KERN_ERR "DRM: Fill_in_dev failed.\n");
25 goto err_g1;
26 }
27
28 usb_set_intfdata(interface, dev); 19 usb_set_intfdata(interface, dev);
29 ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL);
30 if (ret)
31 goto err_g1;
32
33 if (drm_core_check_feature(dev, DRIVER_RENDER) && drm_rnodes) {
34 ret = drm_get_minor(dev, &dev->render, DRM_MINOR_RENDER);
35 if (ret)
36 goto err_g11;
37 }
38 20
39 ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY); 21 ret = drm_dev_register(dev, 0);
40 if (ret) 22 if (ret)
41 goto err_g2; 23 goto err_free;
42
43 if (dev->driver->load) {
44 ret = dev->driver->load(dev, 0);
45 if (ret)
46 goto err_g3;
47 }
48
49 /* setup the grouping for the legacy output */
50 ret = drm_mode_group_init_legacy_group(dev,
51 &dev->primary->mode_group);
52 if (ret)
53 goto err_g3;
54
55 list_add_tail(&dev->driver_item, &driver->device_list);
56
57 mutex_unlock(&drm_global_mutex);
58 24
59 DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", 25 DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n",
60 driver->name, driver->major, driver->minor, driver->patchlevel, 26 driver->name, driver->major, driver->minor, driver->patchlevel,
@@ -62,16 +28,8 @@ int drm_get_usb_dev(struct usb_interface *interface,
62 28
63 return 0; 29 return 0;
64 30
65err_g3: 31err_free:
66 drm_put_minor(&dev->primary);
67err_g2:
68 if (dev->render)
69 drm_put_minor(&dev->render);
70err_g11:
71 drm_put_minor(&dev->control);
72err_g1:
73 kfree(dev); 32 kfree(dev);
74 mutex_unlock(&drm_global_mutex);
75 return ret; 33 return ret;
76 34
77} 35}
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index ea545b5ad467..1973f7966511 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -1640,11 +1640,9 @@ static __inline__ void drm_core_dropmap(struct drm_local_map *map)
1640 1640
1641#include <drm/drm_mem_util.h> 1641#include <drm/drm_mem_util.h>
1642 1642
1643extern int drm_fill_in_dev(struct drm_device *dev,
1644 const struct pci_device_id *ent,
1645 struct drm_driver *driver);
1646struct drm_device *drm_dev_alloc(struct drm_driver *driver, 1643struct drm_device *drm_dev_alloc(struct drm_driver *driver,
1647 struct device *parent); 1644 struct device *parent);
1645int drm_dev_register(struct drm_device *dev, unsigned long flags);
1648int drm_get_minor(struct drm_device *dev, struct drm_minor **minor, int type); 1646int drm_get_minor(struct drm_device *dev, struct drm_minor **minor, int type);
1649/*@}*/ 1647/*@}*/
1650 1648