LCOV - code coverage report
Current view: top level - drivers/gpu/drm - drm_debugfs.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 0 211 0.0 %
Date: 2022-04-01 13:59:58 Functions: 0 20 0.0 %
Branches: 0 96 0.0 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Created: Sun Dec 21 13:08:50 2008 by bgamari@gmail.com
       3                 :            :  *
       4                 :            :  * Copyright 2008 Ben Gamari <bgamari@gmail.com>
       5                 :            :  *
       6                 :            :  * Permission is hereby granted, free of charge, to any person obtaining a
       7                 :            :  * copy of this software and associated documentation files (the "Software"),
       8                 :            :  * to deal in the Software without restriction, including without limitation
       9                 :            :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      10                 :            :  * and/or sell copies of the Software, and to permit persons to whom the
      11                 :            :  * Software is furnished to do so, subject to the following conditions:
      12                 :            :  *
      13                 :            :  * The above copyright notice and this permission notice (including the next
      14                 :            :  * paragraph) shall be included in all copies or substantial portions of the
      15                 :            :  * Software.
      16                 :            :  *
      17                 :            :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      18                 :            :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      19                 :            :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
      20                 :            :  * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
      21                 :            :  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
      22                 :            :  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
      23                 :            :  * OTHER DEALINGS IN THE SOFTWARE.
      24                 :            :  */
      25                 :            : 
      26                 :            : #include <linux/debugfs.h>
      27                 :            : #include <linux/export.h>
      28                 :            : #include <linux/seq_file.h>
      29                 :            : #include <linux/slab.h>
      30                 :            : #include <linux/uaccess.h>
      31                 :            : 
      32                 :            : #include <drm/drm_atomic.h>
      33                 :            : #include <drm/drm_auth.h>
      34                 :            : #include <drm/drm_client.h>
      35                 :            : #include <drm/drm_debugfs.h>
      36                 :            : #include <drm/drm_device.h>
      37                 :            : #include <drm/drm_drv.h>
      38                 :            : #include <drm/drm_edid.h>
      39                 :            : #include <drm/drm_file.h>
      40                 :            : #include <drm/drm_gem.h>
      41                 :            : 
      42                 :            : #include "drm_crtc_internal.h"
      43                 :            : #include "drm_internal.h"
      44                 :            : 
      45                 :            : #if defined(CONFIG_DEBUG_FS)
      46                 :            : 
      47                 :            : /***************************************************
      48                 :            :  * Initialization, etc.
      49                 :            :  **************************************************/
      50                 :            : 
      51                 :          0 : static int drm_name_info(struct seq_file *m, void *data)
      52                 :            : {
      53                 :          0 :         struct drm_info_node *node = (struct drm_info_node *) m->private;
      54                 :          0 :         struct drm_minor *minor = node->minor;
      55                 :          0 :         struct drm_device *dev = minor->dev;
      56                 :          0 :         struct drm_master *master;
      57                 :            : 
      58                 :          0 :         mutex_lock(&dev->master_mutex);
      59                 :          0 :         master = dev->master;
      60                 :          0 :         seq_printf(m, "%s", dev->driver->name);
      61         [ #  # ]:          0 :         if (dev->dev)
      62         [ #  # ]:          0 :                 seq_printf(m, " dev=%s", dev_name(dev->dev));
      63   [ #  #  #  # ]:          0 :         if (master && master->unique)
      64                 :          0 :                 seq_printf(m, " master=%s", master->unique);
      65         [ #  # ]:          0 :         if (dev->unique)
      66                 :          0 :                 seq_printf(m, " unique=%s", dev->unique);
      67                 :          0 :         seq_printf(m, "\n");
      68                 :          0 :         mutex_unlock(&dev->master_mutex);
      69                 :            : 
      70                 :          0 :         return 0;
      71                 :            : }
      72                 :            : 
      73                 :          0 : static int drm_clients_info(struct seq_file *m, void *data)
      74                 :            : {
      75                 :          0 :         struct drm_info_node *node = (struct drm_info_node *) m->private;
      76                 :          0 :         struct drm_device *dev = node->minor->dev;
      77                 :          0 :         struct drm_file *priv;
      78                 :          0 :         kuid_t uid;
      79                 :            : 
      80                 :          0 :         seq_printf(m,
      81                 :            :                    "%20s %5s %3s master a %5s %10s\n",
      82                 :            :                    "command",
      83                 :            :                    "pid",
      84                 :            :                    "dev",
      85                 :            :                    "uid",
      86                 :            :                    "magic");
      87                 :            : 
      88                 :            :         /* dev->filelist is sorted youngest first, but we want to present
      89                 :            :          * oldest first (i.e. kernel, servers, clients), so walk backwardss.
      90                 :            :          */
      91                 :          0 :         mutex_lock(&dev->filelist_mutex);
      92         [ #  # ]:          0 :         list_for_each_entry_reverse(priv, &dev->filelist, lhead) {
      93                 :          0 :                 struct task_struct *task;
      94                 :            : 
      95                 :          0 :                 rcu_read_lock(); /* locks pid_task()->comm */
      96                 :          0 :                 task = pid_task(priv->pid, PIDTYPE_PID);
      97         [ #  # ]:          0 :                 uid = task ? __task_cred(task)->euid : GLOBAL_ROOT_UID;
      98   [ #  #  #  #  :          0 :                 seq_printf(m, "%20s %5d %3d   %c    %c %5d %10u\n",
                   #  # ]
      99                 :            :                            task ? task->comm : "<unknown>",
     100                 :            :                            pid_vnr(priv->pid),
     101                 :          0 :                            priv->minor->index,
     102                 :          0 :                            drm_is_current_master(priv) ? 'y' : 'n',
     103         [ #  # ]:          0 :                            priv->authenticated ? 'y' : 'n',
     104                 :            :                            from_kuid_munged(seq_user_ns(m), uid),
     105                 :            :                            priv->magic);
     106                 :          0 :                 rcu_read_unlock();
     107                 :            :         }
     108                 :          0 :         mutex_unlock(&dev->filelist_mutex);
     109                 :          0 :         return 0;
     110                 :            : }
     111                 :            : 
     112                 :          0 : static int drm_gem_one_name_info(int id, void *ptr, void *data)
     113                 :            : {
     114                 :          0 :         struct drm_gem_object *obj = ptr;
     115                 :          0 :         struct seq_file *m = data;
     116                 :            : 
     117                 :          0 :         seq_printf(m, "%6d %8zd %7d %8d\n",
     118                 :            :                    obj->name, obj->size,
     119                 :            :                    obj->handle_count,
     120                 :            :                    kref_read(&obj->refcount));
     121                 :          0 :         return 0;
     122                 :            : }
     123                 :            : 
     124                 :          0 : static int drm_gem_name_info(struct seq_file *m, void *data)
     125                 :            : {
     126                 :          0 :         struct drm_info_node *node = (struct drm_info_node *) m->private;
     127                 :          0 :         struct drm_device *dev = node->minor->dev;
     128                 :            : 
     129                 :          0 :         seq_printf(m, "  name     size handles refcount\n");
     130                 :            : 
     131                 :          0 :         mutex_lock(&dev->object_name_lock);
     132                 :          0 :         idr_for_each(&dev->object_name_idr, drm_gem_one_name_info, m);
     133                 :          0 :         mutex_unlock(&dev->object_name_lock);
     134                 :            : 
     135                 :          0 :         return 0;
     136                 :            : }
     137                 :            : 
     138                 :            : static const struct drm_info_list drm_debugfs_list[] = {
     139                 :            :         {"name", drm_name_info, 0},
     140                 :            :         {"clients", drm_clients_info, 0},
     141                 :            :         {"gem_names", drm_gem_name_info, DRIVER_GEM},
     142                 :            : };
     143                 :            : #define DRM_DEBUGFS_ENTRIES ARRAY_SIZE(drm_debugfs_list)
     144                 :            : 
     145                 :            : 
     146                 :          0 : static int drm_debugfs_open(struct inode *inode, struct file *file)
     147                 :            : {
     148                 :          0 :         struct drm_info_node *node = inode->i_private;
     149                 :            : 
     150                 :          0 :         return single_open(file, node->info_ent->show, node);
     151                 :            : }
     152                 :            : 
     153                 :            : 
     154                 :            : static const struct file_operations drm_debugfs_fops = {
     155                 :            :         .owner = THIS_MODULE,
     156                 :            :         .open = drm_debugfs_open,
     157                 :            :         .read = seq_read,
     158                 :            :         .llseek = seq_lseek,
     159                 :            :         .release = single_release,
     160                 :            : };
     161                 :            : 
     162                 :            : 
     163                 :            : /**
     164                 :            :  * drm_debugfs_create_files - Initialize a given set of debugfs files for DRM
     165                 :            :  *                      minor
     166                 :            :  * @files: The array of files to create
     167                 :            :  * @count: The number of files given
     168                 :            :  * @root: DRI debugfs dir entry.
     169                 :            :  * @minor: device minor number
     170                 :            :  *
     171                 :            :  * Create a given set of debugfs files represented by an array of
     172                 :            :  * &struct drm_info_list in the given root directory. These files will be removed
     173                 :            :  * automatically on drm_debugfs_cleanup().
     174                 :            :  */
     175                 :          0 : int drm_debugfs_create_files(const struct drm_info_list *files, int count,
     176                 :            :                              struct dentry *root, struct drm_minor *minor)
     177                 :            : {
     178                 :          0 :         struct drm_device *dev = minor->dev;
     179                 :          0 :         struct drm_info_node *tmp;
     180                 :          0 :         int i;
     181                 :            : 
     182         [ #  # ]:          0 :         for (i = 0; i < count; i++) {
     183                 :          0 :                 u32 features = files[i].driver_features;
     184                 :            : 
     185         [ #  # ]:          0 :                 if (features != 0 &&
     186         [ #  # ]:          0 :                     (dev->driver->driver_features & features) != features)
     187                 :          0 :                         continue;
     188                 :            : 
     189                 :          0 :                 tmp = kmalloc(sizeof(struct drm_info_node), GFP_KERNEL);
     190         [ #  # ]:          0 :                 if (tmp == NULL)
     191                 :          0 :                         continue;
     192                 :            : 
     193                 :          0 :                 tmp->minor = minor;
     194                 :          0 :                 tmp->dent = debugfs_create_file(files[i].name,
     195                 :            :                                                 S_IFREG | S_IRUGO, root, tmp,
     196                 :            :                                                 &drm_debugfs_fops);
     197                 :          0 :                 tmp->info_ent = &files[i];
     198                 :            : 
     199                 :          0 :                 mutex_lock(&minor->debugfs_lock);
     200                 :          0 :                 list_add(&tmp->list, &minor->debugfs_list);
     201                 :          0 :                 mutex_unlock(&minor->debugfs_lock);
     202                 :            :         }
     203                 :          0 :         return 0;
     204                 :            : }
     205                 :            : EXPORT_SYMBOL(drm_debugfs_create_files);
     206                 :            : 
     207                 :          0 : int drm_debugfs_init(struct drm_minor *minor, int minor_id,
     208                 :            :                      struct dentry *root)
     209                 :            : {
     210                 :          0 :         struct drm_device *dev = minor->dev;
     211                 :          0 :         char name[64];
     212                 :          0 :         int ret;
     213                 :            : 
     214                 :          0 :         INIT_LIST_HEAD(&minor->debugfs_list);
     215                 :          0 :         mutex_init(&minor->debugfs_lock);
     216                 :          0 :         sprintf(name, "%d", minor_id);
     217                 :          0 :         minor->debugfs_root = debugfs_create_dir(name, root);
     218                 :            : 
     219                 :          0 :         ret = drm_debugfs_create_files(drm_debugfs_list, DRM_DEBUGFS_ENTRIES,
     220                 :            :                                        minor->debugfs_root, minor);
     221         [ #  # ]:          0 :         if (ret) {
     222                 :          0 :                 debugfs_remove(minor->debugfs_root);
     223                 :          0 :                 minor->debugfs_root = NULL;
     224                 :          0 :                 DRM_ERROR("Failed to create core drm debugfs files\n");
     225                 :          0 :                 return ret;
     226                 :            :         }
     227                 :            : 
     228   [ #  #  #  # ]:          0 :         if (drm_drv_uses_atomic_modeset(dev)) {
     229                 :          0 :                 ret = drm_atomic_debugfs_init(minor);
     230         [ #  # ]:          0 :                 if (ret) {
     231                 :          0 :                         DRM_ERROR("Failed to create atomic debugfs files\n");
     232                 :          0 :                         return ret;
     233                 :            :                 }
     234                 :            :         }
     235                 :            : 
     236         [ #  # ]:          0 :         if (drm_core_check_feature(dev, DRIVER_MODESET)) {
     237                 :          0 :                 ret = drm_framebuffer_debugfs_init(minor);
     238         [ #  # ]:          0 :                 if (ret) {
     239                 :          0 :                         DRM_ERROR("Failed to create framebuffer debugfs file\n");
     240                 :          0 :                         return ret;
     241                 :            :                 }
     242                 :            : 
     243                 :          0 :                 ret = drm_client_debugfs_init(minor);
     244         [ #  # ]:          0 :                 if (ret) {
     245                 :          0 :                         DRM_ERROR("Failed to create client debugfs file\n");
     246                 :          0 :                         return ret;
     247                 :            :                 }
     248                 :            :         }
     249                 :            : 
     250         [ #  # ]:          0 :         if (dev->driver->debugfs_init) {
     251                 :          0 :                 ret = dev->driver->debugfs_init(minor);
     252         [ #  # ]:          0 :                 if (ret) {
     253                 :          0 :                         DRM_ERROR("DRM: Driver failed to initialize "
     254                 :            :                                   "/sys/kernel/debug/dri.\n");
     255                 :          0 :                         return ret;
     256                 :            :                 }
     257                 :            :         }
     258                 :            :         return 0;
     259                 :            : }
     260                 :            : 
     261                 :            : 
     262                 :          0 : int drm_debugfs_remove_files(const struct drm_info_list *files, int count,
     263                 :            :                              struct drm_minor *minor)
     264                 :            : {
     265                 :          0 :         struct list_head *pos, *q;
     266                 :          0 :         struct drm_info_node *tmp;
     267                 :          0 :         int i;
     268                 :            : 
     269                 :          0 :         mutex_lock(&minor->debugfs_lock);
     270         [ #  # ]:          0 :         for (i = 0; i < count; i++) {
     271         [ #  # ]:          0 :                 list_for_each_safe(pos, q, &minor->debugfs_list) {
     272                 :          0 :                         tmp = list_entry(pos, struct drm_info_node, list);
     273         [ #  # ]:          0 :                         if (tmp->info_ent == &files[i]) {
     274                 :          0 :                                 debugfs_remove(tmp->dent);
     275                 :          0 :                                 list_del(pos);
     276                 :          0 :                                 kfree(tmp);
     277                 :            :                         }
     278                 :            :                 }
     279                 :            :         }
     280                 :          0 :         mutex_unlock(&minor->debugfs_lock);
     281                 :          0 :         return 0;
     282                 :            : }
     283                 :            : EXPORT_SYMBOL(drm_debugfs_remove_files);
     284                 :            : 
     285                 :          0 : static void drm_debugfs_remove_all_files(struct drm_minor *minor)
     286                 :            : {
     287                 :          0 :         struct drm_info_node *node, *tmp;
     288                 :            : 
     289                 :          0 :         mutex_lock(&minor->debugfs_lock);
     290         [ #  # ]:          0 :         list_for_each_entry_safe(node, tmp, &minor->debugfs_list, list) {
     291                 :          0 :                 debugfs_remove(node->dent);
     292                 :          0 :                 list_del(&node->list);
     293                 :          0 :                 kfree(node);
     294                 :            :         }
     295                 :          0 :         mutex_unlock(&minor->debugfs_lock);
     296                 :          0 : }
     297                 :            : 
     298                 :          0 : void drm_debugfs_cleanup(struct drm_minor *minor)
     299                 :            : {
     300         [ #  # ]:          0 :         if (!minor->debugfs_root)
     301                 :            :                 return;
     302                 :            : 
     303                 :          0 :         drm_debugfs_remove_all_files(minor);
     304                 :            : 
     305                 :          0 :         debugfs_remove_recursive(minor->debugfs_root);
     306                 :          0 :         minor->debugfs_root = NULL;
     307                 :            : }
     308                 :            : 
     309                 :          0 : static int connector_show(struct seq_file *m, void *data)
     310                 :            : {
     311                 :          0 :         struct drm_connector *connector = m->private;
     312                 :            : 
     313                 :          0 :         seq_printf(m, "%s\n", drm_get_connector_force_name(connector->force));
     314                 :            : 
     315                 :          0 :         return 0;
     316                 :            : }
     317                 :            : 
     318                 :          0 : static int connector_open(struct inode *inode, struct file *file)
     319                 :            : {
     320                 :          0 :         struct drm_connector *dev = inode->i_private;
     321                 :            : 
     322                 :          0 :         return single_open(file, connector_show, dev);
     323                 :            : }
     324                 :            : 
     325                 :          0 : static ssize_t connector_write(struct file *file, const char __user *ubuf,
     326                 :            :                                size_t len, loff_t *offp)
     327                 :            : {
     328                 :          0 :         struct seq_file *m = file->private_data;
     329                 :          0 :         struct drm_connector *connector = m->private;
     330                 :          0 :         char buf[12];
     331                 :            : 
     332         [ #  # ]:          0 :         if (len > sizeof(buf) - 1)
     333                 :            :                 return -EINVAL;
     334                 :            : 
     335   [ #  #  #  # ]:          0 :         if (copy_from_user(buf, ubuf, len))
     336                 :            :                 return -EFAULT;
     337                 :            : 
     338                 :          0 :         buf[len] = '\0';
     339                 :            : 
     340         [ #  # ]:          0 :         if (!strcmp(buf, "on"))
     341                 :          0 :                 connector->force = DRM_FORCE_ON;
     342         [ #  # ]:          0 :         else if (!strcmp(buf, "digital"))
     343                 :          0 :                 connector->force = DRM_FORCE_ON_DIGITAL;
     344         [ #  # ]:          0 :         else if (!strcmp(buf, "off"))
     345                 :          0 :                 connector->force = DRM_FORCE_OFF;
     346         [ #  # ]:          0 :         else if (!strcmp(buf, "unspecified"))
     347                 :          0 :                 connector->force = DRM_FORCE_UNSPECIFIED;
     348                 :            :         else
     349                 :            :                 return -EINVAL;
     350                 :            : 
     351                 :          0 :         return len;
     352                 :            : }
     353                 :            : 
     354                 :          0 : static int edid_show(struct seq_file *m, void *data)
     355                 :            : {
     356                 :          0 :         struct drm_connector *connector = m->private;
     357                 :          0 :         struct drm_property_blob *edid = connector->edid_blob_ptr;
     358                 :            : 
     359   [ #  #  #  # ]:          0 :         if (connector->override_edid && edid)
     360                 :          0 :                 seq_write(m, edid->data, edid->length);
     361                 :            : 
     362                 :          0 :         return 0;
     363                 :            : }
     364                 :            : 
     365                 :          0 : static int edid_open(struct inode *inode, struct file *file)
     366                 :            : {
     367                 :          0 :         struct drm_connector *dev = inode->i_private;
     368                 :            : 
     369                 :          0 :         return single_open(file, edid_show, dev);
     370                 :            : }
     371                 :            : 
     372                 :          0 : static ssize_t edid_write(struct file *file, const char __user *ubuf,
     373                 :            :                           size_t len, loff_t *offp)
     374                 :            : {
     375                 :          0 :         struct seq_file *m = file->private_data;
     376                 :          0 :         struct drm_connector *connector = m->private;
     377                 :          0 :         char *buf;
     378                 :          0 :         struct edid *edid;
     379                 :          0 :         int ret;
     380                 :            : 
     381                 :          0 :         buf = memdup_user(ubuf, len);
     382         [ #  # ]:          0 :         if (IS_ERR(buf))
     383                 :          0 :                 return PTR_ERR(buf);
     384                 :            : 
     385                 :          0 :         edid = (struct edid *) buf;
     386                 :            : 
     387   [ #  #  #  # ]:          0 :         if (len == 5 && !strncmp(buf, "reset", 5)) {
     388                 :          0 :                 connector->override_edid = false;
     389                 :          0 :                 ret = drm_connector_update_edid_property(connector, NULL);
     390         [ #  # ]:          0 :         } else if (len < EDID_LENGTH ||
     391         [ #  # ]:          0 :                    EDID_LENGTH * (1 + edid->extensions) > len)
     392                 :            :                 ret = -EINVAL;
     393                 :            :         else {
     394                 :          0 :                 connector->override_edid = false;
     395                 :          0 :                 ret = drm_connector_update_edid_property(connector, edid);
     396         [ #  # ]:          0 :                 if (!ret)
     397                 :          0 :                         connector->override_edid = true;
     398                 :            :         }
     399                 :            : 
     400                 :          0 :         kfree(buf);
     401                 :            : 
     402         [ #  # ]:          0 :         return (ret) ? ret : len;
     403                 :            : }
     404                 :            : 
     405                 :            : static const struct file_operations drm_edid_fops = {
     406                 :            :         .owner = THIS_MODULE,
     407                 :            :         .open = edid_open,
     408                 :            :         .read = seq_read,
     409                 :            :         .llseek = seq_lseek,
     410                 :            :         .release = single_release,
     411                 :            :         .write = edid_write
     412                 :            : };
     413                 :            : 
     414                 :            : 
     415                 :            : static const struct file_operations drm_connector_fops = {
     416                 :            :         .owner = THIS_MODULE,
     417                 :            :         .open = connector_open,
     418                 :            :         .read = seq_read,
     419                 :            :         .llseek = seq_lseek,
     420                 :            :         .release = single_release,
     421                 :            :         .write = connector_write
     422                 :            : };
     423                 :            : 
     424                 :          0 : void drm_debugfs_connector_add(struct drm_connector *connector)
     425                 :            : {
     426                 :          0 :         struct drm_minor *minor = connector->dev->primary;
     427                 :          0 :         struct dentry *root;
     428                 :            : 
     429         [ #  # ]:          0 :         if (!minor->debugfs_root)
     430                 :            :                 return;
     431                 :            : 
     432                 :          0 :         root = debugfs_create_dir(connector->name, minor->debugfs_root);
     433                 :          0 :         connector->debugfs_entry = root;
     434                 :            : 
     435                 :            :         /* force */
     436                 :          0 :         debugfs_create_file("force", S_IRUGO | S_IWUSR, root, connector,
     437                 :            :                             &drm_connector_fops);
     438                 :            : 
     439                 :            :         /* edid */
     440                 :          0 :         debugfs_create_file("edid_override", S_IRUGO | S_IWUSR, root, connector,
     441                 :            :                             &drm_edid_fops);
     442                 :            : }
     443                 :            : 
     444                 :          0 : void drm_debugfs_connector_remove(struct drm_connector *connector)
     445                 :            : {
     446         [ #  # ]:          0 :         if (!connector->debugfs_entry)
     447                 :            :                 return;
     448                 :            : 
     449                 :          0 :         debugfs_remove_recursive(connector->debugfs_entry);
     450                 :            : 
     451                 :          0 :         connector->debugfs_entry = NULL;
     452                 :            : }
     453                 :            : 
     454                 :          0 : void drm_debugfs_crtc_add(struct drm_crtc *crtc)
     455                 :            : {
     456                 :          0 :         struct drm_minor *minor = crtc->dev->primary;
     457                 :          0 :         struct dentry *root;
     458                 :          0 :         char *name;
     459                 :            : 
     460                 :          0 :         name = kasprintf(GFP_KERNEL, "crtc-%d", crtc->index);
     461         [ #  # ]:          0 :         if (!name)
     462                 :            :                 return;
     463                 :            : 
     464                 :          0 :         root = debugfs_create_dir(name, minor->debugfs_root);
     465                 :          0 :         kfree(name);
     466                 :            : 
     467                 :          0 :         crtc->debugfs_entry = root;
     468                 :            : 
     469                 :          0 :         drm_debugfs_crtc_crc_add(crtc);
     470                 :            : }
     471                 :            : 
     472                 :          0 : void drm_debugfs_crtc_remove(struct drm_crtc *crtc)
     473                 :            : {
     474                 :          0 :         debugfs_remove_recursive(crtc->debugfs_entry);
     475                 :          0 :         crtc->debugfs_entry = NULL;
     476                 :          0 : }
     477                 :            : 
     478                 :            : #endif /* CONFIG_DEBUG_FS */

Generated by: LCOV version 1.14