Add device-specific proc_init and proc_cleanup hooks
authorKeith Packard <keithp@keithp.com>
Fri, 20 Jun 2008 23:40:14 +0000 (16:40 -0700)
committerKeith Packard <keithp@keithp.com>
Fri, 20 Jun 2008 23:40:14 +0000 (16:40 -0700)
This allows device drivers to add proc files

linux-core/drmP.h
linux-core/drm_drv.c
linux-core/drm_stub.c

index 392d2ac..ec8a61d 100644 (file)
@@ -770,6 +770,9 @@ struct drm_driver {
        void (*set_version) (struct drm_device *dev,
                             struct drm_set_version *sv);
 
+       int (*proc_init)(struct drm_minor *minor);
+       void (*proc_cleanup)(struct drm_minor *minor);
+
        /**
         * Driver-specific constructor for drm_gem_objects, to set up
         * obj->driver_private.
@@ -1287,7 +1290,7 @@ extern void drm_agp_chipset_flush(struct drm_device *dev);
 extern int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
                     struct drm_driver *driver);
 extern int drm_put_dev(struct drm_device *dev);
-extern int drm_put_minor(struct drm_minor **minor);
+extern int drm_put_minor(struct drm_device *dev);
 extern unsigned int drm_debug; /* 1 to enable debug output */
 
 extern struct class *drm_class;
index 980752c..bc32ed5 100644 (file)
@@ -422,7 +422,7 @@ static void drm_cleanup(struct drm_device * dev)
        drm_memrange_takedown(&dev->offset_manager);
        drm_ht_remove(&dev->object_hash);
 
-       drm_put_minor(&dev->primary);
+       drm_put_minor(dev);
        if (drm_put_dev(dev))
                DRM_ERROR("Cannot unload module\n");
 }
index 5584182..1aacd4f 100644 (file)
@@ -222,6 +222,13 @@ static int drm_get_minor(struct drm_device *dev, struct drm_minor **minor, int t
                        DRM_ERROR("DRM: Failed to initialize /proc/dri.\n");
                        goto err_mem;
                }
+               if (dev->driver->proc_init) {
+                       ret = dev->driver->proc_init(new_minor);
+                       if (ret) {
+                               DRM_ERROR("DRM: Driver failed to initialize /proc/dri.\n");
+                               goto err_mem;
+                       }
+               }
        } else
                new_minor->dev_root = NULL;
 
@@ -238,8 +245,11 @@ static int drm_get_minor(struct drm_device *dev, struct drm_minor **minor, int t
 
 
 err_g2:
-       if (new_minor->type == DRM_MINOR_LEGACY)
+       if (new_minor->type == DRM_MINOR_LEGACY) {
+               if (dev->driver->proc_cleanup)
+                       dev->driver->proc_cleanup(new_minor);
                drm_proc_cleanup(new_minor, drm_proc_root);
+       }
 err_mem:
        kfree(new_minor);
 err_idr:
@@ -302,7 +312,7 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
 
        return 0;
 err_g4:
-       drm_put_minor(&dev->primary);
+       drm_put_minor(dev);
 err_g3:
        if (!drm_fb_loaded)
                pci_disable_device(pdev);
@@ -358,13 +368,17 @@ int drm_put_dev(struct drm_device * dev)
  * last minor released.
  *
  */
-int drm_put_minor(struct drm_minor **minor_p)
+int drm_put_minor(struct drm_device *dev)
 {
+       struct drm_minor **minor_p = &dev->primary;
        struct drm_minor *minor = *minor_p;
        DRM_DEBUG("release secondary minor %d\n", minor->index);
 
-       if (minor->type == DRM_MINOR_LEGACY)
+       if (minor->type == DRM_MINOR_LEGACY) {
+               if (dev->driver->proc_cleanup)
+                       dev->driver->proc_cleanup(minor);
                drm_proc_cleanup(minor, drm_proc_root);
+       }
        drm_sysfs_device_remove(minor);
 
        idr_remove(&drm_minors_idr, minor->index);