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 174 24.1 %
Date: 2023-07-19 18:55:55 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         763 : 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         763 :         WARN_ON(!dev->driver->load && dev->registered && !obj_free_cb);
      46             : 
      47         763 :         mutex_lock(&dev->mode_config.idr_mutex);
      48         763 :         ret = idr_alloc(&dev->mode_config.object_idr, register_obj ? obj : NULL,
      49             :                         1, 0, GFP_KERNEL);
      50         763 :         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         763 :                 obj->id = ret;
      56         763 :                 obj->type = obj_type;
      57         763 :                 if (obj_free_cb) {
      58          12 :                         obj->free_cb = obj_free_cb;
      59          12 :                         kref_init(&obj->refcount);
      60             :                 }
      61             :         }
      62         763 :         mutex_unlock(&dev->mode_config.idr_mutex);
      63             : 
      64         763 :         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         751 : int drm_mode_object_add(struct drm_device *dev,
      80             :                         struct drm_mode_object *obj, uint32_t obj_type)
      81             : {
      82         751 :         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         763 : void drm_mode_object_unregister(struct drm_device *dev,
     105             :                                 struct drm_mode_object *object)
     106             : {
     107         763 :         WARN_ON(!dev->driver->load && dev->registered && !object->free_cb);
     108             : 
     109         763 :         mutex_lock(&dev->mode_config.idr_mutex);
     110         763 :         if (object->id) {
     111         763 :                 idr_remove(&dev->mode_config.object_idr, object->id);
     112         763 :                 object->id = 0;
     113             :         }
     114         763 :         mutex_unlock(&dev->mode_config.idr_mutex);
     115         763 : }
     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 :                 drm_dbg_kms(dev, "[OBJECT:%d] not included in lease", id);
     152           0 :                 obj = NULL;
     153             :         }
     154             : 
     155           0 :         if (obj && obj->free_cb) {
     156           0 :                 if (!kref_get_unless_zero(&obj->refcount))
     157           0 :                         obj = NULL;
     158             :         }
     159           0 :         mutex_unlock(&dev->mode_config.idr_mutex);
     160             : 
     161           0 :         return obj;
     162             : }
     163             : 
     164             : /**
     165             :  * drm_mode_object_find - look up a drm object with static lifetime
     166             :  * @dev: drm device
     167             :  * @file_priv: drm file
     168             :  * @id: id of the mode object
     169             :  * @type: type of the mode object
     170             :  *
     171             :  * This function is used to look up a modeset object. It will acquire a
     172             :  * reference for reference counted objects. This reference must be dropped again
     173             :  * by callind drm_mode_object_put().
     174             :  */
     175           0 : struct drm_mode_object *drm_mode_object_find(struct drm_device *dev,
     176             :                 struct drm_file *file_priv,
     177             :                 uint32_t id, uint32_t type)
     178             : {
     179           0 :         struct drm_mode_object *obj = NULL;
     180             : 
     181           0 :         obj = __drm_mode_object_find(dev, file_priv, id, type);
     182           0 :         return obj;
     183             : }
     184             : EXPORT_SYMBOL(drm_mode_object_find);
     185             : 
     186             : /**
     187             :  * drm_mode_object_put - release a mode object reference
     188             :  * @obj: DRM mode object
     189             :  *
     190             :  * This function decrements the object's refcount if it is a refcounted modeset
     191             :  * object. It is a no-op on any other object. This is used to drop references
     192             :  * acquired with drm_mode_object_get().
     193             :  */
     194           0 : void drm_mode_object_put(struct drm_mode_object *obj)
     195             : {
     196           0 :         if (obj->free_cb) {
     197           0 :                 DRM_DEBUG("OBJ ID: %d (%d)\n", obj->id, kref_read(&obj->refcount));
     198           0 :                 kref_put(&obj->refcount, obj->free_cb);
     199             :         }
     200           0 : }
     201             : EXPORT_SYMBOL(drm_mode_object_put);
     202             : 
     203             : /**
     204             :  * drm_mode_object_get - acquire a mode object reference
     205             :  * @obj: DRM mode object
     206             :  *
     207             :  * This function increments the object's refcount if it is a refcounted modeset
     208             :  * object. It is a no-op on any other object. References should be dropped again
     209             :  * by calling drm_mode_object_put().
     210             :  */
     211           0 : void drm_mode_object_get(struct drm_mode_object *obj)
     212             : {
     213           0 :         if (obj->free_cb) {
     214           0 :                 DRM_DEBUG("OBJ ID: %d (%d)\n", obj->id, kref_read(&obj->refcount));
     215           0 :                 kref_get(&obj->refcount);
     216             :         }
     217           0 : }
     218             : EXPORT_SYMBOL(drm_mode_object_get);
     219             : 
     220             : /**
     221             :  * drm_object_attach_property - attach a property to a modeset object
     222             :  * @obj: drm modeset object
     223             :  * @property: property to attach
     224             :  * @init_val: initial value of the property
     225             :  *
     226             :  * This attaches the given property to the modeset object with the given initial
     227             :  * value. Currently this function cannot fail since the properties are stored in
     228             :  * a statically sized array.
     229             :  *
     230             :  * Note that all properties must be attached before the object itself is
     231             :  * registered and accessible from userspace.
     232             :  */
     233          95 : void drm_object_attach_property(struct drm_mode_object *obj,
     234             :                                 struct drm_property *property,
     235             :                                 uint64_t init_val)
     236             : {
     237          95 :         int count = obj->properties->count;
     238          95 :         struct drm_device *dev = property->dev;
     239             : 
     240             : 
     241          95 :         if (obj->type == DRM_MODE_OBJECT_CONNECTOR) {
     242          74 :                 struct drm_connector *connector = obj_to_connector(obj);
     243             : 
     244          74 :                 WARN_ON(!dev->driver->load &&
     245             :                         connector->registration_state == DRM_CONNECTOR_REGISTERED);
     246             :         } else {
     247          21 :                 WARN_ON(!dev->driver->load && dev->registered);
     248             :         }
     249             : 
     250          95 :         if (count == DRM_OBJECT_MAX_PROPERTY) {
     251           0 :                 WARN(1, "Failed to attach object property (type: 0x%x). Please "
     252             :                         "increase DRM_OBJECT_MAX_PROPERTY by 1 for each time "
     253             :                         "you see this message on the same object type.\n",
     254             :                         obj->type);
     255           0 :                 return;
     256             :         }
     257             : 
     258          95 :         obj->properties->properties[count] = property;
     259          95 :         obj->properties->values[count] = init_val;
     260          95 :         obj->properties->count++;
     261             : }
     262             : EXPORT_SYMBOL(drm_object_attach_property);
     263             : 
     264             : /**
     265             :  * drm_object_property_set_value - set the value of a property
     266             :  * @obj: drm mode object to set property value for
     267             :  * @property: property to set
     268             :  * @val: value the property should be set to
     269             :  *
     270             :  * This function sets a given property on a given object. This function only
     271             :  * changes the software state of the property, it does not call into the
     272             :  * driver's ->set_property callback.
     273             :  *
     274             :  * Note that atomic drivers should not have any need to call this, the core will
     275             :  * ensure consistency of values reported back to userspace through the
     276             :  * appropriate ->atomic_get_property callback. Only legacy drivers should call
     277             :  * this function to update the tracked value (after clamping and other
     278             :  * restrictions have been applied).
     279             :  *
     280             :  * Returns:
     281             :  * Zero on success, error code on failure.
     282             :  */
     283           0 : int drm_object_property_set_value(struct drm_mode_object *obj,
     284             :                                   struct drm_property *property, uint64_t val)
     285             : {
     286             :         int i;
     287             : 
     288           0 :         WARN_ON(drm_drv_uses_atomic_modeset(property->dev) &&
     289             :                 !(property->flags & DRM_MODE_PROP_IMMUTABLE));
     290             : 
     291           0 :         for (i = 0; i < obj->properties->count; i++) {
     292           0 :                 if (obj->properties->properties[i] == property) {
     293           0 :                         obj->properties->values[i] = val;
     294           0 :                         return 0;
     295             :                 }
     296             :         }
     297             : 
     298             :         return -EINVAL;
     299             : }
     300             : EXPORT_SYMBOL(drm_object_property_set_value);
     301             : 
     302             : static int __drm_object_property_get_prop_value(struct drm_mode_object *obj,
     303             :                                                 struct drm_property *property,
     304             :                                                 uint64_t *val)
     305             : {
     306             :         int i;
     307             : 
     308          24 :         for (i = 0; i < obj->properties->count; i++) {
     309          28 :                 if (obj->properties->properties[i] == property) {
     310           4 :                         *val = obj->properties->values[i];
     311             :                         return 0;
     312             :                 }
     313             :         }
     314             : 
     315             :         return -EINVAL;
     316             : }
     317             : 
     318           0 : static int __drm_object_property_get_value(struct drm_mode_object *obj,
     319             :                                            struct drm_property *property,
     320             :                                            uint64_t *val)
     321             : {
     322             : 
     323             :         /* read-only properties bypass atomic mechanism and still store
     324             :          * their value in obj->properties->values[].. mostly to avoid
     325             :          * having to deal w/ EDID and similar props in atomic paths:
     326             :          */
     327           0 :         if (drm_drv_uses_atomic_modeset(property->dev) &&
     328           0 :                         !(property->flags & DRM_MODE_PROP_IMMUTABLE))
     329           0 :                 return drm_atomic_get_property(obj, property, val);
     330             : 
     331           0 :         return __drm_object_property_get_prop_value(obj, property, val);
     332             : }
     333             : 
     334             : /**
     335             :  * drm_object_property_get_value - retrieve the value of a property
     336             :  * @obj: drm mode object to get property value from
     337             :  * @property: property to retrieve
     338             :  * @val: storage for the property value
     339             :  *
     340             :  * This function retrieves the softare state of the given property for the given
     341             :  * property. Since there is no driver callback to retrieve the current property
     342             :  * value this might be out of sync with the hardware, depending upon the driver
     343             :  * and property.
     344             :  *
     345             :  * Atomic drivers should never call this function directly, the core will read
     346             :  * out property values through the various ->atomic_get_property callbacks.
     347             :  *
     348             :  * Returns:
     349             :  * Zero on success, error code on failure.
     350             :  */
     351           0 : int drm_object_property_get_value(struct drm_mode_object *obj,
     352             :                                   struct drm_property *property, uint64_t *val)
     353             : {
     354           0 :         WARN_ON(drm_drv_uses_atomic_modeset(property->dev));
     355             : 
     356           0 :         return __drm_object_property_get_value(obj, property, val);
     357             : }
     358             : EXPORT_SYMBOL(drm_object_property_get_value);
     359             : 
     360             : /**
     361             :  * drm_object_property_get_default_value - retrieve the default value of a
     362             :  * property when in atomic mode.
     363             :  * @obj: drm mode object to get property value from
     364             :  * @property: property to retrieve
     365             :  * @val: storage for the property value
     366             :  *
     367             :  * This function retrieves the default state of the given property as passed in
     368             :  * to drm_object_attach_property
     369             :  *
     370             :  * Only atomic drivers should call this function directly, as for non-atomic
     371             :  * drivers it will return the current value.
     372             :  *
     373             :  * Returns:
     374             :  * Zero on success, error code on failure.
     375             :  */
     376           4 : int drm_object_property_get_default_value(struct drm_mode_object *obj,
     377             :                                           struct drm_property *property,
     378             :                                           uint64_t *val)
     379             : {
     380           8 :         WARN_ON(!drm_drv_uses_atomic_modeset(property->dev));
     381             : 
     382           8 :         return __drm_object_property_get_prop_value(obj, property, val);
     383             : }
     384             : EXPORT_SYMBOL(drm_object_property_get_default_value);
     385             : 
     386             : /* helper for getconnector and getproperties ioctls */
     387           0 : int drm_mode_object_get_properties(struct drm_mode_object *obj, bool atomic,
     388             :                                    uint32_t __user *prop_ptr,
     389             :                                    uint64_t __user *prop_values,
     390             :                                    uint32_t *arg_count_props)
     391             : {
     392             :         int i, ret, count;
     393             : 
     394           0 :         for (i = 0, count = 0; i < obj->properties->count; i++) {
     395           0 :                 struct drm_property *prop = obj->properties->properties[i];
     396             :                 uint64_t val;
     397             : 
     398           0 :                 if ((prop->flags & DRM_MODE_PROP_ATOMIC) && !atomic)
     399           0 :                         continue;
     400             : 
     401           0 :                 if (*arg_count_props > count) {
     402           0 :                         ret = __drm_object_property_get_value(obj, prop, &val);
     403           0 :                         if (ret)
     404           0 :                                 return ret;
     405             : 
     406           0 :                         if (put_user(prop->base.id, prop_ptr + count))
     407             :                                 return -EFAULT;
     408             : 
     409           0 :                         if (put_user(val, prop_values + count))
     410             :                                 return -EFAULT;
     411             :                 }
     412             : 
     413           0 :                 count++;
     414             :         }
     415           0 :         *arg_count_props = count;
     416             : 
     417           0 :         return 0;
     418             : }
     419             : 
     420             : /**
     421             :  * drm_mode_obj_get_properties_ioctl - get the current value of a object's property
     422             :  * @dev: DRM device
     423             :  * @data: ioctl data
     424             :  * @file_priv: DRM file info
     425             :  *
     426             :  * This function retrieves the current value for an object's property. Compared
     427             :  * to the connector specific ioctl this one is extended to also work on crtc and
     428             :  * plane objects.
     429             :  *
     430             :  * Called by the user via ioctl.
     431             :  *
     432             :  * Returns:
     433             :  * Zero on success, negative errno on failure.
     434             :  */
     435           0 : int drm_mode_obj_get_properties_ioctl(struct drm_device *dev, void *data,
     436             :                                       struct drm_file *file_priv)
     437             : {
     438           0 :         struct drm_mode_obj_get_properties *arg = data;
     439             :         struct drm_mode_object *obj;
     440             :         struct drm_modeset_acquire_ctx ctx;
     441           0 :         int ret = 0;
     442             : 
     443           0 :         if (!drm_core_check_feature(dev, DRIVER_MODESET))
     444             :                 return -EOPNOTSUPP;
     445             : 
     446           0 :         DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, 0, ret);
     447             : 
     448           0 :         obj = drm_mode_object_find(dev, file_priv, arg->obj_id, arg->obj_type);
     449           0 :         if (!obj) {
     450             :                 ret = -ENOENT;
     451             :                 goto out;
     452             :         }
     453           0 :         if (!obj->properties) {
     454             :                 ret = -EINVAL;
     455             :                 goto out_unref;
     456             :         }
     457             : 
     458           0 :         ret = drm_mode_object_get_properties(obj, file_priv->atomic,
     459           0 :                         (uint32_t __user *)(unsigned long)(arg->props_ptr),
     460           0 :                         (uint64_t __user *)(unsigned long)(arg->prop_values_ptr),
     461           0 :                         &arg->count_props);
     462             : 
     463             : out_unref:
     464           0 :         drm_mode_object_put(obj);
     465             : out:
     466           0 :         DRM_MODESET_LOCK_ALL_END(dev, ctx, ret);
     467             :         return ret;
     468             : }
     469             : 
     470          17 : struct drm_property *drm_mode_obj_find_prop_id(struct drm_mode_object *obj,
     471             :                                                uint32_t prop_id)
     472             : {
     473             :         int i;
     474             : 
     475          17 :         for (i = 0; i < obj->properties->count; i++)
     476          17 :                 if (obj->properties->properties[i]->base.id == prop_id)
     477             :                         return obj->properties->properties[i];
     478             : 
     479             :         return NULL;
     480             : }
     481             : 
     482           0 : static int set_property_legacy(struct drm_mode_object *obj,
     483             :                                struct drm_property *prop,
     484             :                                uint64_t prop_value)
     485             : {
     486           0 :         struct drm_device *dev = prop->dev;
     487             :         struct drm_mode_object *ref;
     488             :         struct drm_modeset_acquire_ctx ctx;
     489           0 :         int ret = -EINVAL;
     490             : 
     491           0 :         if (!drm_property_change_valid_get(prop, prop_value, &ref))
     492             :                 return -EINVAL;
     493             : 
     494           0 :         DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, 0, ret);
     495           0 :         switch (obj->type) {
     496             :         case DRM_MODE_OBJECT_CONNECTOR:
     497           0 :                 ret = drm_connector_set_obj_prop(obj, prop, prop_value);
     498           0 :                 break;
     499             :         case DRM_MODE_OBJECT_CRTC:
     500           0 :                 ret = drm_mode_crtc_set_obj_prop(obj, prop, prop_value);
     501           0 :                 break;
     502             :         case DRM_MODE_OBJECT_PLANE:
     503           0 :                 ret = drm_mode_plane_set_obj_prop(obj_to_plane(obj),
     504             :                                                   prop, prop_value);
     505           0 :                 break;
     506             :         }
     507           0 :         drm_property_change_valid_put(prop, ref);
     508           0 :         DRM_MODESET_LOCK_ALL_END(dev, ctx, ret);
     509             : 
     510             :         return ret;
     511             : }
     512             : 
     513           0 : static int set_property_atomic(struct drm_mode_object *obj,
     514             :                                struct drm_file *file_priv,
     515             :                                struct drm_property *prop,
     516             :                                uint64_t prop_value)
     517             : {
     518           0 :         struct drm_device *dev = prop->dev;
     519             :         struct drm_atomic_state *state;
     520             :         struct drm_modeset_acquire_ctx ctx;
     521             :         int ret;
     522             : 
     523           0 :         state = drm_atomic_state_alloc(dev);
     524           0 :         if (!state)
     525             :                 return -ENOMEM;
     526             : 
     527           0 :         drm_modeset_acquire_init(&ctx, 0);
     528           0 :         state->acquire_ctx = &ctx;
     529             : 
     530             : retry:
     531           0 :         if (prop == state->dev->mode_config.dpms_property) {
     532           0 :                 if (obj->type != DRM_MODE_OBJECT_CONNECTOR) {
     533             :                         ret = -EINVAL;
     534             :                         goto out;
     535             :                 }
     536             : 
     537           0 :                 ret = drm_atomic_connector_commit_dpms(state,
     538           0 :                                                        obj_to_connector(obj),
     539             :                                                        prop_value);
     540             :         } else {
     541           0 :                 ret = drm_atomic_set_property(state, file_priv, obj, prop, prop_value);
     542           0 :                 if (ret)
     543             :                         goto out;
     544           0 :                 ret = drm_atomic_commit(state);
     545             :         }
     546             : out:
     547           0 :         if (ret == -EDEADLK) {
     548           0 :                 drm_atomic_state_clear(state);
     549           0 :                 drm_modeset_backoff(&ctx);
     550           0 :                 goto retry;
     551             :         }
     552             : 
     553           0 :         drm_atomic_state_put(state);
     554             : 
     555           0 :         drm_modeset_drop_locks(&ctx);
     556           0 :         drm_modeset_acquire_fini(&ctx);
     557             : 
     558           0 :         return ret;
     559             : }
     560             : 
     561           0 : int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,
     562             :                                     struct drm_file *file_priv)
     563             : {
     564           0 :         struct drm_mode_obj_set_property *arg = data;
     565             :         struct drm_mode_object *arg_obj;
     566             :         struct drm_property *property;
     567           0 :         int ret = -EINVAL;
     568             : 
     569           0 :         if (!drm_core_check_feature(dev, DRIVER_MODESET))
     570             :                 return -EOPNOTSUPP;
     571             : 
     572           0 :         arg_obj = drm_mode_object_find(dev, file_priv, arg->obj_id, arg->obj_type);
     573           0 :         if (!arg_obj)
     574             :                 return -ENOENT;
     575             : 
     576           0 :         if (!arg_obj->properties)
     577             :                 goto out_unref;
     578             : 
     579           0 :         property = drm_mode_obj_find_prop_id(arg_obj, arg->prop_id);
     580           0 :         if (!property)
     581             :                 goto out_unref;
     582             : 
     583           0 :         if (drm_drv_uses_atomic_modeset(property->dev))
     584           0 :                 ret = set_property_atomic(arg_obj, file_priv, property, arg->value);
     585             :         else
     586           0 :                 ret = set_property_legacy(arg_obj, property, arg->value);
     587             : 
     588             : out_unref:
     589           0 :         drm_mode_object_put(arg_obj);
     590           0 :         return ret;
     591             : }

Generated by: LCOV version 1.14