drm/nouveau/debugfs: add infrastructure to add files with other fops than only read
authorKarol Herbst <nouveau@karolherbst.de>
Wed, 29 Jul 2015 11:44:21 +0000 (13:44 +0200)
committerBen Skeggs <bskeggs@redhat.com>
Mon, 11 Jan 2016 01:28:24 +0000 (11:28 +1000)
v2: use the same object for private data as with the drm debugfs functions

Signed-off-by: Karol Herbst <nouveau@karolherbst.de>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/nouveau_debugfs.c

index 5392e07edfc6cd9cbcbb342343e231b9fa0d225d..598c722e586f0904563bd1201818e7739563c3bf 100644 (file)
@@ -28,6 +28,7 @@
  *  Ben Skeggs <bskeggs@redhat.com>
  */
 
+#include <linux/debugfs.h>
 #include "nouveau_debugfs.h"
 #include "nouveau_drm.h"
 
@@ -48,17 +49,66 @@ static struct drm_info_list nouveau_debugfs_list[] = {
 };
 #define NOUVEAU_DEBUGFS_ENTRIES ARRAY_SIZE(nouveau_debugfs_list)
 
+static const struct nouveau_debugfs_files {
+       const char *name;
+       const struct file_operations *fops;
+} nouveau_debugfs_files[] = {};
+
+
+static int
+nouveau_debugfs_create_file(struct drm_minor *minor,
+               const struct nouveau_debugfs_files *ndf)
+{
+       struct drm_info_node *node;
+
+       node = kmalloc(sizeof(*node), GFP_KERNEL);
+       if (node == NULL)
+               return -ENOMEM;
+
+       node->minor = minor;
+       node->info_ent = (const void *)ndf->fops;
+       node->dent = debugfs_create_file(ndf->name, S_IRUGO | S_IWUSR,
+                                        minor->debugfs_root, node, ndf->fops);
+       if (!node->dent) {
+               kfree(node);
+               return -ENOMEM;
+       }
+
+       mutex_lock(&minor->debugfs_lock);
+       list_add(&node->list, &minor->debugfs_list);
+       mutex_unlock(&minor->debugfs_lock);
+       return 0;
+}
+
 int
 nouveau_debugfs_init(struct drm_minor *minor)
 {
-       drm_debugfs_create_files(nouveau_debugfs_list, NOUVEAU_DEBUGFS_ENTRIES,
-                                minor->debugfs_root, minor);
-       return 0;
+       int i, ret;
+
+       for (i = 0; i < ARRAY_SIZE(nouveau_debugfs_files); i++) {
+               ret = nouveau_debugfs_create_file(minor,
+                                                 &nouveau_debugfs_files[i]);
+
+               if (ret)
+                       return ret;
+       }
+
+       return drm_debugfs_create_files(nouveau_debugfs_list,
+                                       NOUVEAU_DEBUGFS_ENTRIES,
+                                       minor->debugfs_root, minor);
 }
 
 void
 nouveau_debugfs_takedown(struct drm_minor *minor)
 {
+       int i;
+
        drm_debugfs_remove_files(nouveau_debugfs_list, NOUVEAU_DEBUGFS_ENTRIES,
                                 minor);
+
+       for (i = 0; i < ARRAY_SIZE(nouveau_debugfs_files); i++) {
+               drm_debugfs_remove_files((struct drm_info_list *)
+                                        nouveau_debugfs_files[i].fops,
+                                        1, minor);
+       }
 }