From: Jerome Glisse <jgli...@redhat.com>

Allow driver to provide a custom read callback for debugfs file.
Usefull if driver try to dump big buffer, avoid double buffering.

Signed-off-by: Jerome Glisse <jglisse at redhat.com>
---
 drivers/gpu/drm/drm_debugfs.c             |   19 ++++++++++++++++---
 drivers/gpu/drm/i915/i915_debugfs.c       |    2 +-
 drivers/gpu/drm/nouveau/nouveau_debugfs.c |    4 ++--
 drivers/gpu/drm/radeon/radeon_device.c    |    4 ++--
 include/drm/drmP.h                        |    8 +++++++-
 5 files changed, 28 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c
index 1c7a1c0..d5194e6 100644
--- a/drivers/gpu/drm/drm_debugfs.c
+++ b/drivers/gpu/drm/drm_debugfs.c
@@ -63,11 +63,22 @@ static int drm_debugfs_open(struct inode *inode, struct 
file *file)
        return single_open(file, node->info_ent->show, node);
 }

+static ssize_t drm_debugfs_read(struct file *filp, char __user *ubuf,
+                               size_t max, loff_t *ppos)
+{
+       struct seq_file *m = filp->private_data;
+       struct drm_info_node *node = (struct drm_info_node *) m->private;
+
+       if (node->read) {
+               return node->read(filp, ubuf, max, ppos);
+       }
+       return seq_read(filp, ubuf, max, ppos);
+}

 static const struct file_operations drm_debugfs_fops = {
        .owner = THIS_MODULE,
        .open = drm_debugfs_open,
-       .read = seq_read,
+       .read = drm_debugfs_read,
        .llseek = seq_lseek,
        .release = single_release,
 };
@@ -86,7 +97,8 @@ static const struct file_operations drm_debugfs_fops = {
  * gdm_debugfs_lists in the given root directory.
  */
 int drm_debugfs_create_files(struct drm_info_list *files, int count,
-                            struct dentry *root, struct drm_minor *minor)
+                            struct dentry *root, struct drm_minor *minor,
+                            drm_debugfs_read_t read)
 {
        struct drm_device *dev = minor->dev;
        struct dentry *ent;
@@ -118,6 +130,7 @@ int drm_debugfs_create_files(struct drm_info_list *files, 
int count,
                tmp->minor = minor;
                tmp->dent = ent;
                tmp->info_ent = &files[i];
+               tmp->read = read;

                mutex_lock(&minor->debugfs_lock);
                list_add(&tmp->list, &minor->debugfs_list);
@@ -159,7 +172,7 @@ int drm_debugfs_init(struct drm_minor *minor, int minor_id,
        }

        ret = drm_debugfs_create_files(drm_debugfs_list, DRM_DEBUGFS_ENTRIES,
-                                      minor->debugfs_root, minor);
+                                      minor->debugfs_root, minor, NULL);
        if (ret) {
                debugfs_remove(minor->debugfs_root);
                minor->debugfs_root = NULL;
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
b/drivers/gpu/drm/i915/i915_debugfs.c
index 950f72a..636c4f4 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -2018,7 +2018,7 @@ int i915_debugfs_init(struct drm_minor *minor)

        return drm_debugfs_create_files(i915_debugfs_list,
                                        I915_DEBUGFS_ENTRIES,
-                                       minor->debugfs_root, minor);
+                                       minor->debugfs_root, minor, NULL);
 }

 void i915_debugfs_cleanup(struct drm_minor *minor)
diff --git a/drivers/gpu/drm/nouveau/nouveau_debugfs.c 
b/drivers/gpu/drm/nouveau/nouveau_debugfs.c
index fa2ec49..12cbc5c 100644
--- a/drivers/gpu/drm/nouveau/nouveau_debugfs.c
+++ b/drivers/gpu/drm/nouveau/nouveau_debugfs.c
@@ -94,7 +94,7 @@ nouveau_debugfs_channel_init(struct nouveau_channel *chan)

        ret = drm_debugfs_create_files(&chan->debugfs.info, 1,
                                       dev_priv->debugfs.channel_root,
-                                      chan->dev->primary);
+                                      chan->dev->primary, NULL);
        if (ret == 0)
                chan->debugfs.active = true;
        return ret;
@@ -186,7 +186,7 @@ int
 nouveau_debugfs_init(struct drm_minor *minor)
 {
        drm_debugfs_create_files(nouveau_debugfs_list, NOUVEAU_DEBUGFS_ENTRIES,
-                                minor->debugfs_root, minor);
+                                minor->debugfs_root, minor, NULL);
        return 0;
 }

diff --git a/drivers/gpu/drm/radeon/radeon_device.c 
b/drivers/gpu/drm/radeon/radeon_device.c
index 3d41525..944ac11 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -1039,10 +1039,10 @@ int radeon_debugfs_add_files(struct radeon_device *rdev,
 #if defined(CONFIG_DEBUG_FS)
        drm_debugfs_create_files(files, nfiles,
                                 rdev->ddev->control->debugfs_root,
-                                rdev->ddev->control);
+                                rdev->ddev->control, NULL);
        drm_debugfs_create_files(files, nfiles,
                                 rdev->ddev->primary->debugfs_root,
-                                rdev->ddev->primary);
+                                rdev->ddev->primary, NULL);
 #endif
        return 0;
 }
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index efd1249..1e41407 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -1011,6 +1011,8 @@ struct drm_info_node {
        struct drm_minor *minor;
        struct drm_info_list *info_ent;
        struct dentry *dent;
+       /* read callback */
+       ssize_t (*read)(struct file *filp, char __user *ubuf,size_t max, loff_t 
*ppos);
 };

 /**
@@ -1528,10 +1530,14 @@ extern int drm_proc_cleanup(struct drm_minor *minor, 
struct proc_dir_entry *root

                                /* Debugfs support */
 #if defined(CONFIG_DEBUG_FS)
+typedef ssize_t (drm_debugfs_read_t)(struct file *filp, char __user *ubuf,
+                                    size_t max, loff_t *ppos);
+
 extern int drm_debugfs_init(struct drm_minor *minor, int minor_id,
                            struct dentry *root);
 extern int drm_debugfs_create_files(struct drm_info_list *files, int count,
-                                   struct dentry *root, struct drm_minor 
*minor);
+                                   struct dentry *root, struct drm_minor 
*minor,
+                                   drm_debugfs_read_t read);
 extern int drm_debugfs_remove_files(struct drm_info_list *files, int count,
                                     struct drm_minor *minor);
 extern int drm_debugfs_cleanup(struct drm_minor *minor);
-- 
1.7.7.6

Reply via email to