Bladeren bron

drm/nouveau/debugfs: add infrastructure to add files with other fops than only read

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>
Karol Herbst 10 jaren geleden
bovenliggende
commit
1b7ab1a1c3
1 gewijzigde bestanden met toevoegingen van 53 en 3 verwijderingen
  1. 53 3
      drivers/gpu/drm/nouveau/nouveau_debugfs.c

+ 53 - 3
drivers/gpu/drm/nouveau/nouveau_debugfs.c

@@ -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);
+	}
 }