LCOV - code coverage report
Current view: top level - drivers/gpu/drm - drm_mode_config.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 0 248 0.0 %
Date: 2022-04-01 14:58:12 Functions: 0 7 0.0 %
Branches: 0 130 0.0 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright (c) 2016 Intel Corporation
       3                 :            :  *
       4                 :            :  * Permission to use, copy, modify, distribute, and sell this software and its
       5                 :            :  * documentation for any purpose is hereby granted without fee, provided that
       6                 :            :  * the above copyright notice appear in all copies and that both that copyright
       7                 :            :  * notice and this permission notice appear in supporting documentation, and
       8                 :            :  * that the name of the copyright holders not be used in advertising or
       9                 :            :  * publicity pertaining to distribution of the software without specific,
      10                 :            :  * written prior permission.  The copyright holders make no representations
      11                 :            :  * about the suitability of this software for any purpose.  It is provided "as
      12                 :            :  * is" without express or implied warranty.
      13                 :            :  *
      14                 :            :  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
      15                 :            :  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
      16                 :            :  * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
      17                 :            :  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
      18                 :            :  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
      19                 :            :  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
      20                 :            :  * OF THIS SOFTWARE.
      21                 :            :  */
      22                 :            : 
      23                 :            : #include <linux/uaccess.h>
      24                 :            : 
      25                 :            : #include <drm/drm_drv.h>
      26                 :            : #include <drm/drm_encoder.h>
      27                 :            : #include <drm/drm_file.h>
      28                 :            : #include <drm/drm_mode_config.h>
      29                 :            : #include <drm/drm_print.h>
      30                 :            : #include <linux/dma-resv.h>
      31                 :            : 
      32                 :            : #include "drm_crtc_internal.h"
      33                 :            : #include "drm_internal.h"
      34                 :            : 
      35                 :          0 : int drm_modeset_register_all(struct drm_device *dev)
      36                 :            : {
      37                 :          0 :         int ret;
      38                 :            : 
      39                 :          0 :         ret = drm_plane_register_all(dev);
      40         [ #  # ]:          0 :         if (ret)
      41                 :          0 :                 goto err_plane;
      42                 :            : 
      43                 :          0 :         ret = drm_crtc_register_all(dev);
      44         [ #  # ]:          0 :         if  (ret)
      45                 :          0 :                 goto err_crtc;
      46                 :            : 
      47                 :          0 :         ret = drm_encoder_register_all(dev);
      48         [ #  # ]:          0 :         if (ret)
      49                 :          0 :                 goto err_encoder;
      50                 :            : 
      51                 :          0 :         ret = drm_connector_register_all(dev);
      52         [ #  # ]:          0 :         if (ret)
      53                 :          0 :                 goto err_connector;
      54                 :            : 
      55                 :            :         return 0;
      56                 :            : 
      57                 :            : err_connector:
      58                 :          0 :         drm_encoder_unregister_all(dev);
      59                 :          0 : err_encoder:
      60                 :          0 :         drm_crtc_unregister_all(dev);
      61                 :          0 : err_crtc:
      62                 :          0 :         drm_plane_unregister_all(dev);
      63                 :            : err_plane:
      64                 :            :         return ret;
      65                 :            : }
      66                 :            : 
      67                 :          0 : void drm_modeset_unregister_all(struct drm_device *dev)
      68                 :            : {
      69                 :          0 :         drm_connector_unregister_all(dev);
      70                 :          0 :         drm_encoder_unregister_all(dev);
      71                 :          0 :         drm_crtc_unregister_all(dev);
      72                 :          0 :         drm_plane_unregister_all(dev);
      73                 :          0 : }
      74                 :            : 
      75                 :            : /**
      76                 :            :  * drm_mode_getresources - get graphics configuration
      77                 :            :  * @dev: drm device for the ioctl
      78                 :            :  * @data: data pointer for the ioctl
      79                 :            :  * @file_priv: drm file for the ioctl call
      80                 :            :  *
      81                 :            :  * Construct a set of configuration description structures and return
      82                 :            :  * them to the user, including CRTC, connector and framebuffer configuration.
      83                 :            :  *
      84                 :            :  * Called by the user via ioctl.
      85                 :            :  *
      86                 :            :  * Returns:
      87                 :            :  * Zero on success, negative errno on failure.
      88                 :            :  */
      89                 :          0 : int drm_mode_getresources(struct drm_device *dev, void *data,
      90                 :            :                           struct drm_file *file_priv)
      91                 :            : {
      92                 :          0 :         struct drm_mode_card_res *card_res = data;
      93                 :          0 :         struct drm_framebuffer *fb;
      94                 :          0 :         struct drm_connector *connector;
      95                 :          0 :         struct drm_crtc *crtc;
      96                 :          0 :         struct drm_encoder *encoder;
      97                 :          0 :         int count, ret = 0;
      98                 :          0 :         uint32_t __user *fb_id;
      99                 :          0 :         uint32_t __user *crtc_id;
     100                 :          0 :         uint32_t __user *connector_id;
     101                 :          0 :         uint32_t __user *encoder_id;
     102                 :          0 :         struct drm_connector_list_iter conn_iter;
     103                 :            : 
     104         [ #  # ]:          0 :         if (!drm_core_check_feature(dev, DRIVER_MODESET))
     105                 :            :                 return -EOPNOTSUPP;
     106                 :            : 
     107                 :          0 :         mutex_lock(&file_priv->fbs_lock);
     108                 :          0 :         count = 0;
     109                 :          0 :         fb_id = u64_to_user_ptr(card_res->fb_id_ptr);
     110         [ #  # ]:          0 :         list_for_each_entry(fb, &file_priv->fbs, filp_head) {
     111         [ #  # ]:          0 :                 if (count < card_res->count_fbs &&
     112         [ #  # ]:          0 :                     put_user(fb->base.id, fb_id + count)) {
     113                 :          0 :                         mutex_unlock(&file_priv->fbs_lock);
     114                 :          0 :                         return -EFAULT;
     115                 :            :                 }
     116                 :          0 :                 count++;
     117                 :            :         }
     118                 :          0 :         card_res->count_fbs = count;
     119                 :          0 :         mutex_unlock(&file_priv->fbs_lock);
     120                 :            : 
     121                 :          0 :         card_res->max_height = dev->mode_config.max_height;
     122                 :          0 :         card_res->min_height = dev->mode_config.min_height;
     123                 :          0 :         card_res->max_width = dev->mode_config.max_width;
     124                 :          0 :         card_res->min_width = dev->mode_config.min_width;
     125                 :            : 
     126                 :          0 :         count = 0;
     127                 :          0 :         crtc_id = u64_to_user_ptr(card_res->crtc_id_ptr);
     128         [ #  # ]:          0 :         drm_for_each_crtc(crtc, dev) {
     129         [ #  # ]:          0 :                 if (drm_lease_held(file_priv, crtc->base.id)) {
     130         [ #  # ]:          0 :                         if (count < card_res->count_crtcs &&
     131         [ #  # ]:          0 :                             put_user(crtc->base.id, crtc_id + count))
     132                 :            :                                 return -EFAULT;
     133                 :          0 :                         count++;
     134                 :            :                 }
     135                 :            :         }
     136                 :          0 :         card_res->count_crtcs = count;
     137                 :            : 
     138                 :          0 :         count = 0;
     139                 :          0 :         encoder_id = u64_to_user_ptr(card_res->encoder_id_ptr);
     140         [ #  # ]:          0 :         drm_for_each_encoder(encoder, dev) {
     141         [ #  # ]:          0 :                 if (count < card_res->count_encoders &&
     142         [ #  # ]:          0 :                     put_user(encoder->base.id, encoder_id + count))
     143                 :            :                         return -EFAULT;
     144                 :          0 :                 count++;
     145                 :            :         }
     146                 :          0 :         card_res->count_encoders = count;
     147                 :            : 
     148                 :          0 :         drm_connector_list_iter_begin(dev, &conn_iter);
     149                 :          0 :         count = 0;
     150                 :          0 :         connector_id = u64_to_user_ptr(card_res->connector_id_ptr);
     151         [ #  # ]:          0 :         drm_for_each_connector_iter(connector, &conn_iter) {
     152                 :            :                 /* only expose writeback connectors if userspace understands them */
     153         [ #  # ]:          0 :                 if (!file_priv->writeback_connectors &&
     154         [ #  # ]:          0 :                     (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK))
     155                 :          0 :                         continue;
     156                 :            : 
     157         [ #  # ]:          0 :                 if (drm_lease_held(file_priv, connector->base.id)) {
     158         [ #  # ]:          0 :                         if (count < card_res->count_connectors &&
     159         [ #  # ]:          0 :                             put_user(connector->base.id, connector_id + count)) {
     160                 :          0 :                                 drm_connector_list_iter_end(&conn_iter);
     161                 :          0 :                                 return -EFAULT;
     162                 :            :                         }
     163                 :          0 :                         count++;
     164                 :            :                 }
     165                 :            :         }
     166                 :          0 :         card_res->count_connectors = count;
     167                 :          0 :         drm_connector_list_iter_end(&conn_iter);
     168                 :            : 
     169                 :          0 :         return ret;
     170                 :            : }
     171                 :            : 
     172                 :            : /**
     173                 :            :  * drm_mode_config_reset - call ->reset callbacks
     174                 :            :  * @dev: drm device
     175                 :            :  *
     176                 :            :  * This functions calls all the crtc's, encoder's and connector's ->reset
     177                 :            :  * callback. Drivers can use this in e.g. their driver load or resume code to
     178                 :            :  * reset hardware and software state.
     179                 :            :  */
     180                 :          0 : void drm_mode_config_reset(struct drm_device *dev)
     181                 :            : {
     182                 :          0 :         struct drm_crtc *crtc;
     183                 :          0 :         struct drm_plane *plane;
     184                 :          0 :         struct drm_encoder *encoder;
     185                 :          0 :         struct drm_connector *connector;
     186                 :          0 :         struct drm_connector_list_iter conn_iter;
     187                 :            : 
     188         [ #  # ]:          0 :         drm_for_each_plane(plane, dev)
     189         [ #  # ]:          0 :                 if (plane->funcs->reset)
     190                 :          0 :                         plane->funcs->reset(plane);
     191                 :            : 
     192         [ #  # ]:          0 :         drm_for_each_crtc(crtc, dev)
     193         [ #  # ]:          0 :                 if (crtc->funcs->reset)
     194                 :          0 :                         crtc->funcs->reset(crtc);
     195                 :            : 
     196         [ #  # ]:          0 :         drm_for_each_encoder(encoder, dev)
     197         [ #  # ]:          0 :                 if (encoder->funcs->reset)
     198                 :          0 :                         encoder->funcs->reset(encoder);
     199                 :            : 
     200                 :          0 :         drm_connector_list_iter_begin(dev, &conn_iter);
     201         [ #  # ]:          0 :         drm_for_each_connector_iter(connector, &conn_iter)
     202         [ #  # ]:          0 :                 if (connector->funcs->reset)
     203                 :          0 :                         connector->funcs->reset(connector);
     204                 :          0 :         drm_connector_list_iter_end(&conn_iter);
     205                 :          0 : }
     206                 :            : EXPORT_SYMBOL(drm_mode_config_reset);
     207                 :            : 
     208                 :            : /*
     209                 :            :  * Global properties
     210                 :            :  */
     211                 :            : static const struct drm_prop_enum_list drm_plane_type_enum_list[] = {
     212                 :            :         { DRM_PLANE_TYPE_OVERLAY, "Overlay" },
     213                 :            :         { DRM_PLANE_TYPE_PRIMARY, "Primary" },
     214                 :            :         { DRM_PLANE_TYPE_CURSOR, "Cursor" },
     215                 :            : };
     216                 :            : 
     217                 :          0 : static int drm_mode_create_standard_properties(struct drm_device *dev)
     218                 :            : {
     219                 :          0 :         struct drm_property *prop;
     220                 :          0 :         int ret;
     221                 :            : 
     222                 :          0 :         ret = drm_connector_create_standard_properties(dev);
     223         [ #  # ]:          0 :         if (ret)
     224                 :            :                 return ret;
     225                 :            : 
     226                 :          0 :         prop = drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,
     227                 :            :                                         "type", drm_plane_type_enum_list,
     228                 :            :                                         ARRAY_SIZE(drm_plane_type_enum_list));
     229         [ #  # ]:          0 :         if (!prop)
     230                 :            :                 return -ENOMEM;
     231                 :          0 :         dev->mode_config.plane_type_property = prop;
     232                 :            : 
     233                 :          0 :         prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
     234                 :            :                         "SRC_X", 0, UINT_MAX);
     235         [ #  # ]:          0 :         if (!prop)
     236                 :            :                 return -ENOMEM;
     237                 :          0 :         dev->mode_config.prop_src_x = prop;
     238                 :            : 
     239                 :          0 :         prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
     240                 :            :                         "SRC_Y", 0, UINT_MAX);
     241         [ #  # ]:          0 :         if (!prop)
     242                 :            :                 return -ENOMEM;
     243                 :          0 :         dev->mode_config.prop_src_y = prop;
     244                 :            : 
     245                 :          0 :         prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
     246                 :            :                         "SRC_W", 0, UINT_MAX);
     247         [ #  # ]:          0 :         if (!prop)
     248                 :            :                 return -ENOMEM;
     249                 :          0 :         dev->mode_config.prop_src_w = prop;
     250                 :            : 
     251                 :          0 :         prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
     252                 :            :                         "SRC_H", 0, UINT_MAX);
     253         [ #  # ]:          0 :         if (!prop)
     254                 :            :                 return -ENOMEM;
     255                 :          0 :         dev->mode_config.prop_src_h = prop;
     256                 :            : 
     257                 :          0 :         prop = drm_property_create_signed_range(dev, DRM_MODE_PROP_ATOMIC,
     258                 :            :                         "CRTC_X", INT_MIN, INT_MAX);
     259         [ #  # ]:          0 :         if (!prop)
     260                 :            :                 return -ENOMEM;
     261                 :          0 :         dev->mode_config.prop_crtc_x = prop;
     262                 :            : 
     263                 :          0 :         prop = drm_property_create_signed_range(dev, DRM_MODE_PROP_ATOMIC,
     264                 :            :                         "CRTC_Y", INT_MIN, INT_MAX);
     265         [ #  # ]:          0 :         if (!prop)
     266                 :            :                 return -ENOMEM;
     267                 :          0 :         dev->mode_config.prop_crtc_y = prop;
     268                 :            : 
     269                 :          0 :         prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
     270                 :            :                         "CRTC_W", 0, INT_MAX);
     271         [ #  # ]:          0 :         if (!prop)
     272                 :            :                 return -ENOMEM;
     273                 :          0 :         dev->mode_config.prop_crtc_w = prop;
     274                 :            : 
     275                 :          0 :         prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
     276                 :            :                         "CRTC_H", 0, INT_MAX);
     277         [ #  # ]:          0 :         if (!prop)
     278                 :            :                 return -ENOMEM;
     279                 :          0 :         dev->mode_config.prop_crtc_h = prop;
     280                 :            : 
     281                 :          0 :         prop = drm_property_create_object(dev, DRM_MODE_PROP_ATOMIC,
     282                 :            :                         "FB_ID", DRM_MODE_OBJECT_FB);
     283         [ #  # ]:          0 :         if (!prop)
     284                 :            :                 return -ENOMEM;
     285                 :          0 :         dev->mode_config.prop_fb_id = prop;
     286                 :            : 
     287                 :          0 :         prop = drm_property_create_signed_range(dev, DRM_MODE_PROP_ATOMIC,
     288                 :            :                         "IN_FENCE_FD", -1, INT_MAX);
     289         [ #  # ]:          0 :         if (!prop)
     290                 :            :                 return -ENOMEM;
     291                 :          0 :         dev->mode_config.prop_in_fence_fd = prop;
     292                 :            : 
     293                 :          0 :         prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
     294                 :            :                         "OUT_FENCE_PTR", 0, U64_MAX);
     295         [ #  # ]:          0 :         if (!prop)
     296                 :            :                 return -ENOMEM;
     297                 :          0 :         dev->mode_config.prop_out_fence_ptr = prop;
     298                 :            : 
     299                 :          0 :         prop = drm_property_create_object(dev, DRM_MODE_PROP_ATOMIC,
     300                 :            :                         "CRTC_ID", DRM_MODE_OBJECT_CRTC);
     301         [ #  # ]:          0 :         if (!prop)
     302                 :            :                 return -ENOMEM;
     303                 :          0 :         dev->mode_config.prop_crtc_id = prop;
     304                 :            : 
     305                 :          0 :         prop = drm_property_create(dev,
     306                 :            :                         DRM_MODE_PROP_ATOMIC | DRM_MODE_PROP_BLOB,
     307                 :            :                         "FB_DAMAGE_CLIPS", 0);
     308         [ #  # ]:          0 :         if (!prop)
     309                 :            :                 return -ENOMEM;
     310                 :          0 :         dev->mode_config.prop_fb_damage_clips = prop;
     311                 :            : 
     312                 :          0 :         prop = drm_property_create_bool(dev, DRM_MODE_PROP_ATOMIC,
     313                 :            :                         "ACTIVE");
     314         [ #  # ]:          0 :         if (!prop)
     315                 :            :                 return -ENOMEM;
     316                 :          0 :         dev->mode_config.prop_active = prop;
     317                 :            : 
     318                 :          0 :         prop = drm_property_create(dev,
     319                 :            :                         DRM_MODE_PROP_ATOMIC | DRM_MODE_PROP_BLOB,
     320                 :            :                         "MODE_ID", 0);
     321         [ #  # ]:          0 :         if (!prop)
     322                 :            :                 return -ENOMEM;
     323                 :          0 :         dev->mode_config.prop_mode_id = prop;
     324                 :            : 
     325                 :          0 :         prop = drm_property_create_bool(dev, 0,
     326                 :            :                         "VRR_ENABLED");
     327         [ #  # ]:          0 :         if (!prop)
     328                 :            :                 return -ENOMEM;
     329                 :          0 :         dev->mode_config.prop_vrr_enabled = prop;
     330                 :            : 
     331                 :          0 :         prop = drm_property_create(dev,
     332                 :            :                         DRM_MODE_PROP_BLOB,
     333                 :            :                         "DEGAMMA_LUT", 0);
     334         [ #  # ]:          0 :         if (!prop)
     335                 :            :                 return -ENOMEM;
     336                 :          0 :         dev->mode_config.degamma_lut_property = prop;
     337                 :            : 
     338                 :          0 :         prop = drm_property_create_range(dev,
     339                 :            :                         DRM_MODE_PROP_IMMUTABLE,
     340                 :            :                         "DEGAMMA_LUT_SIZE", 0, UINT_MAX);
     341         [ #  # ]:          0 :         if (!prop)
     342                 :            :                 return -ENOMEM;
     343                 :          0 :         dev->mode_config.degamma_lut_size_property = prop;
     344                 :            : 
     345                 :          0 :         prop = drm_property_create(dev,
     346                 :            :                         DRM_MODE_PROP_BLOB,
     347                 :            :                         "CTM", 0);
     348         [ #  # ]:          0 :         if (!prop)
     349                 :            :                 return -ENOMEM;
     350                 :          0 :         dev->mode_config.ctm_property = prop;
     351                 :            : 
     352                 :          0 :         prop = drm_property_create(dev,
     353                 :            :                         DRM_MODE_PROP_BLOB,
     354                 :            :                         "GAMMA_LUT", 0);
     355         [ #  # ]:          0 :         if (!prop)
     356                 :            :                 return -ENOMEM;
     357                 :          0 :         dev->mode_config.gamma_lut_property = prop;
     358                 :            : 
     359                 :          0 :         prop = drm_property_create_range(dev,
     360                 :            :                         DRM_MODE_PROP_IMMUTABLE,
     361                 :            :                         "GAMMA_LUT_SIZE", 0, UINT_MAX);
     362         [ #  # ]:          0 :         if (!prop)
     363                 :            :                 return -ENOMEM;
     364                 :          0 :         dev->mode_config.gamma_lut_size_property = prop;
     365                 :            : 
     366                 :          0 :         prop = drm_property_create(dev,
     367                 :            :                                    DRM_MODE_PROP_IMMUTABLE | DRM_MODE_PROP_BLOB,
     368                 :            :                                    "IN_FORMATS", 0);
     369         [ #  # ]:          0 :         if (!prop)
     370                 :            :                 return -ENOMEM;
     371                 :          0 :         dev->mode_config.modifiers_property = prop;
     372                 :            : 
     373                 :          0 :         return 0;
     374                 :            : }
     375                 :            : 
     376                 :            : /**
     377                 :            :  * drm_mode_config_init - initialize DRM mode_configuration structure
     378                 :            :  * @dev: DRM device
     379                 :            :  *
     380                 :            :  * Initialize @dev's mode_config structure, used for tracking the graphics
     381                 :            :  * configuration of @dev.
     382                 :            :  *
     383                 :            :  * Since this initializes the modeset locks, no locking is possible. Which is no
     384                 :            :  * problem, since this should happen single threaded at init time. It is the
     385                 :            :  * driver's problem to ensure this guarantee.
     386                 :            :  *
     387                 :            :  */
     388                 :          0 : void drm_mode_config_init(struct drm_device *dev)
     389                 :            : {
     390                 :          0 :         mutex_init(&dev->mode_config.mutex);
     391                 :          0 :         drm_modeset_lock_init(&dev->mode_config.connection_mutex);
     392                 :          0 :         mutex_init(&dev->mode_config.idr_mutex);
     393                 :          0 :         mutex_init(&dev->mode_config.fb_lock);
     394                 :          0 :         mutex_init(&dev->mode_config.blob_lock);
     395                 :          0 :         INIT_LIST_HEAD(&dev->mode_config.fb_list);
     396                 :          0 :         INIT_LIST_HEAD(&dev->mode_config.crtc_list);
     397                 :          0 :         INIT_LIST_HEAD(&dev->mode_config.connector_list);
     398                 :          0 :         INIT_LIST_HEAD(&dev->mode_config.encoder_list);
     399                 :          0 :         INIT_LIST_HEAD(&dev->mode_config.property_list);
     400                 :          0 :         INIT_LIST_HEAD(&dev->mode_config.property_blob_list);
     401                 :          0 :         INIT_LIST_HEAD(&dev->mode_config.plane_list);
     402                 :          0 :         INIT_LIST_HEAD(&dev->mode_config.privobj_list);
     403                 :          0 :         idr_init(&dev->mode_config.object_idr);
     404                 :          0 :         idr_init(&dev->mode_config.tile_idr);
     405                 :          0 :         ida_init(&dev->mode_config.connector_ida);
     406                 :          0 :         spin_lock_init(&dev->mode_config.connector_list_lock);
     407                 :            : 
     408                 :          0 :         init_llist_head(&dev->mode_config.connector_free_list);
     409                 :          0 :         INIT_WORK(&dev->mode_config.connector_free_work, drm_connector_free_work_fn);
     410                 :            : 
     411                 :          0 :         drm_mode_create_standard_properties(dev);
     412                 :            : 
     413                 :            :         /* Just to be sure */
     414                 :          0 :         dev->mode_config.num_fb = 0;
     415                 :          0 :         dev->mode_config.num_connector = 0;
     416                 :          0 :         dev->mode_config.num_crtc = 0;
     417                 :          0 :         dev->mode_config.num_encoder = 0;
     418                 :          0 :         dev->mode_config.num_total_plane = 0;
     419                 :            : 
     420                 :          0 :         if (IS_ENABLED(CONFIG_LOCKDEP)) {
     421                 :            :                 struct drm_modeset_acquire_ctx modeset_ctx;
     422                 :            :                 struct ww_acquire_ctx resv_ctx;
     423                 :            :                 struct dma_resv resv;
     424                 :            :                 int ret;
     425                 :            : 
     426                 :            :                 dma_resv_init(&resv);
     427                 :            : 
     428                 :            :                 drm_modeset_acquire_init(&modeset_ctx, 0);
     429                 :            :                 ret = drm_modeset_lock(&dev->mode_config.connection_mutex,
     430                 :            :                                        &modeset_ctx);
     431                 :            :                 if (ret == -EDEADLK)
     432                 :            :                         ret = drm_modeset_backoff(&modeset_ctx);
     433                 :            : 
     434                 :            :                 ww_acquire_init(&resv_ctx, &reservation_ww_class);
     435                 :            :                 ret = dma_resv_lock(&resv, &resv_ctx);
     436                 :            :                 if (ret == -EDEADLK)
     437                 :            :                         dma_resv_lock_slow(&resv, &resv_ctx);
     438                 :            : 
     439                 :            :                 dma_resv_unlock(&resv);
     440                 :            :                 ww_acquire_fini(&resv_ctx);
     441                 :            : 
     442                 :            :                 drm_modeset_drop_locks(&modeset_ctx);
     443                 :            :                 drm_modeset_acquire_fini(&modeset_ctx);
     444                 :            :                 dma_resv_fini(&resv);
     445                 :            :         }
     446                 :          0 : }
     447                 :            : EXPORT_SYMBOL(drm_mode_config_init);
     448                 :            : 
     449                 :            : /**
     450                 :            :  * drm_mode_config_cleanup - free up DRM mode_config info
     451                 :            :  * @dev: DRM device
     452                 :            :  *
     453                 :            :  * Free up all the connectors and CRTCs associated with this DRM device, then
     454                 :            :  * free up the framebuffers and associated buffer objects.
     455                 :            :  *
     456                 :            :  * Note that since this /should/ happen single-threaded at driver/device
     457                 :            :  * teardown time, no locking is required. It's the driver's job to ensure that
     458                 :            :  * this guarantee actually holds true.
     459                 :            :  */
     460                 :          0 : void drm_mode_config_cleanup(struct drm_device *dev)
     461                 :            : {
     462                 :          0 :         struct drm_connector *connector;
     463                 :          0 :         struct drm_connector_list_iter conn_iter;
     464                 :          0 :         struct drm_crtc *crtc, *ct;
     465                 :          0 :         struct drm_encoder *encoder, *enct;
     466                 :          0 :         struct drm_framebuffer *fb, *fbt;
     467                 :          0 :         struct drm_property *property, *pt;
     468                 :          0 :         struct drm_property_blob *blob, *bt;
     469                 :          0 :         struct drm_plane *plane, *plt;
     470                 :            : 
     471         [ #  # ]:          0 :         list_for_each_entry_safe(encoder, enct, &dev->mode_config.encoder_list,
     472                 :            :                                  head) {
     473                 :          0 :                 encoder->funcs->destroy(encoder);
     474                 :            :         }
     475                 :            : 
     476                 :          0 :         drm_connector_list_iter_begin(dev, &conn_iter);
     477         [ #  # ]:          0 :         drm_for_each_connector_iter(connector, &conn_iter) {
     478                 :            :                 /* drm_connector_list_iter holds an full reference to the
     479                 :            :                  * current connector itself, which means it is inherently safe
     480                 :            :                  * against unreferencing the current connector - but not against
     481                 :            :                  * deleting it right away. */
     482                 :          0 :                 drm_connector_put(connector);
     483                 :            :         }
     484                 :          0 :         drm_connector_list_iter_end(&conn_iter);
     485                 :            :         /* connector_iter drops references in a work item. */
     486                 :          0 :         flush_work(&dev->mode_config.connector_free_work);
     487   [ #  #  #  # ]:          0 :         if (WARN_ON(!list_empty(&dev->mode_config.connector_list))) {
     488                 :          0 :                 drm_connector_list_iter_begin(dev, &conn_iter);
     489         [ #  # ]:          0 :                 drm_for_each_connector_iter(connector, &conn_iter)
     490                 :          0 :                         DRM_ERROR("connector %s leaked!\n", connector->name);
     491                 :          0 :                 drm_connector_list_iter_end(&conn_iter);
     492                 :            :         }
     493                 :            : 
     494         [ #  # ]:          0 :         list_for_each_entry_safe(property, pt, &dev->mode_config.property_list,
     495                 :            :                                  head) {
     496                 :          0 :                 drm_property_destroy(dev, property);
     497                 :            :         }
     498                 :            : 
     499         [ #  # ]:          0 :         list_for_each_entry_safe(plane, plt, &dev->mode_config.plane_list,
     500                 :            :                                  head) {
     501                 :          0 :                 plane->funcs->destroy(plane);
     502                 :            :         }
     503                 :            : 
     504         [ #  # ]:          0 :         list_for_each_entry_safe(crtc, ct, &dev->mode_config.crtc_list, head) {
     505                 :          0 :                 crtc->funcs->destroy(crtc);
     506                 :            :         }
     507                 :            : 
     508         [ #  # ]:          0 :         list_for_each_entry_safe(blob, bt, &dev->mode_config.property_blob_list,
     509                 :            :                                  head_global) {
     510                 :          0 :                 drm_property_blob_put(blob);
     511                 :            :         }
     512                 :            : 
     513                 :            :         /*
     514                 :            :          * Single-threaded teardown context, so it's not required to grab the
     515                 :            :          * fb_lock to protect against concurrent fb_list access. Contrary, it
     516                 :            :          * would actually deadlock with the drm_framebuffer_cleanup function.
     517                 :            :          *
     518                 :            :          * Also, if there are any framebuffers left, that's a driver leak now,
     519                 :            :          * so politely WARN about this.
     520                 :            :          */
     521         [ #  # ]:          0 :         WARN_ON(!list_empty(&dev->mode_config.fb_list));
     522         [ #  # ]:          0 :         list_for_each_entry_safe(fb, fbt, &dev->mode_config.fb_list, head) {
     523                 :          0 :                 struct drm_printer p = drm_debug_printer("[leaked fb]");
     524                 :          0 :                 drm_printf(&p, "framebuffer[%u]:\n", fb->base.id);
     525                 :          0 :                 drm_framebuffer_print_info(&p, 1, fb);
     526                 :          0 :                 drm_framebuffer_free(&fb->base.refcount);
     527                 :            :         }
     528                 :            : 
     529                 :          0 :         ida_destroy(&dev->mode_config.connector_ida);
     530                 :          0 :         idr_destroy(&dev->mode_config.tile_idr);
     531                 :          0 :         idr_destroy(&dev->mode_config.object_idr);
     532         [ #  # ]:          0 :         drm_modeset_lock_fini(&dev->mode_config.connection_mutex);
     533                 :          0 : }
     534                 :            : EXPORT_SYMBOL(drm_mode_config_cleanup);

Generated by: LCOV version 1.14