LCOV - code coverage report
Current view: top level - drivers/gpu/drm - drm_mode_object.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 42 173 24.3 %
Date: 2023-04-06 08:38:28 Functions: 6 20 30.0 %

          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         613 : 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             :         int ret;
      44             : 
      45         613 :         WARN_ON(!dev->driver->load && dev->registered && !obj_free_cb);
      46             : 
      47         613 :         mutex_lock(&dev->mode_config.idr_mutex);
      48         613 :         ret = idr_alloc(&dev->mode_config.object_idr, register_obj ? obj : NULL,
      49             :                         1, 0, GFP_KERNEL);
      50         613 :         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         613 :                 obj->id = ret;
      56         613 :                 obj->type = obj_type;
      57         613 :                 if (obj_free_cb) {
      58          12 :                         obj->free_cb = obj_free_cb;
      59          12 :                         kref_init(&obj->refcount);
      60             :                 }
      61             :         }
      62         613 :         mutex_unlock(&dev->mode_config.idr_mutex);
      63             : 
      64         613 :         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         601 : int drm_mode_object_add(struct drm_device *dev,
      80             :                         struct drm_mode_object *obj, uint32_t obj_type)
      81             : {
      82         601 :         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 identifier
      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         613 : void drm_mode_object_unregister(struct drm_device *dev,
     105             :                                 struct drm_mode_object *object)
     106             : {
     107         613 :         WARN_ON(!dev->driver->load && dev->registered && !object->free_cb);
     108             : 
     109         613 :         mutex_lock(&dev->mode_config.idr_mutex);
     110         613 :         if (object->id) {
     111         613 :                 idr_remove(&dev->mode_config.object_idr, object->id);
     112         613 :                 object->id = 0;
     113             :         }
     114         613 :         mutex_unlock(&dev->mode_config.idr_mutex);
     115         613 : }
     116             : 
     117             : /**
     118             :  * drm_mode_object_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             :         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           0 :                 obj = NULL;
     146           0 :         if (obj && obj->id != id)
     147           0 :                 obj = NULL;
     148             : 
     149           0 :         if (obj && drm_mode_object_lease_required(obj->type) &&
     150           0 :             !_drm_lease_held(file_priv, obj->id))
     151           0 :                 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          95 : void drm_object_attach_property(struct drm_mode_object *obj,
     232             :                                 struct drm_property *property,
     233             :                                 uint64_t init_val)
     234             : {
     235          95 :         int count = obj->properties->count;
     236          95 :         struct drm_device *dev = property->dev;
     237             : 
     238             : 
     239          95 :         if (obj->type == DRM_MODE_OBJECT_CONNECTOR) {
     240          74 :                 struct drm_connector *connector = obj_to_connector(obj);
     241             : 
     242          74 :                 WARN_ON(!dev->driver->load &&
     243             :                         connector->registration_state == DRM_CONNECTOR_REGISTERED);
     244             :         } else {
     245          21 :                 WARN_ON(!dev->driver->load && dev->registered);
     246             :         }
     247             : 
     248          95 :         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          95 :         obj->properties->properties[count] = property;
     257          95 :         obj->properties->values[count] = init_val;
     258          95 :         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             :         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             : static int __drm_object_property_get_prop_value(struct drm_mode_object *obj,
     301             :                                                 struct drm_property *property,
     302             :                                                 uint64_t *val)
     303             : {
     304             :         int i;
     305             : 
     306          24 :         for (i = 0; i < obj->properties->count; i++) {
     307          28 :                 if (obj->properties->properties[i] == property) {
     308           4 :                         *val = obj->properties->values[i];
     309             :                         return 0;
     310             :                 }
     311             :         }
     312             : 
     313             :         return -EINVAL;
     314             : }
     315             : 
     316           0 : static int __drm_object_property_get_value(struct drm_mode_object *obj,
     317             :                                            struct drm_property *property,
     318             :                                            uint64_t *val)
     319             : {
     320             : 
     321             :         /* read-only properties bypass atomic mechanism and still store
     322             :          * their value in obj->properties->values[].. mostly to avoid
     323             :          * having to deal w/ EDID and similar props in atomic paths:
     324             :          */
     325           0 :         if (drm_drv_uses_atomic_modeset(property->dev) &&
     326           0 :                         !(property->flags & DRM_MODE_PROP_IMMUTABLE))
     327           0 :                 return drm_atomic_get_property(obj, property, val);
     328             : 
     329           0 :         return __drm_object_property_get_prop_value(obj, property, val);
     330             : }
     331             : 
     332             : /**
     333             :  * drm_object_property_get_value - retrieve the value of a property
     334             :  * @obj: drm mode object to get property value from
     335             :  * @property: property to retrieve
     336             :  * @val: storage for the property value
     337             :  *
     338             :  * This function retrieves the softare state of the given property for the given
     339             :  * property. Since there is no driver callback to retrieve the current property
     340             :  * value this might be out of sync with the hardware, depending upon the driver
     341             :  * and property.
     342             :  *
     343             :  * Atomic drivers should never call this function directly, the core will read
     344             :  * out property values through the various ->atomic_get_property callbacks.
     345             :  *
     346             :  * Returns:
     347             :  * Zero on success, error code on failure.
     348             :  */
     349           0 : int drm_object_property_get_value(struct drm_mode_object *obj,
     350             :                                   struct drm_property *property, uint64_t *val)
     351             : {
     352           0 :         WARN_ON(drm_drv_uses_atomic_modeset(property->dev));
     353             : 
     354           0 :         return __drm_object_property_get_value(obj, property, val);
     355             : }
     356             : EXPORT_SYMBOL(drm_object_property_get_value);
     357             : 
     358             : /**
     359             :  * drm_object_property_get_default_value - retrieve the default value of a
     360             :  * property when in atomic mode.
     361             :  * @obj: drm mode object to get property value from
     362             :  * @property: property to retrieve
     363             :  * @val: storage for the property value
     364             :  *
     365             :  * This function retrieves the default state of the given property as passed in
     366             :  * to drm_object_attach_property
     367             :  *
     368             :  * Only atomic drivers should call this function directly, as for non-atomic
     369             :  * drivers it will return the current value.
     370             :  *
     371             :  * Returns:
     372             :  * Zero on success, error code on failure.
     373             :  */
     374           4 : int drm_object_property_get_default_value(struct drm_mode_object *obj,
     375             :                                           struct drm_property *property,
     376             :                                           uint64_t *val)
     377             : {
     378           8 :         WARN_ON(!drm_drv_uses_atomic_modeset(property->dev));
     379             : 
     380           8 :         return __drm_object_property_get_prop_value(obj, property, val);
     381             : }
     382             : EXPORT_SYMBOL(drm_object_property_get_default_value);
     383             : 
     384             : /* helper for getconnector and getproperties ioctls */
     385           0 : int drm_mode_object_get_properties(struct drm_mode_object *obj, bool atomic,
     386             :                                    uint32_t __user *prop_ptr,
     387             :                                    uint64_t __user *prop_values,
     388             :                                    uint32_t *arg_count_props)
     389             : {
     390             :         int i, ret, count;
     391             : 
     392           0 :         for (i = 0, count = 0; i < obj->properties->count; i++) {
     393           0 :                 struct drm_property *prop = obj->properties->properties[i];
     394             :                 uint64_t val;
     395             : 
     396           0 :                 if ((prop->flags & DRM_MODE_PROP_ATOMIC) && !atomic)
     397           0 :                         continue;
     398             : 
     399           0 :                 if (*arg_count_props > count) {
     400           0 :                         ret = __drm_object_property_get_value(obj, prop, &val);
     401           0 :                         if (ret)
     402           0 :                                 return ret;
     403             : 
     404           0 :                         if (put_user(prop->base.id, prop_ptr + count))
     405             :                                 return -EFAULT;
     406             : 
     407           0 :                         if (put_user(val, prop_values + count))
     408             :                                 return -EFAULT;
     409             :                 }
     410             : 
     411           0 :                 count++;
     412             :         }
     413           0 :         *arg_count_props = count;
     414             : 
     415           0 :         return 0;
     416             : }
     417             : 
     418             : /**
     419             :  * drm_mode_obj_get_properties_ioctl - get the current value of a object's property
     420             :  * @dev: DRM device
     421             :  * @data: ioctl data
     422             :  * @file_priv: DRM file info
     423             :  *
     424             :  * This function retrieves the current value for an object's property. Compared
     425             :  * to the connector specific ioctl this one is extended to also work on crtc and
     426             :  * plane objects.
     427             :  *
     428             :  * Called by the user via ioctl.
     429             :  *
     430             :  * Returns:
     431             :  * Zero on success, negative errno on failure.
     432             :  */
     433           0 : int drm_mode_obj_get_properties_ioctl(struct drm_device *dev, void *data,
     434             :                                       struct drm_file *file_priv)
     435             : {
     436           0 :         struct drm_mode_obj_get_properties *arg = data;
     437             :         struct drm_mode_object *obj;
     438             :         struct drm_modeset_acquire_ctx ctx;
     439           0 :         int ret = 0;
     440             : 
     441           0 :         if (!drm_core_check_feature(dev, DRIVER_MODESET))
     442             :                 return -EOPNOTSUPP;
     443             : 
     444           0 :         DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, 0, ret);
     445             : 
     446           0 :         obj = drm_mode_object_find(dev, file_priv, arg->obj_id, arg->obj_type);
     447           0 :         if (!obj) {
     448             :                 ret = -ENOENT;
     449             :                 goto out;
     450             :         }
     451           0 :         if (!obj->properties) {
     452             :                 ret = -EINVAL;
     453             :                 goto out_unref;
     454             :         }
     455             : 
     456           0 :         ret = drm_mode_object_get_properties(obj, file_priv->atomic,
     457           0 :                         (uint32_t __user *)(unsigned long)(arg->props_ptr),
     458           0 :                         (uint64_t __user *)(unsigned long)(arg->prop_values_ptr),
     459           0 :                         &arg->count_props);
     460             : 
     461             : out_unref:
     462           0 :         drm_mode_object_put(obj);
     463             : out:
     464           0 :         DRM_MODESET_LOCK_ALL_END(dev, ctx, ret);
     465             :         return ret;
     466             : }
     467             : 
     468          17 : struct drm_property *drm_mode_obj_find_prop_id(struct drm_mode_object *obj,
     469             :                                                uint32_t prop_id)
     470             : {
     471             :         int i;
     472             : 
     473          17 :         for (i = 0; i < obj->properties->count; i++)
     474          17 :                 if (obj->properties->properties[i]->base.id == prop_id)
     475             :                         return obj->properties->properties[i];
     476             : 
     477             :         return NULL;
     478             : }
     479             : 
     480           0 : static int set_property_legacy(struct drm_mode_object *obj,
     481             :                                struct drm_property *prop,
     482             :                                uint64_t prop_value)
     483             : {
     484           0 :         struct drm_device *dev = prop->dev;
     485             :         struct drm_mode_object *ref;
     486             :         struct drm_modeset_acquire_ctx ctx;
     487           0 :         int ret = -EINVAL;
     488             : 
     489           0 :         if (!drm_property_change_valid_get(prop, prop_value, &ref))
     490             :                 return -EINVAL;
     491             : 
     492           0 :         DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, 0, ret);
     493           0 :         switch (obj->type) {
     494             :         case DRM_MODE_OBJECT_CONNECTOR:
     495           0 :                 ret = drm_connector_set_obj_prop(obj, prop, prop_value);
     496           0 :                 break;
     497             :         case DRM_MODE_OBJECT_CRTC:
     498           0 :                 ret = drm_mode_crtc_set_obj_prop(obj, prop, prop_value);
     499           0 :                 break;
     500             :         case DRM_MODE_OBJECT_PLANE:
     501           0 :                 ret = drm_mode_plane_set_obj_prop(obj_to_plane(obj),
     502             :                                                   prop, prop_value);
     503           0 :                 break;
     504             :         }
     505           0 :         drm_property_change_valid_put(prop, ref);
     506           0 :         DRM_MODESET_LOCK_ALL_END(dev, ctx, ret);
     507             : 
     508             :         return ret;
     509             : }
     510             : 
     511           0 : static int set_property_atomic(struct drm_mode_object *obj,
     512             :                                struct drm_file *file_priv,
     513             :                                struct drm_property *prop,
     514             :                                uint64_t prop_value)
     515             : {
     516           0 :         struct drm_device *dev = prop->dev;
     517             :         struct drm_atomic_state *state;
     518             :         struct drm_modeset_acquire_ctx ctx;
     519             :         int ret;
     520             : 
     521           0 :         state = drm_atomic_state_alloc(dev);
     522           0 :         if (!state)
     523             :                 return -ENOMEM;
     524             : 
     525           0 :         drm_modeset_acquire_init(&ctx, 0);
     526           0 :         state->acquire_ctx = &ctx;
     527             : 
     528             : retry:
     529           0 :         if (prop == state->dev->mode_config.dpms_property) {
     530           0 :                 if (obj->type != DRM_MODE_OBJECT_CONNECTOR) {
     531             :                         ret = -EINVAL;
     532             :                         goto out;
     533             :                 }
     534             : 
     535           0 :                 ret = drm_atomic_connector_commit_dpms(state,
     536           0 :                                                        obj_to_connector(obj),
     537             :                                                        prop_value);
     538             :         } else {
     539           0 :                 ret = drm_atomic_set_property(state, file_priv, obj, prop, prop_value);
     540           0 :                 if (ret)
     541             :                         goto out;
     542           0 :                 ret = drm_atomic_commit(state);
     543             :         }
     544             : out:
     545           0 :         if (ret == -EDEADLK) {
     546           0 :                 drm_atomic_state_clear(state);
     547           0 :                 drm_modeset_backoff(&ctx);
     548           0 :                 goto retry;
     549             :         }
     550             : 
     551           0 :         drm_atomic_state_put(state);
     552             : 
     553           0 :         drm_modeset_drop_locks(&ctx);
     554           0 :         drm_modeset_acquire_fini(&ctx);
     555             : 
     556           0 :         return ret;
     557             : }
     558             : 
     559           0 : int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,
     560             :                                     struct drm_file *file_priv)
     561             : {
     562           0 :         struct drm_mode_obj_set_property *arg = data;
     563             :         struct drm_mode_object *arg_obj;
     564             :         struct drm_property *property;
     565           0 :         int ret = -EINVAL;
     566             : 
     567           0 :         if (!drm_core_check_feature(dev, DRIVER_MODESET))
     568             :                 return -EOPNOTSUPP;
     569             : 
     570           0 :         arg_obj = drm_mode_object_find(dev, file_priv, arg->obj_id, arg->obj_type);
     571           0 :         if (!arg_obj)
     572             :                 return -ENOENT;
     573             : 
     574           0 :         if (!arg_obj->properties)
     575             :                 goto out_unref;
     576             : 
     577           0 :         property = drm_mode_obj_find_prop_id(arg_obj, arg->prop_id);
     578           0 :         if (!property)
     579             :                 goto out_unref;
     580             : 
     581           0 :         if (drm_drv_uses_atomic_modeset(property->dev))
     582           0 :                 ret = set_property_atomic(arg_obj, file_priv, property, arg->value);
     583             :         else
     584           0 :                 ret = set_property_legacy(arg_obj, property, arg->value);
     585             : 
     586             : out_unref:
     587           0 :         drm_mode_object_put(arg_obj);
     588           0 :         return ret;
     589             : }

Generated by: LCOV version 1.14