LCOV - code coverage report
Current view: top level - drivers/gpu/drm - drm_mode_object.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 0 201 0.0 %
Date: 2022-04-01 14:35:51 Functions: 0 19 0.0 %
Branches: 0 148 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/export.h>
      24                 :            : #include <linux/uaccess.h>
      25                 :            : 
      26                 :            : #include <drm/drm_atomic.h>
      27                 :            : #include <drm/drm_drv.h>
      28                 :            : #include <drm/drm_device.h>
      29                 :            : #include <drm/drm_file.h>
      30                 :            : #include <drm/drm_mode_object.h>
      31                 :            : #include <drm/drm_print.h>
      32                 :            : 
      33                 :            : #include "drm_crtc_internal.h"
      34                 :            : 
      35                 :            : /*
      36                 :            :  * Internal function to assign a slot in the object idr and optionally
      37                 :            :  * register the object into the idr.
      38                 :            :  */
      39                 :          0 : int __drm_mode_object_add(struct drm_device *dev, struct drm_mode_object *obj,
      40                 :            :                           uint32_t obj_type, bool register_obj,
      41                 :            :                           void (*obj_free_cb)(struct kref *kref))
      42                 :            : {
      43                 :          0 :         int ret;
      44                 :            : 
      45   [ #  #  #  #  :          0 :         WARN_ON(!dev->driver->load && dev->registered && !obj_free_cb);
             #  #  #  # ]
      46                 :            : 
      47                 :          0 :         mutex_lock(&dev->mode_config.idr_mutex);
      48         [ #  # ]:          0 :         ret = idr_alloc(&dev->mode_config.object_idr, register_obj ? obj : NULL,
      49                 :            :                         1, 0, GFP_KERNEL);
      50         [ #  # ]:          0 :         if (ret >= 0) {
      51                 :            :                 /*
      52                 :            :                  * Set up the object linking under the protection of the idr
      53                 :            :                  * lock so that other users can't see inconsistent state.
      54                 :            :                  */
      55                 :          0 :                 obj->id = ret;
      56                 :          0 :                 obj->type = obj_type;
      57         [ #  # ]:          0 :                 if (obj_free_cb) {
      58                 :          0 :                         obj->free_cb = obj_free_cb;
      59                 :          0 :                         kref_init(&obj->refcount);
      60                 :            :                 }
      61                 :            :         }
      62                 :          0 :         mutex_unlock(&dev->mode_config.idr_mutex);
      63                 :            : 
      64                 :          0 :         return ret < 0 ? ret : 0;
      65                 :            : }
      66                 :            : 
      67                 :            : /**
      68                 :            :  * drm_mode_object_add - allocate a new modeset identifier
      69                 :            :  * @dev: DRM device
      70                 :            :  * @obj: object pointer, used to generate unique ID
      71                 :            :  * @obj_type: object type
      72                 :            :  *
      73                 :            :  * Create a unique identifier based on @ptr in @dev's identifier space.  Used
      74                 :            :  * for tracking modes, CRTCs and connectors.
      75                 :            :  *
      76                 :            :  * Returns:
      77                 :            :  * Zero on success, error code on failure.
      78                 :            :  */
      79                 :          0 : int drm_mode_object_add(struct drm_device *dev,
      80                 :            :                         struct drm_mode_object *obj, uint32_t obj_type)
      81                 :            : {
      82                 :          0 :         return __drm_mode_object_add(dev, obj, obj_type, true, NULL);
      83                 :            : }
      84                 :            : 
      85                 :          0 : void drm_mode_object_register(struct drm_device *dev,
      86                 :            :                               struct drm_mode_object *obj)
      87                 :            : {
      88                 :          0 :         mutex_lock(&dev->mode_config.idr_mutex);
      89                 :          0 :         idr_replace(&dev->mode_config.object_idr, obj, obj->id);
      90                 :          0 :         mutex_unlock(&dev->mode_config.idr_mutex);
      91                 :          0 : }
      92                 :            : 
      93                 :            : /**
      94                 :            :  * drm_mode_object_unregister - free a modeset identifer
      95                 :            :  * @dev: DRM device
      96                 :            :  * @object: object to free
      97                 :            :  *
      98                 :            :  * Free @id from @dev's unique identifier pool.
      99                 :            :  * This function can be called multiple times, and guards against
     100                 :            :  * multiple removals.
     101                 :            :  * These modeset identifiers are _not_ reference counted. Hence don't use this
     102                 :            :  * for reference counted modeset objects like framebuffers.
     103                 :            :  */
     104                 :          0 : void drm_mode_object_unregister(struct drm_device *dev,
     105                 :            :                                 struct drm_mode_object *object)
     106                 :            : {
     107   [ #  #  #  #  :          0 :         WARN_ON(!dev->driver->load && dev->registered && !object->free_cb);
             #  #  #  # ]
     108                 :            : 
     109                 :          0 :         mutex_lock(&dev->mode_config.idr_mutex);
     110         [ #  # ]:          0 :         if (object->id) {
     111                 :          0 :                 idr_remove(&dev->mode_config.object_idr, object->id);
     112                 :          0 :                 object->id = 0;
     113                 :            :         }
     114                 :          0 :         mutex_unlock(&dev->mode_config.idr_mutex);
     115                 :          0 : }
     116                 :            : 
     117                 :            : /**
     118                 :            :  * drm_lease_required - check types which must be leased to be used
     119                 :            :  * @type: type of object
     120                 :            :  *
     121                 :            :  * Returns whether the provided type of drm_mode_object must
     122                 :            :  * be owned or leased to be used by a process.
     123                 :            :  */
     124                 :          0 : bool drm_mode_object_lease_required(uint32_t type)
     125                 :            : {
     126         [ #  # ]:          0 :         switch(type) {
     127                 :            :         case DRM_MODE_OBJECT_CRTC:
     128                 :            :         case DRM_MODE_OBJECT_CONNECTOR:
     129                 :            :         case DRM_MODE_OBJECT_PLANE:
     130                 :            :                 return true;
     131                 :          0 :         default:
     132                 :          0 :                 return false;
     133                 :            :         }
     134                 :            : }
     135                 :            : 
     136                 :          0 : struct drm_mode_object *__drm_mode_object_find(struct drm_device *dev,
     137                 :            :                                                struct drm_file *file_priv,
     138                 :            :                                                uint32_t id, uint32_t type)
     139                 :            : {
     140                 :          0 :         struct drm_mode_object *obj = NULL;
     141                 :            : 
     142                 :          0 :         mutex_lock(&dev->mode_config.idr_mutex);
     143                 :          0 :         obj = idr_find(&dev->mode_config.object_idr, id);
     144   [ #  #  #  # ]:          0 :         if (obj && type != DRM_MODE_OBJECT_ANY && obj->type != type)
     145                 :            :                 obj = NULL;
     146   [ #  #  #  # ]:          0 :         if (obj && obj->id != id)
     147                 :            :                 obj = NULL;
     148                 :            : 
     149   [ #  #  #  #  :          0 :         if (obj && drm_mode_object_lease_required(obj->type) &&
                   #  # ]
     150                 :          0 :             !_drm_lease_held(file_priv, obj->id))
     151                 :            :                 obj = NULL;
     152                 :            : 
     153   [ #  #  #  # ]:          0 :         if (obj && obj->free_cb) {
     154         [ #  # ]:          0 :                 if (!kref_get_unless_zero(&obj->refcount))
     155                 :          0 :                         obj = NULL;
     156                 :            :         }
     157                 :          0 :         mutex_unlock(&dev->mode_config.idr_mutex);
     158                 :            : 
     159                 :          0 :         return obj;
     160                 :            : }
     161                 :            : 
     162                 :            : /**
     163                 :            :  * drm_mode_object_find - look up a drm object with static lifetime
     164                 :            :  * @dev: drm device
     165                 :            :  * @file_priv: drm file
     166                 :            :  * @id: id of the mode object
     167                 :            :  * @type: type of the mode object
     168                 :            :  *
     169                 :            :  * This function is used to look up a modeset object. It will acquire a
     170                 :            :  * reference for reference counted objects. This reference must be dropped again
     171                 :            :  * by callind drm_mode_object_put().
     172                 :            :  */
     173                 :          0 : struct drm_mode_object *drm_mode_object_find(struct drm_device *dev,
     174                 :            :                 struct drm_file *file_priv,
     175                 :            :                 uint32_t id, uint32_t type)
     176                 :            : {
     177                 :          0 :         struct drm_mode_object *obj = NULL;
     178                 :            : 
     179                 :          0 :         obj = __drm_mode_object_find(dev, file_priv, id, type);
     180                 :          0 :         return obj;
     181                 :            : }
     182                 :            : EXPORT_SYMBOL(drm_mode_object_find);
     183                 :            : 
     184                 :            : /**
     185                 :            :  * drm_mode_object_put - release a mode object reference
     186                 :            :  * @obj: DRM mode object
     187                 :            :  *
     188                 :            :  * This function decrements the object's refcount if it is a refcounted modeset
     189                 :            :  * object. It is a no-op on any other object. This is used to drop references
     190                 :            :  * acquired with drm_mode_object_get().
     191                 :            :  */
     192                 :          0 : void drm_mode_object_put(struct drm_mode_object *obj)
     193                 :            : {
     194         [ #  # ]:          0 :         if (obj->free_cb) {
     195                 :          0 :                 DRM_DEBUG("OBJ ID: %d (%d)\n", obj->id, kref_read(&obj->refcount));
     196                 :          0 :                 kref_put(&obj->refcount, obj->free_cb);
     197                 :            :         }
     198                 :          0 : }
     199                 :            : EXPORT_SYMBOL(drm_mode_object_put);
     200                 :            : 
     201                 :            : /**
     202                 :            :  * drm_mode_object_get - acquire a mode object reference
     203                 :            :  * @obj: DRM mode object
     204                 :            :  *
     205                 :            :  * This function increments the object's refcount if it is a refcounted modeset
     206                 :            :  * object. It is a no-op on any other object. References should be dropped again
     207                 :            :  * by calling drm_mode_object_put().
     208                 :            :  */
     209                 :          0 : void drm_mode_object_get(struct drm_mode_object *obj)
     210                 :            : {
     211         [ #  # ]:          0 :         if (obj->free_cb) {
     212                 :          0 :                 DRM_DEBUG("OBJ ID: %d (%d)\n", obj->id, kref_read(&obj->refcount));
     213                 :          0 :                 kref_get(&obj->refcount);
     214                 :            :         }
     215                 :          0 : }
     216                 :            : EXPORT_SYMBOL(drm_mode_object_get);
     217                 :            : 
     218                 :            : /**
     219                 :            :  * drm_object_attach_property - attach a property to a modeset object
     220                 :            :  * @obj: drm modeset object
     221                 :            :  * @property: property to attach
     222                 :            :  * @init_val: initial value of the property
     223                 :            :  *
     224                 :            :  * This attaches the given property to the modeset object with the given initial
     225                 :            :  * value. Currently this function cannot fail since the properties are stored in
     226                 :            :  * a statically sized array.
     227                 :            :  *
     228                 :            :  * Note that all properties must be attached before the object itself is
     229                 :            :  * registered and accessible from userspace.
     230                 :            :  */
     231                 :          0 : void drm_object_attach_property(struct drm_mode_object *obj,
     232                 :            :                                 struct drm_property *property,
     233                 :            :                                 uint64_t init_val)
     234                 :            : {
     235                 :          0 :         int count = obj->properties->count;
     236                 :          0 :         struct drm_device *dev = property->dev;
     237                 :            : 
     238                 :            : 
     239         [ #  # ]:          0 :         if (obj->type == DRM_MODE_OBJECT_CONNECTOR) {
     240                 :          0 :                 struct drm_connector *connector = obj_to_connector(obj);
     241                 :            : 
     242   [ #  #  #  #  :          0 :                 WARN_ON(!dev->driver->load &&
                   #  # ]
     243                 :            :                         connector->registration_state == DRM_CONNECTOR_REGISTERED);
     244                 :            :         } else {
     245   [ #  #  #  #  :          0 :                 WARN_ON(!dev->driver->load && dev->registered);
                   #  # ]
     246                 :            :         }
     247                 :            : 
     248         [ #  # ]:          0 :         if (count == DRM_OBJECT_MAX_PROPERTY) {
     249                 :          0 :                 WARN(1, "Failed to attach object property (type: 0x%x). Please "
     250                 :            :                         "increase DRM_OBJECT_MAX_PROPERTY by 1 for each time "
     251                 :            :                         "you see this message on the same object type.\n",
     252                 :            :                         obj->type);
     253                 :          0 :                 return;
     254                 :            :         }
     255                 :            : 
     256                 :          0 :         obj->properties->properties[count] = property;
     257                 :          0 :         obj->properties->values[count] = init_val;
     258                 :          0 :         obj->properties->count++;
     259                 :            : }
     260                 :            : EXPORT_SYMBOL(drm_object_attach_property);
     261                 :            : 
     262                 :            : /**
     263                 :            :  * drm_object_property_set_value - set the value of a property
     264                 :            :  * @obj: drm mode object to set property value for
     265                 :            :  * @property: property to set
     266                 :            :  * @val: value the property should be set to
     267                 :            :  *
     268                 :            :  * This function sets a given property on a given object. This function only
     269                 :            :  * changes the software state of the property, it does not call into the
     270                 :            :  * driver's ->set_property callback.
     271                 :            :  *
     272                 :            :  * Note that atomic drivers should not have any need to call this, the core will
     273                 :            :  * ensure consistency of values reported back to userspace through the
     274                 :            :  * appropriate ->atomic_get_property callback. Only legacy drivers should call
     275                 :            :  * this function to update the tracked value (after clamping and other
     276                 :            :  * restrictions have been applied).
     277                 :            :  *
     278                 :            :  * Returns:
     279                 :            :  * Zero on success, error code on failure.
     280                 :            :  */
     281                 :          0 : int drm_object_property_set_value(struct drm_mode_object *obj,
     282                 :            :                                   struct drm_property *property, uint64_t val)
     283                 :            : {
     284                 :          0 :         int i;
     285                 :            : 
     286   [ #  #  #  #  :          0 :         WARN_ON(drm_drv_uses_atomic_modeset(property->dev) &&
             #  #  #  # ]
     287                 :            :                 !(property->flags & DRM_MODE_PROP_IMMUTABLE));
     288                 :            : 
     289         [ #  # ]:          0 :         for (i = 0; i < obj->properties->count; i++) {
     290         [ #  # ]:          0 :                 if (obj->properties->properties[i] == property) {
     291                 :          0 :                         obj->properties->values[i] = val;
     292                 :          0 :                         return 0;
     293                 :            :                 }
     294                 :            :         }
     295                 :            : 
     296                 :            :         return -EINVAL;
     297                 :            : }
     298                 :            : EXPORT_SYMBOL(drm_object_property_set_value);
     299                 :            : 
     300                 :          0 : static int __drm_object_property_get_value(struct drm_mode_object *obj,
     301                 :            :                                            struct drm_property *property,
     302                 :            :                                            uint64_t *val)
     303                 :            : {
     304                 :          0 :         int i;
     305                 :            : 
     306                 :            :         /* read-only properties bypass atomic mechanism and still store
     307                 :            :          * their value in obj->properties->values[].. mostly to avoid
     308                 :            :          * having to deal w/ EDID and similar props in atomic paths:
     309                 :            :          */
     310   [ #  #  #  # ]:          0 :         if (drm_drv_uses_atomic_modeset(property->dev) &&
     311         [ #  # ]:          0 :                         !(property->flags & DRM_MODE_PROP_IMMUTABLE))
     312                 :          0 :                 return drm_atomic_get_property(obj, property, val);
     313                 :            : 
     314         [ #  # ]:          0 :         for (i = 0; i < obj->properties->count; i++) {
     315         [ #  # ]:          0 :                 if (obj->properties->properties[i] == property) {
     316                 :          0 :                         *val = obj->properties->values[i];
     317                 :          0 :                         return 0;
     318                 :            :                 }
     319                 :            : 
     320                 :            :         }
     321                 :            : 
     322                 :            :         return -EINVAL;
     323                 :            : }
     324                 :            : 
     325                 :            : /**
     326                 :            :  * drm_object_property_get_value - retrieve the value of a property
     327                 :            :  * @obj: drm mode object to get property value from
     328                 :            :  * @property: property to retrieve
     329                 :            :  * @val: storage for the property value
     330                 :            :  *
     331                 :            :  * This function retrieves the softare state of the given property for the given
     332                 :            :  * property. Since there is no driver callback to retrieve the current property
     333                 :            :  * value this might be out of sync with the hardware, depending upon the driver
     334                 :            :  * and property.
     335                 :            :  *
     336                 :            :  * Atomic drivers should never call this function directly, the core will read
     337                 :            :  * out property values through the various ->atomic_get_property callbacks.
     338                 :            :  *
     339                 :            :  * Returns:
     340                 :            :  * Zero on success, error code on failure.
     341                 :            :  */
     342                 :          0 : int drm_object_property_get_value(struct drm_mode_object *obj,
     343                 :            :                                   struct drm_property *property, uint64_t *val)
     344                 :            : {
     345   [ #  #  #  # ]:          0 :         WARN_ON(drm_drv_uses_atomic_modeset(property->dev));
     346                 :            : 
     347                 :          0 :         return __drm_object_property_get_value(obj, property, val);
     348                 :            : }
     349                 :            : EXPORT_SYMBOL(drm_object_property_get_value);
     350                 :            : 
     351                 :            : /* helper for getconnector and getproperties ioctls */
     352                 :          0 : int drm_mode_object_get_properties(struct drm_mode_object *obj, bool atomic,
     353                 :            :                                    uint32_t __user *prop_ptr,
     354                 :            :                                    uint64_t __user *prop_values,
     355                 :            :                                    uint32_t *arg_count_props)
     356                 :            : {
     357                 :          0 :         int i, ret, count;
     358                 :            : 
     359         [ #  # ]:          0 :         for (i = 0, count = 0; i < obj->properties->count; i++) {
     360                 :          0 :                 struct drm_property *prop = obj->properties->properties[i];
     361                 :          0 :                 uint64_t val;
     362                 :            : 
     363   [ #  #  #  # ]:          0 :                 if ((prop->flags & DRM_MODE_PROP_ATOMIC) && !atomic)
     364                 :          0 :                         continue;
     365                 :            : 
     366         [ #  # ]:          0 :                 if (*arg_count_props > count) {
     367                 :          0 :                         ret = __drm_object_property_get_value(obj, prop, &val);
     368         [ #  # ]:          0 :                         if (ret)
     369                 :          0 :                                 return ret;
     370                 :            : 
     371         [ #  # ]:          0 :                         if (put_user(prop->base.id, prop_ptr + count))
     372                 :            :                                 return -EFAULT;
     373                 :            : 
     374         [ #  # ]:          0 :                         if (put_user(val, prop_values + count))
     375                 :            :                                 return -EFAULT;
     376                 :            :                 }
     377                 :            : 
     378                 :          0 :                 count++;
     379                 :            :         }
     380                 :          0 :         *arg_count_props = count;
     381                 :            : 
     382                 :          0 :         return 0;
     383                 :            : }
     384                 :            : 
     385                 :            : /**
     386                 :            :  * drm_mode_obj_get_properties_ioctl - get the current value of a object's property
     387                 :            :  * @dev: DRM device
     388                 :            :  * @data: ioctl data
     389                 :            :  * @file_priv: DRM file info
     390                 :            :  *
     391                 :            :  * This function retrieves the current value for an object's property. Compared
     392                 :            :  * to the connector specific ioctl this one is extended to also work on crtc and
     393                 :            :  * plane objects.
     394                 :            :  *
     395                 :            :  * Called by the user via ioctl.
     396                 :            :  *
     397                 :            :  * Returns:
     398                 :            :  * Zero on success, negative errno on failure.
     399                 :            :  */
     400                 :          0 : int drm_mode_obj_get_properties_ioctl(struct drm_device *dev, void *data,
     401                 :            :                                       struct drm_file *file_priv)
     402                 :            : {
     403                 :          0 :         struct drm_mode_obj_get_properties *arg = data;
     404                 :          0 :         struct drm_mode_object *obj;
     405                 :          0 :         int ret = 0;
     406                 :            : 
     407         [ #  # ]:          0 :         if (!drm_core_check_feature(dev, DRIVER_MODESET))
     408                 :            :                 return -EOPNOTSUPP;
     409                 :            : 
     410                 :          0 :         drm_modeset_lock_all(dev);
     411                 :            : 
     412                 :          0 :         obj = drm_mode_object_find(dev, file_priv, arg->obj_id, arg->obj_type);
     413         [ #  # ]:          0 :         if (!obj) {
     414                 :          0 :                 ret = -ENOENT;
     415                 :          0 :                 goto out;
     416                 :            :         }
     417         [ #  # ]:          0 :         if (!obj->properties) {
     418                 :          0 :                 ret = -EINVAL;
     419                 :          0 :                 goto out_unref;
     420                 :            :         }
     421                 :            : 
     422                 :          0 :         ret = drm_mode_object_get_properties(obj, file_priv->atomic,
     423                 :          0 :                         (uint32_t __user *)(unsigned long)(arg->props_ptr),
     424                 :          0 :                         (uint64_t __user *)(unsigned long)(arg->prop_values_ptr),
     425                 :          0 :                         &arg->count_props);
     426                 :            : 
     427                 :          0 : out_unref:
     428                 :          0 :         drm_mode_object_put(obj);
     429                 :          0 : out:
     430                 :          0 :         drm_modeset_unlock_all(dev);
     431                 :          0 :         return ret;
     432                 :            : }
     433                 :            : 
     434                 :          0 : struct drm_property *drm_mode_obj_find_prop_id(struct drm_mode_object *obj,
     435                 :            :                                                uint32_t prop_id)
     436                 :            : {
     437                 :          0 :         int i;
     438                 :            : 
     439   [ #  #  #  # ]:          0 :         for (i = 0; i < obj->properties->count; i++)
     440   [ #  #  #  # ]:          0 :                 if (obj->properties->properties[i]->base.id == prop_id)
     441                 :          0 :                         return obj->properties->properties[i];
     442                 :            : 
     443                 :            :         return NULL;
     444                 :            : }
     445                 :            : 
     446                 :          0 : static int set_property_legacy(struct drm_mode_object *obj,
     447                 :            :                                struct drm_property *prop,
     448                 :            :                                uint64_t prop_value)
     449                 :            : {
     450                 :          0 :         struct drm_device *dev = prop->dev;
     451                 :          0 :         struct drm_mode_object *ref;
     452                 :          0 :         int ret = -EINVAL;
     453                 :            : 
     454         [ #  # ]:          0 :         if (!drm_property_change_valid_get(prop, prop_value, &ref))
     455                 :            :                 return -EINVAL;
     456                 :            : 
     457                 :          0 :         drm_modeset_lock_all(dev);
     458   [ #  #  #  # ]:          0 :         switch (obj->type) {
     459                 :          0 :         case DRM_MODE_OBJECT_CONNECTOR:
     460                 :          0 :                 ret = drm_connector_set_obj_prop(obj, prop, prop_value);
     461                 :          0 :                 break;
     462                 :          0 :         case DRM_MODE_OBJECT_CRTC:
     463                 :          0 :                 ret = drm_mode_crtc_set_obj_prop(obj, prop, prop_value);
     464                 :          0 :                 break;
     465                 :          0 :         case DRM_MODE_OBJECT_PLANE:
     466                 :          0 :                 ret = drm_mode_plane_set_obj_prop(obj_to_plane(obj),
     467                 :            :                                                   prop, prop_value);
     468                 :          0 :                 break;
     469                 :            :         }
     470                 :          0 :         drm_property_change_valid_put(prop, ref);
     471                 :          0 :         drm_modeset_unlock_all(dev);
     472                 :            : 
     473                 :          0 :         return ret;
     474                 :            : }
     475                 :            : 
     476                 :          0 : static int set_property_atomic(struct drm_mode_object *obj,
     477                 :            :                                struct drm_file *file_priv,
     478                 :            :                                struct drm_property *prop,
     479                 :            :                                uint64_t prop_value)
     480                 :            : {
     481                 :          0 :         struct drm_device *dev = prop->dev;
     482                 :          0 :         struct drm_atomic_state *state;
     483                 :          0 :         struct drm_modeset_acquire_ctx ctx;
     484                 :          0 :         int ret;
     485                 :            : 
     486                 :          0 :         state = drm_atomic_state_alloc(dev);
     487         [ #  # ]:          0 :         if (!state)
     488                 :            :                 return -ENOMEM;
     489                 :            : 
     490                 :          0 :         drm_modeset_acquire_init(&ctx, 0);
     491                 :          0 :         state->acquire_ctx = &ctx;
     492                 :            : 
     493                 :          0 : retry:
     494         [ #  # ]:          0 :         if (prop == state->dev->mode_config.dpms_property) {
     495         [ #  # ]:          0 :                 if (obj->type != DRM_MODE_OBJECT_CONNECTOR) {
     496                 :          0 :                         ret = -EINVAL;
     497                 :          0 :                         goto out;
     498                 :            :                 }
     499                 :            : 
     500                 :          0 :                 ret = drm_atomic_connector_commit_dpms(state,
     501                 :          0 :                                                        obj_to_connector(obj),
     502                 :            :                                                        prop_value);
     503                 :            :         } else {
     504                 :          0 :                 ret = drm_atomic_set_property(state, file_priv, obj, prop, prop_value);
     505         [ #  # ]:          0 :                 if (ret)
     506                 :          0 :                         goto out;
     507                 :          0 :                 ret = drm_atomic_commit(state);
     508                 :            :         }
     509                 :          0 : out:
     510         [ #  # ]:          0 :         if (ret == -EDEADLK) {
     511                 :          0 :                 drm_atomic_state_clear(state);
     512                 :          0 :                 drm_modeset_backoff(&ctx);
     513                 :          0 :                 goto retry;
     514                 :            :         }
     515                 :            : 
     516                 :          0 :         drm_atomic_state_put(state);
     517                 :            : 
     518                 :          0 :         drm_modeset_drop_locks(&ctx);
     519                 :          0 :         drm_modeset_acquire_fini(&ctx);
     520                 :            : 
     521                 :          0 :         return ret;
     522                 :            : }
     523                 :            : 
     524                 :          0 : int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,
     525                 :            :                                     struct drm_file *file_priv)
     526                 :            : {
     527                 :          0 :         struct drm_mode_obj_set_property *arg = data;
     528                 :          0 :         struct drm_mode_object *arg_obj;
     529                 :          0 :         struct drm_property *property;
     530                 :          0 :         int ret = -EINVAL;
     531                 :            : 
     532         [ #  # ]:          0 :         if (!drm_core_check_feature(dev, DRIVER_MODESET))
     533                 :            :                 return -EOPNOTSUPP;
     534                 :            : 
     535                 :          0 :         arg_obj = drm_mode_object_find(dev, file_priv, arg->obj_id, arg->obj_type);
     536         [ #  # ]:          0 :         if (!arg_obj)
     537                 :            :                 return -ENOENT;
     538                 :            : 
     539         [ #  # ]:          0 :         if (!arg_obj->properties)
     540                 :          0 :                 goto out_unref;
     541                 :            : 
     542                 :          0 :         property = drm_mode_obj_find_prop_id(arg_obj, arg->prop_id);
     543         [ #  # ]:          0 :         if (!property)
     544                 :          0 :                 goto out_unref;
     545                 :            : 
     546   [ #  #  #  # ]:          0 :         if (drm_drv_uses_atomic_modeset(property->dev))
     547                 :          0 :                 ret = set_property_atomic(arg_obj, file_priv, property, arg->value);
     548                 :            :         else
     549                 :          0 :                 ret = set_property_legacy(arg_obj, property, arg->value);
     550                 :            : 
     551                 :          0 : out_unref:
     552                 :          0 :         drm_mode_object_put(arg_obj);
     553                 :          0 :         return ret;
     554                 :            : }

Generated by: LCOV version 1.14