2 * Copyright (c) 2016 Intel Corporation
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.
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
23 #include <linux/export.h>
24 #include <linux/uaccess.h>
26 #include <drm/drm_crtc.h>
27 #include <drm/drm_drv.h>
28 #include <drm/drm_file.h>
29 #include <drm/drm_framebuffer.h>
30 #include <drm/drm_property.h>
32 #include "drm_crtc_internal.h"
37 * Properties as represented by &drm_property are used to extend the modeset
38 * interface exposed to userspace. For the atomic modeset IOCTL properties are
39 * even the only way to transport metadata about the desired new modeset
40 * configuration from userspace to the kernel. Properties have a well-defined
41 * value range, which is enforced by the drm core. See the documentation of the
42 * flags member of &struct drm_property for an overview of the different
43 * property types and ranges.
45 * Properties don't store the current value directly, but need to be
46 * instatiated by attaching them to a &drm_mode_object with
47 * drm_object_attach_property().
49 * Property values are only 64bit. To support bigger piles of data (like gamma
50 * tables, color correction matrices or large structures) a property can instead
51 * point at a &drm_property_blob with that additional data.
53 * Properties are defined by their symbolic name, userspace must keep a
54 * per-object mapping from those names to the property ID used in the atomic
55 * IOCTL and in the get/set property IOCTL.
58 static bool drm_property_flags_valid(u32 flags
)
60 u32 legacy_type
= flags
& DRM_MODE_PROP_LEGACY_TYPE
;
61 u32 ext_type
= flags
& DRM_MODE_PROP_EXTENDED_TYPE
;
63 /* Reject undefined/deprecated flags */
64 if (flags
& ~(DRM_MODE_PROP_LEGACY_TYPE
|
65 DRM_MODE_PROP_EXTENDED_TYPE
|
66 DRM_MODE_PROP_IMMUTABLE
|
67 DRM_MODE_PROP_ATOMIC
))
70 /* We want either a legacy type or an extended type, but not both */
71 if (!legacy_type
== !ext_type
)
74 /* Only one legacy type at a time please */
75 if (legacy_type
&& !is_power_of_2(legacy_type
))
82 * drm_property_create - create a new property type
84 * @flags: flags specifying the property type
85 * @name: name of the property
86 * @num_values: number of pre-defined values
88 * This creates a new generic drm property which can then be attached to a drm
89 * object with drm_object_attach_property(). The returned property object must
90 * be freed with drm_property_destroy(), which is done automatically when
91 * calling drm_mode_config_cleanup().
94 * A pointer to the newly created property on success, NULL on failure.
96 struct drm_property
*drm_property_create(struct drm_device
*dev
,
97 u32 flags
, const char *name
,
100 struct drm_property
*property
= NULL
;
103 if (WARN_ON(!drm_property_flags_valid(flags
)))
106 if (WARN_ON(strlen(name
) >= DRM_PROP_NAME_LEN
))
109 property
= kzalloc(sizeof(struct drm_property
), GFP_KERNEL
);
116 property
->values
= kcalloc(num_values
, sizeof(uint64_t),
118 if (!property
->values
)
122 ret
= drm_mode_object_add(dev
, &property
->base
, DRM_MODE_OBJECT_PROPERTY
);
126 property
->flags
= flags
;
127 property
->num_values
= num_values
;
128 INIT_LIST_HEAD(&property
->enum_list
);
130 strncpy(property
->name
, name
, DRM_PROP_NAME_LEN
);
131 property
->name
[DRM_PROP_NAME_LEN
-1] = '\0';
133 list_add_tail(&property
->head
, &dev
->mode_config
.property_list
);
137 kfree(property
->values
);
141 EXPORT_SYMBOL(drm_property_create
);
144 * drm_property_create_enum - create a new enumeration property type
146 * @flags: flags specifying the property type
147 * @name: name of the property
148 * @props: enumeration lists with property values
149 * @num_values: number of pre-defined values
151 * This creates a new generic drm property which can then be attached to a drm
152 * object with drm_object_attach_property(). The returned property object must
153 * be freed with drm_property_destroy(), which is done automatically when
154 * calling drm_mode_config_cleanup().
156 * Userspace is only allowed to set one of the predefined values for enumeration
160 * A pointer to the newly created property on success, NULL on failure.
162 struct drm_property
*drm_property_create_enum(struct drm_device
*dev
,
163 u32 flags
, const char *name
,
164 const struct drm_prop_enum_list
*props
,
167 struct drm_property
*property
;
170 flags
|= DRM_MODE_PROP_ENUM
;
172 property
= drm_property_create(dev
, flags
, name
, num_values
);
176 for (i
= 0; i
< num_values
; i
++) {
177 ret
= drm_property_add_enum(property
,
181 drm_property_destroy(dev
, property
);
188 EXPORT_SYMBOL(drm_property_create_enum
);
191 * drm_property_create_bitmask - create a new bitmask property type
193 * @flags: flags specifying the property type
194 * @name: name of the property
195 * @props: enumeration lists with property bitflags
196 * @num_props: size of the @props array
197 * @supported_bits: bitmask of all supported enumeration values
199 * This creates a new bitmask drm property which can then be attached to a drm
200 * object with drm_object_attach_property(). The returned property object must
201 * be freed with drm_property_destroy(), which is done automatically when
202 * calling drm_mode_config_cleanup().
204 * Compared to plain enumeration properties userspace is allowed to set any
205 * or'ed together combination of the predefined property bitflag values
208 * A pointer to the newly created property on success, NULL on failure.
210 struct drm_property
*drm_property_create_bitmask(struct drm_device
*dev
,
211 u32 flags
, const char *name
,
212 const struct drm_prop_enum_list
*props
,
214 uint64_t supported_bits
)
216 struct drm_property
*property
;
218 int num_values
= hweight64(supported_bits
);
220 flags
|= DRM_MODE_PROP_BITMASK
;
222 property
= drm_property_create(dev
, flags
, name
, num_values
);
225 for (i
= 0; i
< num_props
; i
++) {
226 if (!(supported_bits
& (1ULL << props
[i
].type
)))
229 ret
= drm_property_add_enum(property
,
233 drm_property_destroy(dev
, property
);
240 EXPORT_SYMBOL(drm_property_create_bitmask
);
242 static struct drm_property
*property_create_range(struct drm_device
*dev
,
243 u32 flags
, const char *name
,
244 uint64_t min
, uint64_t max
)
246 struct drm_property
*property
;
248 property
= drm_property_create(dev
, flags
, name
, 2);
252 property
->values
[0] = min
;
253 property
->values
[1] = max
;
259 * drm_property_create_range - create a new unsigned ranged property type
261 * @flags: flags specifying the property type
262 * @name: name of the property
263 * @min: minimum value of the property
264 * @max: maximum value of the property
266 * This creates a new generic drm property which can then be attached to a drm
267 * object with drm_object_attach_property(). The returned property object must
268 * be freed with drm_property_destroy(), which is done automatically when
269 * calling drm_mode_config_cleanup().
271 * Userspace is allowed to set any unsigned integer value in the (min, max)
275 * A pointer to the newly created property on success, NULL on failure.
277 struct drm_property
*drm_property_create_range(struct drm_device
*dev
,
278 u32 flags
, const char *name
,
279 uint64_t min
, uint64_t max
)
281 return property_create_range(dev
, DRM_MODE_PROP_RANGE
| flags
,
284 EXPORT_SYMBOL(drm_property_create_range
);
287 * drm_property_create_signed_range - create a new signed ranged property type
289 * @flags: flags specifying the property type
290 * @name: name of the property
291 * @min: minimum value of the property
292 * @max: maximum value of the property
294 * This creates a new generic drm property which can then be attached to a drm
295 * object with drm_object_attach_property(). The returned property object must
296 * be freed with drm_property_destroy(), which is done automatically when
297 * calling drm_mode_config_cleanup().
299 * Userspace is allowed to set any signed integer value in the (min, max)
303 * A pointer to the newly created property on success, NULL on failure.
305 struct drm_property
*drm_property_create_signed_range(struct drm_device
*dev
,
306 u32 flags
, const char *name
,
307 int64_t min
, int64_t max
)
309 return property_create_range(dev
, DRM_MODE_PROP_SIGNED_RANGE
| flags
,
310 name
, I642U64(min
), I642U64(max
));
312 EXPORT_SYMBOL(drm_property_create_signed_range
);
315 * drm_property_create_object - create a new object property type
317 * @flags: flags specifying the property type
318 * @name: name of the property
319 * @type: object type from DRM_MODE_OBJECT_* defines
321 * This creates a new generic drm property which can then be attached to a drm
322 * object with drm_object_attach_property(). The returned property object must
323 * be freed with drm_property_destroy(), which is done automatically when
324 * calling drm_mode_config_cleanup().
326 * Userspace is only allowed to set this to any property value of the given
327 * @type. Only useful for atomic properties, which is enforced.
330 * A pointer to the newly created property on success, NULL on failure.
332 struct drm_property
*drm_property_create_object(struct drm_device
*dev
,
333 u32 flags
, const char *name
,
336 struct drm_property
*property
;
338 flags
|= DRM_MODE_PROP_OBJECT
;
340 if (WARN_ON(!(flags
& DRM_MODE_PROP_ATOMIC
)))
343 property
= drm_property_create(dev
, flags
, name
, 1);
347 property
->values
[0] = type
;
351 EXPORT_SYMBOL(drm_property_create_object
);
354 * drm_property_create_bool - create a new boolean property type
356 * @flags: flags specifying the property type
357 * @name: name of the property
359 * This creates a new generic drm property which can then be attached to a drm
360 * object with drm_object_attach_property(). The returned property object must
361 * be freed with drm_property_destroy(), which is done automatically when
362 * calling drm_mode_config_cleanup().
364 * This is implemented as a ranged property with only {0, 1} as valid values.
367 * A pointer to the newly created property on success, NULL on failure.
369 struct drm_property
*drm_property_create_bool(struct drm_device
*dev
,
370 u32 flags
, const char *name
)
372 return drm_property_create_range(dev
, flags
, name
, 0, 1);
374 EXPORT_SYMBOL(drm_property_create_bool
);
377 * drm_property_add_enum - add a possible value to an enumeration property
378 * @property: enumeration property to change
379 * @value: value of the new enumeration
380 * @name: symbolic name of the new enumeration
382 * This functions adds enumerations to a property.
384 * It's use is deprecated, drivers should use one of the more specific helpers
385 * to directly create the property with all enumerations already attached.
388 * Zero on success, error code on failure.
390 int drm_property_add_enum(struct drm_property
*property
,
391 uint64_t value
, const char *name
)
393 struct drm_property_enum
*prop_enum
;
396 if (WARN_ON(strlen(name
) >= DRM_PROP_NAME_LEN
))
399 if (WARN_ON(!drm_property_type_is(property
, DRM_MODE_PROP_ENUM
) &&
400 !drm_property_type_is(property
, DRM_MODE_PROP_BITMASK
)))
404 * Bitmask enum properties have the additional constraint of values
407 if (WARN_ON(drm_property_type_is(property
, DRM_MODE_PROP_BITMASK
) &&
411 list_for_each_entry(prop_enum
, &property
->enum_list
, head
) {
412 if (WARN_ON(prop_enum
->value
== value
))
417 if (WARN_ON(index
>= property
->num_values
))
420 prop_enum
= kzalloc(sizeof(struct drm_property_enum
), GFP_KERNEL
);
424 strncpy(prop_enum
->name
, name
, DRM_PROP_NAME_LEN
);
425 prop_enum
->name
[DRM_PROP_NAME_LEN
-1] = '\0';
426 prop_enum
->value
= value
;
428 property
->values
[index
] = value
;
429 list_add_tail(&prop_enum
->head
, &property
->enum_list
);
432 EXPORT_SYMBOL(drm_property_add_enum
);
435 * drm_property_destroy - destroy a drm property
437 * @property: property to destry
439 * This function frees a property including any attached resources like
440 * enumeration values.
442 void drm_property_destroy(struct drm_device
*dev
, struct drm_property
*property
)
444 struct drm_property_enum
*prop_enum
, *pt
;
446 list_for_each_entry_safe(prop_enum
, pt
, &property
->enum_list
, head
) {
447 list_del(&prop_enum
->head
);
451 if (property
->num_values
)
452 kfree(property
->values
);
453 drm_mode_object_unregister(dev
, &property
->base
);
454 list_del(&property
->head
);
457 EXPORT_SYMBOL(drm_property_destroy
);
459 int drm_mode_getproperty_ioctl(struct drm_device
*dev
,
460 void *data
, struct drm_file
*file_priv
)
462 struct drm_mode_get_property
*out_resp
= data
;
463 struct drm_property
*property
;
467 struct drm_property_enum
*prop_enum
;
468 struct drm_mode_property_enum __user
*enum_ptr
;
469 uint64_t __user
*values_ptr
;
471 if (!drm_core_check_feature(dev
, DRIVER_MODESET
))
474 property
= drm_property_find(dev
, file_priv
, out_resp
->prop_id
);
478 strncpy(out_resp
->name
, property
->name
, DRM_PROP_NAME_LEN
);
479 out_resp
->name
[DRM_PROP_NAME_LEN
-1] = 0;
480 out_resp
->flags
= property
->flags
;
482 value_count
= property
->num_values
;
483 values_ptr
= u64_to_user_ptr(out_resp
->values_ptr
);
485 for (i
= 0; i
< value_count
; i
++) {
486 if (i
< out_resp
->count_values
&&
487 put_user(property
->values
[i
], values_ptr
+ i
)) {
491 out_resp
->count_values
= value_count
;
494 enum_ptr
= u64_to_user_ptr(out_resp
->enum_blob_ptr
);
496 if (drm_property_type_is(property
, DRM_MODE_PROP_ENUM
) ||
497 drm_property_type_is(property
, DRM_MODE_PROP_BITMASK
)) {
498 list_for_each_entry(prop_enum
, &property
->enum_list
, head
) {
500 if (out_resp
->count_enum_blobs
< enum_count
)
503 if (copy_to_user(&enum_ptr
[copied
].value
,
504 &prop_enum
->value
, sizeof(uint64_t)))
507 if (copy_to_user(&enum_ptr
[copied
].name
,
508 &prop_enum
->name
, DRM_PROP_NAME_LEN
))
512 out_resp
->count_enum_blobs
= enum_count
;
516 * NOTE: The idea seems to have been to use this to read all the blob
517 * property values. But nothing ever added them to the corresponding
518 * list, userspace always used the special-purpose get_blob ioctl to
519 * read the value for a blob property. It also doesn't make a lot of
520 * sense to return values here when everything else is just metadata for
521 * the property itself.
523 if (drm_property_type_is(property
, DRM_MODE_PROP_BLOB
))
524 out_resp
->count_enum_blobs
= 0;
529 static void drm_property_free_blob(struct kref
*kref
)
531 struct drm_property_blob
*blob
=
532 container_of(kref
, struct drm_property_blob
, base
.refcount
);
534 mutex_lock(&blob
->dev
->mode_config
.blob_lock
);
535 list_del(&blob
->head_global
);
536 mutex_unlock(&blob
->dev
->mode_config
.blob_lock
);
538 drm_mode_object_unregister(blob
->dev
, &blob
->base
);
544 * drm_property_create_blob - Create new blob property
545 * @dev: DRM device to create property for
546 * @length: Length to allocate for blob data
547 * @data: If specified, copies data into blob
549 * Creates a new blob property for a specified DRM device, optionally
550 * copying data. Note that blob properties are meant to be invariant, hence the
551 * data must be filled out before the blob is used as the value of any property.
554 * New blob property with a single reference on success, or an ERR_PTR
557 struct drm_property_blob
*
558 drm_property_create_blob(struct drm_device
*dev
, size_t length
,
561 struct drm_property_blob
*blob
;
564 if (!length
|| length
> INT_MAX
- sizeof(struct drm_property_blob
))
565 return ERR_PTR(-EINVAL
);
567 blob
= kvzalloc(sizeof(struct drm_property_blob
)+length
, GFP_KERNEL
);
569 return ERR_PTR(-ENOMEM
);
571 /* This must be explicitly initialised, so we can safely call list_del
572 * on it in the removal handler, even if it isn't in a file list. */
573 INIT_LIST_HEAD(&blob
->head_file
);
574 blob
->data
= (void *)blob
+ sizeof(*blob
);
575 blob
->length
= length
;
579 memcpy(blob
->data
, data
, length
);
581 ret
= __drm_mode_object_add(dev
, &blob
->base
, DRM_MODE_OBJECT_BLOB
,
582 true, drm_property_free_blob
);
585 return ERR_PTR(-EINVAL
);
588 mutex_lock(&dev
->mode_config
.blob_lock
);
589 list_add_tail(&blob
->head_global
,
590 &dev
->mode_config
.property_blob_list
);
591 mutex_unlock(&dev
->mode_config
.blob_lock
);
595 EXPORT_SYMBOL(drm_property_create_blob
);
598 * drm_property_blob_put - release a blob property reference
599 * @blob: DRM blob property
601 * Releases a reference to a blob property. May free the object.
603 void drm_property_blob_put(struct drm_property_blob
*blob
)
608 drm_mode_object_put(&blob
->base
);
610 EXPORT_SYMBOL(drm_property_blob_put
);
612 void drm_property_destroy_user_blobs(struct drm_device
*dev
,
613 struct drm_file
*file_priv
)
615 struct drm_property_blob
*blob
, *bt
;
618 * When the file gets released that means no one else can access the
619 * blob list any more, so no need to grab dev->blob_lock.
621 list_for_each_entry_safe(blob
, bt
, &file_priv
->blobs
, head_file
) {
622 list_del_init(&blob
->head_file
);
623 drm_property_blob_put(blob
);
628 * drm_property_blob_get - acquire blob property reference
629 * @blob: DRM blob property
631 * Acquires a reference to an existing blob property. Returns @blob, which
632 * allows this to be used as a shorthand in assignments.
634 struct drm_property_blob
*drm_property_blob_get(struct drm_property_blob
*blob
)
636 drm_mode_object_get(&blob
->base
);
639 EXPORT_SYMBOL(drm_property_blob_get
);
642 * drm_property_lookup_blob - look up a blob property and take a reference
644 * @id: id of the blob property
646 * If successful, this takes an additional reference to the blob property.
647 * callers need to make sure to eventually unreference the returned property
648 * again, using drm_property_blob_put().
651 * NULL on failure, pointer to the blob on success.
653 struct drm_property_blob
*drm_property_lookup_blob(struct drm_device
*dev
,
656 struct drm_mode_object
*obj
;
657 struct drm_property_blob
*blob
= NULL
;
659 obj
= __drm_mode_object_find(dev
, NULL
, id
, DRM_MODE_OBJECT_BLOB
);
661 blob
= obj_to_blob(obj
);
664 EXPORT_SYMBOL(drm_property_lookup_blob
);
667 * drm_property_replace_global_blob - replace existing blob property
669 * @replace: location of blob property pointer to be replaced
670 * @length: length of data for new blob, or 0 for no data
671 * @data: content for new blob, or NULL for no data
672 * @obj_holds_id: optional object for property holding blob ID
673 * @prop_holds_id: optional property holding blob ID
674 * @return 0 on success or error on failure
676 * This function will replace a global property in the blob list, optionally
677 * updating a property which holds the ID of that property.
679 * If length is 0 or data is NULL, no new blob will be created, and the holding
680 * property, if specified, will be set to 0.
682 * Access to the replace pointer is assumed to be protected by the caller, e.g.
683 * by holding the relevant modesetting object lock for its parent.
685 * For example, a drm_connector has a 'PATH' property, which contains the ID
686 * of a blob property with the value of the MST path information. Calling this
687 * function with replace pointing to the connector's path_blob_ptr, length and
688 * data set for the new path information, obj_holds_id set to the connector's
689 * base object, and prop_holds_id set to the path property name, will perform
690 * a completely atomic update. The access to path_blob_ptr is protected by the
691 * caller holding a lock on the connector.
693 int drm_property_replace_global_blob(struct drm_device
*dev
,
694 struct drm_property_blob
**replace
,
697 struct drm_mode_object
*obj_holds_id
,
698 struct drm_property
*prop_holds_id
)
700 struct drm_property_blob
*new_blob
= NULL
;
701 struct drm_property_blob
*old_blob
= NULL
;
704 WARN_ON(replace
== NULL
);
708 if (length
&& data
) {
709 new_blob
= drm_property_create_blob(dev
, length
, data
);
710 if (IS_ERR(new_blob
))
711 return PTR_ERR(new_blob
);
715 ret
= drm_object_property_set_value(obj_holds_id
,
718 new_blob
->base
.id
: 0);
723 drm_property_blob_put(old_blob
);
729 drm_property_blob_put(new_blob
);
732 EXPORT_SYMBOL(drm_property_replace_global_blob
);
735 * drm_property_replace_blob - replace a blob property
736 * @blob: a pointer to the member blob to be replaced
737 * @new_blob: the new blob to replace with
739 * Return: true if the blob was in fact replaced.
741 bool drm_property_replace_blob(struct drm_property_blob
**blob
,
742 struct drm_property_blob
*new_blob
)
744 struct drm_property_blob
*old_blob
= *blob
;
746 if (old_blob
== new_blob
)
749 drm_property_blob_put(old_blob
);
751 drm_property_blob_get(new_blob
);
755 EXPORT_SYMBOL(drm_property_replace_blob
);
757 int drm_mode_getblob_ioctl(struct drm_device
*dev
,
758 void *data
, struct drm_file
*file_priv
)
760 struct drm_mode_get_blob
*out_resp
= data
;
761 struct drm_property_blob
*blob
;
764 if (!drm_core_check_feature(dev
, DRIVER_MODESET
))
767 blob
= drm_property_lookup_blob(dev
, out_resp
->blob_id
);
771 if (out_resp
->length
== blob
->length
) {
772 if (copy_to_user(u64_to_user_ptr(out_resp
->data
),
779 out_resp
->length
= blob
->length
;
781 drm_property_blob_put(blob
);
786 int drm_mode_createblob_ioctl(struct drm_device
*dev
,
787 void *data
, struct drm_file
*file_priv
)
789 struct drm_mode_create_blob
*out_resp
= data
;
790 struct drm_property_blob
*blob
;
793 if (!drm_core_check_feature(dev
, DRIVER_MODESET
))
796 blob
= drm_property_create_blob(dev
, out_resp
->length
, NULL
);
798 return PTR_ERR(blob
);
800 if (copy_from_user(blob
->data
,
801 u64_to_user_ptr(out_resp
->data
),
807 /* Dropping the lock between create_blob and our access here is safe
808 * as only the same file_priv can remove the blob; at this point, it is
809 * not associated with any file_priv. */
810 mutex_lock(&dev
->mode_config
.blob_lock
);
811 out_resp
->blob_id
= blob
->base
.id
;
812 list_add_tail(&blob
->head_file
, &file_priv
->blobs
);
813 mutex_unlock(&dev
->mode_config
.blob_lock
);
818 drm_property_blob_put(blob
);
822 int drm_mode_destroyblob_ioctl(struct drm_device
*dev
,
823 void *data
, struct drm_file
*file_priv
)
825 struct drm_mode_destroy_blob
*out_resp
= data
;
826 struct drm_property_blob
*blob
= NULL
, *bt
;
830 if (!drm_core_check_feature(dev
, DRIVER_MODESET
))
833 blob
= drm_property_lookup_blob(dev
, out_resp
->blob_id
);
837 mutex_lock(&dev
->mode_config
.blob_lock
);
838 /* Ensure the property was actually created by this user. */
839 list_for_each_entry(bt
, &file_priv
->blobs
, head_file
) {
851 /* We must drop head_file here, because we may not be the last
852 * reference on the blob. */
853 list_del_init(&blob
->head_file
);
854 mutex_unlock(&dev
->mode_config
.blob_lock
);
856 /* One reference from lookup, and one from the filp. */
857 drm_property_blob_put(blob
);
858 drm_property_blob_put(blob
);
863 mutex_unlock(&dev
->mode_config
.blob_lock
);
864 drm_property_blob_put(blob
);
869 /* Some properties could refer to dynamic refcnt'd objects, or things that
870 * need special locking to handle lifetime issues (ie. to ensure the prop
871 * value doesn't become invalid part way through the property update due to
872 * race). The value returned by reference via 'obj' should be passed back
873 * to drm_property_change_valid_put() after the property is set (and the
874 * object to which the property is attached has a chance to take its own
877 bool drm_property_change_valid_get(struct drm_property
*property
,
878 uint64_t value
, struct drm_mode_object
**ref
)
882 if (property
->flags
& DRM_MODE_PROP_IMMUTABLE
)
887 if (drm_property_type_is(property
, DRM_MODE_PROP_RANGE
)) {
888 if (value
< property
->values
[0] || value
> property
->values
[1])
891 } else if (drm_property_type_is(property
, DRM_MODE_PROP_SIGNED_RANGE
)) {
892 int64_t svalue
= U642I64(value
);
894 if (svalue
< U642I64(property
->values
[0]) ||
895 svalue
> U642I64(property
->values
[1]))
898 } else if (drm_property_type_is(property
, DRM_MODE_PROP_BITMASK
)) {
899 uint64_t valid_mask
= 0;
901 for (i
= 0; i
< property
->num_values
; i
++)
902 valid_mask
|= (1ULL << property
->values
[i
]);
903 return !(value
& ~valid_mask
);
904 } else if (drm_property_type_is(property
, DRM_MODE_PROP_BLOB
)) {
905 struct drm_property_blob
*blob
;
910 blob
= drm_property_lookup_blob(property
->dev
, value
);
917 } else if (drm_property_type_is(property
, DRM_MODE_PROP_OBJECT
)) {
918 /* a zero value for an object property translates to null: */
922 *ref
= __drm_mode_object_find(property
->dev
, NULL
, value
,
923 property
->values
[0]);
927 for (i
= 0; i
< property
->num_values
; i
++)
928 if (property
->values
[i
] == value
)
933 void drm_property_change_valid_put(struct drm_property
*property
,
934 struct drm_mode_object
*ref
)
939 if (drm_property_type_is(property
, DRM_MODE_PROP_OBJECT
)) {
940 drm_mode_object_put(ref
);
941 } else if (drm_property_type_is(property
, DRM_MODE_PROP_BLOB
))
942 drm_property_blob_put(obj_to_blob(ref
));