1 1.4 riastrad /* $NetBSD: drm_property.c,v 1.4 2021/12/19 09:50:27 riastradh Exp $ */ 2 1.1 riastrad 3 1.1 riastrad /* 4 1.1 riastrad * Copyright (c) 2016 Intel Corporation 5 1.1 riastrad * 6 1.1 riastrad * Permission to use, copy, modify, distribute, and sell this software and its 7 1.1 riastrad * documentation for any purpose is hereby granted without fee, provided that 8 1.1 riastrad * the above copyright notice appear in all copies and that both that copyright 9 1.1 riastrad * notice and this permission notice appear in supporting documentation, and 10 1.1 riastrad * that the name of the copyright holders not be used in advertising or 11 1.1 riastrad * publicity pertaining to distribution of the software without specific, 12 1.1 riastrad * written prior permission. The copyright holders make no representations 13 1.1 riastrad * about the suitability of this software for any purpose. It is provided "as 14 1.1 riastrad * is" without express or implied warranty. 15 1.1 riastrad * 16 1.1 riastrad * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 17 1.1 riastrad * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 18 1.1 riastrad * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 19 1.1 riastrad * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 20 1.1 riastrad * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 21 1.1 riastrad * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 22 1.1 riastrad * OF THIS SOFTWARE. 23 1.1 riastrad */ 24 1.1 riastrad 25 1.1 riastrad #include <sys/cdefs.h> 26 1.4 riastrad __KERNEL_RCSID(0, "$NetBSD: drm_property.c,v 1.4 2021/12/19 09:50:27 riastradh Exp $"); 27 1.1 riastrad 28 1.4 riastrad #include <linux/mm.h> 29 1.1 riastrad #include <linux/export.h> 30 1.1 riastrad #include <linux/uaccess.h> 31 1.1 riastrad 32 1.1 riastrad #include <drm/drm_crtc.h> 33 1.1 riastrad #include <drm/drm_drv.h> 34 1.1 riastrad #include <drm/drm_file.h> 35 1.1 riastrad #include <drm/drm_framebuffer.h> 36 1.1 riastrad #include <drm/drm_property.h> 37 1.1 riastrad 38 1.1 riastrad #include "drm_crtc_internal.h" 39 1.1 riastrad 40 1.1 riastrad /** 41 1.1 riastrad * DOC: overview 42 1.1 riastrad * 43 1.1 riastrad * Properties as represented by &drm_property are used to extend the modeset 44 1.1 riastrad * interface exposed to userspace. For the atomic modeset IOCTL properties are 45 1.1 riastrad * even the only way to transport metadata about the desired new modeset 46 1.1 riastrad * configuration from userspace to the kernel. Properties have a well-defined 47 1.1 riastrad * value range, which is enforced by the drm core. See the documentation of the 48 1.1 riastrad * flags member of &struct drm_property for an overview of the different 49 1.1 riastrad * property types and ranges. 50 1.1 riastrad * 51 1.1 riastrad * Properties don't store the current value directly, but need to be 52 1.1 riastrad * instatiated by attaching them to a &drm_mode_object with 53 1.1 riastrad * drm_object_attach_property(). 54 1.1 riastrad * 55 1.1 riastrad * Property values are only 64bit. To support bigger piles of data (like gamma 56 1.1 riastrad * tables, color correction matrices or large structures) a property can instead 57 1.1 riastrad * point at a &drm_property_blob with that additional data. 58 1.1 riastrad * 59 1.1 riastrad * Properties are defined by their symbolic name, userspace must keep a 60 1.1 riastrad * per-object mapping from those names to the property ID used in the atomic 61 1.1 riastrad * IOCTL and in the get/set property IOCTL. 62 1.1 riastrad */ 63 1.1 riastrad 64 1.1 riastrad static bool drm_property_flags_valid(u32 flags) 65 1.1 riastrad { 66 1.1 riastrad u32 legacy_type = flags & DRM_MODE_PROP_LEGACY_TYPE; 67 1.1 riastrad u32 ext_type = flags & DRM_MODE_PROP_EXTENDED_TYPE; 68 1.1 riastrad 69 1.1 riastrad /* Reject undefined/deprecated flags */ 70 1.1 riastrad if (flags & ~(DRM_MODE_PROP_LEGACY_TYPE | 71 1.1 riastrad DRM_MODE_PROP_EXTENDED_TYPE | 72 1.1 riastrad DRM_MODE_PROP_IMMUTABLE | 73 1.1 riastrad DRM_MODE_PROP_ATOMIC)) 74 1.1 riastrad return false; 75 1.1 riastrad 76 1.1 riastrad /* We want either a legacy type or an extended type, but not both */ 77 1.1 riastrad if (!legacy_type == !ext_type) 78 1.1 riastrad return false; 79 1.1 riastrad 80 1.1 riastrad /* Only one legacy type at a time please */ 81 1.1 riastrad if (legacy_type && !is_power_of_2(legacy_type)) 82 1.1 riastrad return false; 83 1.1 riastrad 84 1.1 riastrad return true; 85 1.1 riastrad } 86 1.1 riastrad 87 1.1 riastrad /** 88 1.1 riastrad * drm_property_create - create a new property type 89 1.1 riastrad * @dev: drm device 90 1.1 riastrad * @flags: flags specifying the property type 91 1.1 riastrad * @name: name of the property 92 1.1 riastrad * @num_values: number of pre-defined values 93 1.1 riastrad * 94 1.1 riastrad * This creates a new generic drm property which can then be attached to a drm 95 1.1 riastrad * object with drm_object_attach_property(). The returned property object must 96 1.1 riastrad * be freed with drm_property_destroy(), which is done automatically when 97 1.1 riastrad * calling drm_mode_config_cleanup(). 98 1.1 riastrad * 99 1.1 riastrad * Returns: 100 1.1 riastrad * A pointer to the newly created property on success, NULL on failure. 101 1.1 riastrad */ 102 1.1 riastrad struct drm_property *drm_property_create(struct drm_device *dev, 103 1.1 riastrad u32 flags, const char *name, 104 1.1 riastrad int num_values) 105 1.1 riastrad { 106 1.1 riastrad struct drm_property *property = NULL; 107 1.1 riastrad int ret; 108 1.1 riastrad 109 1.1 riastrad if (WARN_ON(!drm_property_flags_valid(flags))) 110 1.1 riastrad return NULL; 111 1.1 riastrad 112 1.1 riastrad if (WARN_ON(strlen(name) >= DRM_PROP_NAME_LEN)) 113 1.1 riastrad return NULL; 114 1.1 riastrad 115 1.1 riastrad property = kzalloc(sizeof(struct drm_property), GFP_KERNEL); 116 1.1 riastrad if (!property) 117 1.1 riastrad return NULL; 118 1.1 riastrad 119 1.1 riastrad property->dev = dev; 120 1.1 riastrad 121 1.1 riastrad if (num_values) { 122 1.1 riastrad property->values = kcalloc(num_values, sizeof(uint64_t), 123 1.1 riastrad GFP_KERNEL); 124 1.1 riastrad if (!property->values) 125 1.1 riastrad goto fail; 126 1.1 riastrad } 127 1.1 riastrad 128 1.1 riastrad ret = drm_mode_object_add(dev, &property->base, DRM_MODE_OBJECT_PROPERTY); 129 1.1 riastrad if (ret) 130 1.1 riastrad goto fail; 131 1.1 riastrad 132 1.1 riastrad property->flags = flags; 133 1.1 riastrad property->num_values = num_values; 134 1.1 riastrad INIT_LIST_HEAD(&property->enum_list); 135 1.1 riastrad 136 1.1 riastrad strncpy(property->name, name, DRM_PROP_NAME_LEN); 137 1.1 riastrad property->name[DRM_PROP_NAME_LEN-1] = '\0'; 138 1.1 riastrad 139 1.1 riastrad list_add_tail(&property->head, &dev->mode_config.property_list); 140 1.1 riastrad 141 1.1 riastrad return property; 142 1.1 riastrad fail: 143 1.1 riastrad kfree(property->values); 144 1.1 riastrad kfree(property); 145 1.1 riastrad return NULL; 146 1.1 riastrad } 147 1.1 riastrad EXPORT_SYMBOL(drm_property_create); 148 1.1 riastrad 149 1.1 riastrad /** 150 1.1 riastrad * drm_property_create_enum - create a new enumeration property type 151 1.1 riastrad * @dev: drm device 152 1.1 riastrad * @flags: flags specifying the property type 153 1.1 riastrad * @name: name of the property 154 1.1 riastrad * @props: enumeration lists with property values 155 1.1 riastrad * @num_values: number of pre-defined values 156 1.1 riastrad * 157 1.1 riastrad * This creates a new generic drm property which can then be attached to a drm 158 1.1 riastrad * object with drm_object_attach_property(). The returned property object must 159 1.1 riastrad * be freed with drm_property_destroy(), which is done automatically when 160 1.1 riastrad * calling drm_mode_config_cleanup(). 161 1.1 riastrad * 162 1.1 riastrad * Userspace is only allowed to set one of the predefined values for enumeration 163 1.1 riastrad * properties. 164 1.1 riastrad * 165 1.1 riastrad * Returns: 166 1.1 riastrad * A pointer to the newly created property on success, NULL on failure. 167 1.1 riastrad */ 168 1.1 riastrad struct drm_property *drm_property_create_enum(struct drm_device *dev, 169 1.1 riastrad u32 flags, const char *name, 170 1.1 riastrad const struct drm_prop_enum_list *props, 171 1.1 riastrad int num_values) 172 1.1 riastrad { 173 1.1 riastrad struct drm_property *property; 174 1.1 riastrad int i, ret; 175 1.1 riastrad 176 1.1 riastrad flags |= DRM_MODE_PROP_ENUM; 177 1.1 riastrad 178 1.1 riastrad property = drm_property_create(dev, flags, name, num_values); 179 1.1 riastrad if (!property) 180 1.1 riastrad return NULL; 181 1.1 riastrad 182 1.1 riastrad for (i = 0; i < num_values; i++) { 183 1.1 riastrad ret = drm_property_add_enum(property, 184 1.1 riastrad props[i].type, 185 1.1 riastrad props[i].name); 186 1.1 riastrad if (ret) { 187 1.1 riastrad drm_property_destroy(dev, property); 188 1.1 riastrad return NULL; 189 1.1 riastrad } 190 1.1 riastrad } 191 1.1 riastrad 192 1.1 riastrad return property; 193 1.1 riastrad } 194 1.1 riastrad EXPORT_SYMBOL(drm_property_create_enum); 195 1.1 riastrad 196 1.1 riastrad /** 197 1.1 riastrad * drm_property_create_bitmask - create a new bitmask property type 198 1.1 riastrad * @dev: drm device 199 1.1 riastrad * @flags: flags specifying the property type 200 1.1 riastrad * @name: name of the property 201 1.1 riastrad * @props: enumeration lists with property bitflags 202 1.1 riastrad * @num_props: size of the @props array 203 1.1 riastrad * @supported_bits: bitmask of all supported enumeration values 204 1.1 riastrad * 205 1.1 riastrad * This creates a new bitmask drm property which can then be attached to a drm 206 1.1 riastrad * object with drm_object_attach_property(). The returned property object must 207 1.1 riastrad * be freed with drm_property_destroy(), which is done automatically when 208 1.1 riastrad * calling drm_mode_config_cleanup(). 209 1.1 riastrad * 210 1.1 riastrad * Compared to plain enumeration properties userspace is allowed to set any 211 1.1 riastrad * or'ed together combination of the predefined property bitflag values 212 1.1 riastrad * 213 1.1 riastrad * Returns: 214 1.1 riastrad * A pointer to the newly created property on success, NULL on failure. 215 1.1 riastrad */ 216 1.1 riastrad struct drm_property *drm_property_create_bitmask(struct drm_device *dev, 217 1.1 riastrad u32 flags, const char *name, 218 1.1 riastrad const struct drm_prop_enum_list *props, 219 1.1 riastrad int num_props, 220 1.1 riastrad uint64_t supported_bits) 221 1.1 riastrad { 222 1.1 riastrad struct drm_property *property; 223 1.1 riastrad int i, ret; 224 1.1 riastrad int num_values = hweight64(supported_bits); 225 1.1 riastrad 226 1.1 riastrad flags |= DRM_MODE_PROP_BITMASK; 227 1.1 riastrad 228 1.1 riastrad property = drm_property_create(dev, flags, name, num_values); 229 1.1 riastrad if (!property) 230 1.1 riastrad return NULL; 231 1.1 riastrad for (i = 0; i < num_props; i++) { 232 1.1 riastrad if (!(supported_bits & (1ULL << props[i].type))) 233 1.1 riastrad continue; 234 1.1 riastrad 235 1.1 riastrad ret = drm_property_add_enum(property, 236 1.1 riastrad props[i].type, 237 1.1 riastrad props[i].name); 238 1.1 riastrad if (ret) { 239 1.1 riastrad drm_property_destroy(dev, property); 240 1.1 riastrad return NULL; 241 1.1 riastrad } 242 1.1 riastrad } 243 1.1 riastrad 244 1.1 riastrad return property; 245 1.1 riastrad } 246 1.1 riastrad EXPORT_SYMBOL(drm_property_create_bitmask); 247 1.1 riastrad 248 1.1 riastrad static struct drm_property *property_create_range(struct drm_device *dev, 249 1.1 riastrad u32 flags, const char *name, 250 1.1 riastrad uint64_t min, uint64_t max) 251 1.1 riastrad { 252 1.1 riastrad struct drm_property *property; 253 1.1 riastrad 254 1.1 riastrad property = drm_property_create(dev, flags, name, 2); 255 1.1 riastrad if (!property) 256 1.1 riastrad return NULL; 257 1.1 riastrad 258 1.1 riastrad property->values[0] = min; 259 1.1 riastrad property->values[1] = max; 260 1.1 riastrad 261 1.1 riastrad return property; 262 1.1 riastrad } 263 1.1 riastrad 264 1.1 riastrad /** 265 1.1 riastrad * drm_property_create_range - create a new unsigned ranged property type 266 1.1 riastrad * @dev: drm device 267 1.1 riastrad * @flags: flags specifying the property type 268 1.1 riastrad * @name: name of the property 269 1.1 riastrad * @min: minimum value of the property 270 1.1 riastrad * @max: maximum value of the property 271 1.1 riastrad * 272 1.1 riastrad * This creates a new generic drm property which can then be attached to a drm 273 1.1 riastrad * object with drm_object_attach_property(). The returned property object must 274 1.1 riastrad * be freed with drm_property_destroy(), which is done automatically when 275 1.1 riastrad * calling drm_mode_config_cleanup(). 276 1.1 riastrad * 277 1.1 riastrad * Userspace is allowed to set any unsigned integer value in the (min, max) 278 1.1 riastrad * range inclusive. 279 1.1 riastrad * 280 1.1 riastrad * Returns: 281 1.1 riastrad * A pointer to the newly created property on success, NULL on failure. 282 1.1 riastrad */ 283 1.1 riastrad struct drm_property *drm_property_create_range(struct drm_device *dev, 284 1.1 riastrad u32 flags, const char *name, 285 1.1 riastrad uint64_t min, uint64_t max) 286 1.1 riastrad { 287 1.1 riastrad return property_create_range(dev, DRM_MODE_PROP_RANGE | flags, 288 1.1 riastrad name, min, max); 289 1.1 riastrad } 290 1.1 riastrad EXPORT_SYMBOL(drm_property_create_range); 291 1.1 riastrad 292 1.1 riastrad /** 293 1.1 riastrad * drm_property_create_signed_range - create a new signed ranged property type 294 1.1 riastrad * @dev: drm device 295 1.1 riastrad * @flags: flags specifying the property type 296 1.1 riastrad * @name: name of the property 297 1.1 riastrad * @min: minimum value of the property 298 1.1 riastrad * @max: maximum value of the property 299 1.1 riastrad * 300 1.1 riastrad * This creates a new generic drm property which can then be attached to a drm 301 1.1 riastrad * object with drm_object_attach_property(). The returned property object must 302 1.1 riastrad * be freed with drm_property_destroy(), which is done automatically when 303 1.1 riastrad * calling drm_mode_config_cleanup(). 304 1.1 riastrad * 305 1.1 riastrad * Userspace is allowed to set any signed integer value in the (min, max) 306 1.1 riastrad * range inclusive. 307 1.1 riastrad * 308 1.1 riastrad * Returns: 309 1.1 riastrad * A pointer to the newly created property on success, NULL on failure. 310 1.1 riastrad */ 311 1.1 riastrad struct drm_property *drm_property_create_signed_range(struct drm_device *dev, 312 1.1 riastrad u32 flags, const char *name, 313 1.1 riastrad int64_t min, int64_t max) 314 1.1 riastrad { 315 1.1 riastrad return property_create_range(dev, DRM_MODE_PROP_SIGNED_RANGE | flags, 316 1.1 riastrad name, I642U64(min), I642U64(max)); 317 1.1 riastrad } 318 1.1 riastrad EXPORT_SYMBOL(drm_property_create_signed_range); 319 1.1 riastrad 320 1.1 riastrad /** 321 1.1 riastrad * drm_property_create_object - create a new object property type 322 1.1 riastrad * @dev: drm device 323 1.1 riastrad * @flags: flags specifying the property type 324 1.1 riastrad * @name: name of the property 325 1.1 riastrad * @type: object type from DRM_MODE_OBJECT_* defines 326 1.1 riastrad * 327 1.1 riastrad * This creates a new generic drm property which can then be attached to a drm 328 1.1 riastrad * object with drm_object_attach_property(). The returned property object must 329 1.1 riastrad * be freed with drm_property_destroy(), which is done automatically when 330 1.1 riastrad * calling drm_mode_config_cleanup(). 331 1.1 riastrad * 332 1.1 riastrad * Userspace is only allowed to set this to any property value of the given 333 1.1 riastrad * @type. Only useful for atomic properties, which is enforced. 334 1.1 riastrad * 335 1.1 riastrad * Returns: 336 1.1 riastrad * A pointer to the newly created property on success, NULL on failure. 337 1.1 riastrad */ 338 1.1 riastrad struct drm_property *drm_property_create_object(struct drm_device *dev, 339 1.1 riastrad u32 flags, const char *name, 340 1.1 riastrad uint32_t type) 341 1.1 riastrad { 342 1.1 riastrad struct drm_property *property; 343 1.1 riastrad 344 1.1 riastrad flags |= DRM_MODE_PROP_OBJECT; 345 1.1 riastrad 346 1.1 riastrad if (WARN_ON(!(flags & DRM_MODE_PROP_ATOMIC))) 347 1.1 riastrad return NULL; 348 1.1 riastrad 349 1.1 riastrad property = drm_property_create(dev, flags, name, 1); 350 1.1 riastrad if (!property) 351 1.1 riastrad return NULL; 352 1.1 riastrad 353 1.1 riastrad property->values[0] = type; 354 1.1 riastrad 355 1.1 riastrad return property; 356 1.1 riastrad } 357 1.1 riastrad EXPORT_SYMBOL(drm_property_create_object); 358 1.1 riastrad 359 1.1 riastrad /** 360 1.1 riastrad * drm_property_create_bool - create a new boolean property type 361 1.1 riastrad * @dev: drm device 362 1.1 riastrad * @flags: flags specifying the property type 363 1.1 riastrad * @name: name of the property 364 1.1 riastrad * 365 1.1 riastrad * This creates a new generic drm property which can then be attached to a drm 366 1.1 riastrad * object with drm_object_attach_property(). The returned property object must 367 1.1 riastrad * be freed with drm_property_destroy(), which is done automatically when 368 1.1 riastrad * calling drm_mode_config_cleanup(). 369 1.1 riastrad * 370 1.1 riastrad * This is implemented as a ranged property with only {0, 1} as valid values. 371 1.1 riastrad * 372 1.1 riastrad * Returns: 373 1.1 riastrad * A pointer to the newly created property on success, NULL on failure. 374 1.1 riastrad */ 375 1.1 riastrad struct drm_property *drm_property_create_bool(struct drm_device *dev, 376 1.1 riastrad u32 flags, const char *name) 377 1.1 riastrad { 378 1.1 riastrad return drm_property_create_range(dev, flags, name, 0, 1); 379 1.1 riastrad } 380 1.1 riastrad EXPORT_SYMBOL(drm_property_create_bool); 381 1.1 riastrad 382 1.1 riastrad /** 383 1.1 riastrad * drm_property_add_enum - add a possible value to an enumeration property 384 1.1 riastrad * @property: enumeration property to change 385 1.1 riastrad * @value: value of the new enumeration 386 1.1 riastrad * @name: symbolic name of the new enumeration 387 1.1 riastrad * 388 1.1 riastrad * This functions adds enumerations to a property. 389 1.1 riastrad * 390 1.1 riastrad * It's use is deprecated, drivers should use one of the more specific helpers 391 1.1 riastrad * to directly create the property with all enumerations already attached. 392 1.1 riastrad * 393 1.1 riastrad * Returns: 394 1.1 riastrad * Zero on success, error code on failure. 395 1.1 riastrad */ 396 1.1 riastrad int drm_property_add_enum(struct drm_property *property, 397 1.1 riastrad uint64_t value, const char *name) 398 1.1 riastrad { 399 1.1 riastrad struct drm_property_enum *prop_enum; 400 1.1 riastrad int index = 0; 401 1.1 riastrad 402 1.1 riastrad if (WARN_ON(strlen(name) >= DRM_PROP_NAME_LEN)) 403 1.1 riastrad return -EINVAL; 404 1.1 riastrad 405 1.1 riastrad if (WARN_ON(!drm_property_type_is(property, DRM_MODE_PROP_ENUM) && 406 1.1 riastrad !drm_property_type_is(property, DRM_MODE_PROP_BITMASK))) 407 1.1 riastrad return -EINVAL; 408 1.1 riastrad 409 1.1 riastrad /* 410 1.1 riastrad * Bitmask enum properties have the additional constraint of values 411 1.1 riastrad * from 0 to 63 412 1.1 riastrad */ 413 1.1 riastrad if (WARN_ON(drm_property_type_is(property, DRM_MODE_PROP_BITMASK) && 414 1.1 riastrad value > 63)) 415 1.1 riastrad return -EINVAL; 416 1.1 riastrad 417 1.1 riastrad list_for_each_entry(prop_enum, &property->enum_list, head) { 418 1.1 riastrad if (WARN_ON(prop_enum->value == value)) 419 1.1 riastrad return -EINVAL; 420 1.1 riastrad index++; 421 1.1 riastrad } 422 1.1 riastrad 423 1.1 riastrad if (WARN_ON(index >= property->num_values)) 424 1.1 riastrad return -EINVAL; 425 1.1 riastrad 426 1.1 riastrad prop_enum = kzalloc(sizeof(struct drm_property_enum), GFP_KERNEL); 427 1.1 riastrad if (!prop_enum) 428 1.1 riastrad return -ENOMEM; 429 1.1 riastrad 430 1.1 riastrad strncpy(prop_enum->name, name, DRM_PROP_NAME_LEN); 431 1.1 riastrad prop_enum->name[DRM_PROP_NAME_LEN-1] = '\0'; 432 1.1 riastrad prop_enum->value = value; 433 1.1 riastrad 434 1.1 riastrad property->values[index] = value; 435 1.1 riastrad list_add_tail(&prop_enum->head, &property->enum_list); 436 1.1 riastrad return 0; 437 1.1 riastrad } 438 1.1 riastrad EXPORT_SYMBOL(drm_property_add_enum); 439 1.1 riastrad 440 1.1 riastrad /** 441 1.1 riastrad * drm_property_destroy - destroy a drm property 442 1.1 riastrad * @dev: drm device 443 1.1 riastrad * @property: property to destry 444 1.1 riastrad * 445 1.1 riastrad * This function frees a property including any attached resources like 446 1.1 riastrad * enumeration values. 447 1.1 riastrad */ 448 1.1 riastrad void drm_property_destroy(struct drm_device *dev, struct drm_property *property) 449 1.1 riastrad { 450 1.1 riastrad struct drm_property_enum *prop_enum, *pt; 451 1.1 riastrad 452 1.1 riastrad list_for_each_entry_safe(prop_enum, pt, &property->enum_list, head) { 453 1.1 riastrad list_del(&prop_enum->head); 454 1.1 riastrad kfree(prop_enum); 455 1.1 riastrad } 456 1.1 riastrad 457 1.1 riastrad if (property->num_values) 458 1.1 riastrad kfree(property->values); 459 1.1 riastrad drm_mode_object_unregister(dev, &property->base); 460 1.1 riastrad list_del(&property->head); 461 1.1 riastrad kfree(property); 462 1.1 riastrad } 463 1.1 riastrad EXPORT_SYMBOL(drm_property_destroy); 464 1.1 riastrad 465 1.1 riastrad int drm_mode_getproperty_ioctl(struct drm_device *dev, 466 1.1 riastrad void *data, struct drm_file *file_priv) 467 1.1 riastrad { 468 1.1 riastrad struct drm_mode_get_property *out_resp = data; 469 1.1 riastrad struct drm_property *property; 470 1.1 riastrad int enum_count = 0; 471 1.1 riastrad int value_count = 0; 472 1.1 riastrad int i, copied; 473 1.1 riastrad struct drm_property_enum *prop_enum; 474 1.1 riastrad struct drm_mode_property_enum __user *enum_ptr; 475 1.1 riastrad uint64_t __user *values_ptr; 476 1.1 riastrad 477 1.1 riastrad if (!drm_core_check_feature(dev, DRIVER_MODESET)) 478 1.1 riastrad return -EOPNOTSUPP; 479 1.1 riastrad 480 1.1 riastrad property = drm_property_find(dev, file_priv, out_resp->prop_id); 481 1.1 riastrad if (!property) 482 1.1 riastrad return -ENOENT; 483 1.1 riastrad 484 1.1 riastrad strncpy(out_resp->name, property->name, DRM_PROP_NAME_LEN); 485 1.1 riastrad out_resp->name[DRM_PROP_NAME_LEN-1] = 0; 486 1.1 riastrad out_resp->flags = property->flags; 487 1.1 riastrad 488 1.1 riastrad value_count = property->num_values; 489 1.1 riastrad values_ptr = u64_to_user_ptr(out_resp->values_ptr); 490 1.1 riastrad 491 1.1 riastrad for (i = 0; i < value_count; i++) { 492 1.1 riastrad if (i < out_resp->count_values && 493 1.1 riastrad put_user(property->values[i], values_ptr + i)) { 494 1.1 riastrad return -EFAULT; 495 1.1 riastrad } 496 1.1 riastrad } 497 1.1 riastrad out_resp->count_values = value_count; 498 1.1 riastrad 499 1.1 riastrad copied = 0; 500 1.1 riastrad enum_ptr = u64_to_user_ptr(out_resp->enum_blob_ptr); 501 1.1 riastrad 502 1.1 riastrad if (drm_property_type_is(property, DRM_MODE_PROP_ENUM) || 503 1.1 riastrad drm_property_type_is(property, DRM_MODE_PROP_BITMASK)) { 504 1.1 riastrad list_for_each_entry(prop_enum, &property->enum_list, head) { 505 1.1 riastrad enum_count++; 506 1.1 riastrad if (out_resp->count_enum_blobs < enum_count) 507 1.1 riastrad continue; 508 1.1 riastrad 509 1.1 riastrad if (copy_to_user(&enum_ptr[copied].value, 510 1.1 riastrad &prop_enum->value, sizeof(uint64_t))) 511 1.1 riastrad return -EFAULT; 512 1.1 riastrad 513 1.1 riastrad if (copy_to_user(&enum_ptr[copied].name, 514 1.1 riastrad &prop_enum->name, DRM_PROP_NAME_LEN)) 515 1.1 riastrad return -EFAULT; 516 1.1 riastrad copied++; 517 1.1 riastrad } 518 1.1 riastrad out_resp->count_enum_blobs = enum_count; 519 1.1 riastrad } 520 1.1 riastrad 521 1.1 riastrad /* 522 1.1 riastrad * NOTE: The idea seems to have been to use this to read all the blob 523 1.1 riastrad * property values. But nothing ever added them to the corresponding 524 1.1 riastrad * list, userspace always used the special-purpose get_blob ioctl to 525 1.1 riastrad * read the value for a blob property. It also doesn't make a lot of 526 1.1 riastrad * sense to return values here when everything else is just metadata for 527 1.1 riastrad * the property itself. 528 1.1 riastrad */ 529 1.1 riastrad if (drm_property_type_is(property, DRM_MODE_PROP_BLOB)) 530 1.1 riastrad out_resp->count_enum_blobs = 0; 531 1.1 riastrad 532 1.1 riastrad return 0; 533 1.1 riastrad } 534 1.1 riastrad 535 1.1 riastrad static void drm_property_free_blob(struct kref *kref) 536 1.1 riastrad { 537 1.1 riastrad struct drm_property_blob *blob = 538 1.1 riastrad container_of(kref, struct drm_property_blob, base.refcount); 539 1.1 riastrad 540 1.1 riastrad mutex_lock(&blob->dev->mode_config.blob_lock); 541 1.1 riastrad list_del(&blob->head_global); 542 1.1 riastrad mutex_unlock(&blob->dev->mode_config.blob_lock); 543 1.1 riastrad 544 1.1 riastrad drm_mode_object_unregister(blob->dev, &blob->base); 545 1.1 riastrad 546 1.1 riastrad kvfree(blob); 547 1.1 riastrad } 548 1.1 riastrad 549 1.1 riastrad /** 550 1.1 riastrad * drm_property_create_blob - Create new blob property 551 1.1 riastrad * @dev: DRM device to create property for 552 1.1 riastrad * @length: Length to allocate for blob data 553 1.1 riastrad * @data: If specified, copies data into blob 554 1.1 riastrad * 555 1.1 riastrad * Creates a new blob property for a specified DRM device, optionally 556 1.1 riastrad * copying data. Note that blob properties are meant to be invariant, hence the 557 1.1 riastrad * data must be filled out before the blob is used as the value of any property. 558 1.1 riastrad * 559 1.1 riastrad * Returns: 560 1.1 riastrad * New blob property with a single reference on success, or an ERR_PTR 561 1.1 riastrad * value on failure. 562 1.1 riastrad */ 563 1.1 riastrad struct drm_property_blob * 564 1.1 riastrad drm_property_create_blob(struct drm_device *dev, size_t length, 565 1.1 riastrad const void *data) 566 1.1 riastrad { 567 1.1 riastrad struct drm_property_blob *blob; 568 1.1 riastrad int ret; 569 1.1 riastrad 570 1.1 riastrad if (!length || length > INT_MAX - sizeof(struct drm_property_blob)) 571 1.1 riastrad return ERR_PTR(-EINVAL); 572 1.1 riastrad 573 1.1 riastrad blob = kvzalloc(sizeof(struct drm_property_blob)+length, GFP_KERNEL); 574 1.1 riastrad if (!blob) 575 1.1 riastrad return ERR_PTR(-ENOMEM); 576 1.1 riastrad 577 1.1 riastrad /* This must be explicitly initialised, so we can safely call list_del 578 1.1 riastrad * on it in the removal handler, even if it isn't in a file list. */ 579 1.1 riastrad INIT_LIST_HEAD(&blob->head_file); 580 1.3 riastrad blob->data = (char *)blob + sizeof(*blob); 581 1.1 riastrad blob->length = length; 582 1.1 riastrad blob->dev = dev; 583 1.1 riastrad 584 1.1 riastrad if (data) 585 1.1 riastrad memcpy(blob->data, data, length); 586 1.1 riastrad 587 1.1 riastrad ret = __drm_mode_object_add(dev, &blob->base, DRM_MODE_OBJECT_BLOB, 588 1.1 riastrad true, drm_property_free_blob); 589 1.1 riastrad if (ret) { 590 1.1 riastrad kvfree(blob); 591 1.1 riastrad return ERR_PTR(-EINVAL); 592 1.1 riastrad } 593 1.1 riastrad 594 1.1 riastrad mutex_lock(&dev->mode_config.blob_lock); 595 1.1 riastrad list_add_tail(&blob->head_global, 596 1.1 riastrad &dev->mode_config.property_blob_list); 597 1.1 riastrad mutex_unlock(&dev->mode_config.blob_lock); 598 1.1 riastrad 599 1.1 riastrad return blob; 600 1.1 riastrad } 601 1.1 riastrad EXPORT_SYMBOL(drm_property_create_blob); 602 1.1 riastrad 603 1.1 riastrad /** 604 1.1 riastrad * drm_property_blob_put - release a blob property reference 605 1.1 riastrad * @blob: DRM blob property 606 1.1 riastrad * 607 1.1 riastrad * Releases a reference to a blob property. May free the object. 608 1.1 riastrad */ 609 1.1 riastrad void drm_property_blob_put(struct drm_property_blob *blob) 610 1.1 riastrad { 611 1.1 riastrad if (!blob) 612 1.1 riastrad return; 613 1.1 riastrad 614 1.1 riastrad drm_mode_object_put(&blob->base); 615 1.1 riastrad } 616 1.1 riastrad EXPORT_SYMBOL(drm_property_blob_put); 617 1.1 riastrad 618 1.1 riastrad void drm_property_destroy_user_blobs(struct drm_device *dev, 619 1.1 riastrad struct drm_file *file_priv) 620 1.1 riastrad { 621 1.1 riastrad struct drm_property_blob *blob, *bt; 622 1.1 riastrad 623 1.1 riastrad /* 624 1.1 riastrad * When the file gets released that means no one else can access the 625 1.1 riastrad * blob list any more, so no need to grab dev->blob_lock. 626 1.1 riastrad */ 627 1.1 riastrad list_for_each_entry_safe(blob, bt, &file_priv->blobs, head_file) { 628 1.1 riastrad list_del_init(&blob->head_file); 629 1.1 riastrad drm_property_blob_put(blob); 630 1.1 riastrad } 631 1.1 riastrad } 632 1.1 riastrad 633 1.1 riastrad /** 634 1.1 riastrad * drm_property_blob_get - acquire blob property reference 635 1.1 riastrad * @blob: DRM blob property 636 1.1 riastrad * 637 1.1 riastrad * Acquires a reference to an existing blob property. Returns @blob, which 638 1.1 riastrad * allows this to be used as a shorthand in assignments. 639 1.1 riastrad */ 640 1.1 riastrad struct drm_property_blob *drm_property_blob_get(struct drm_property_blob *blob) 641 1.1 riastrad { 642 1.1 riastrad drm_mode_object_get(&blob->base); 643 1.1 riastrad return blob; 644 1.1 riastrad } 645 1.1 riastrad EXPORT_SYMBOL(drm_property_blob_get); 646 1.1 riastrad 647 1.1 riastrad /** 648 1.1 riastrad * drm_property_lookup_blob - look up a blob property and take a reference 649 1.1 riastrad * @dev: drm device 650 1.1 riastrad * @id: id of the blob property 651 1.1 riastrad * 652 1.1 riastrad * If successful, this takes an additional reference to the blob property. 653 1.1 riastrad * callers need to make sure to eventually unreference the returned property 654 1.1 riastrad * again, using drm_property_blob_put(). 655 1.1 riastrad * 656 1.1 riastrad * Return: 657 1.1 riastrad * NULL on failure, pointer to the blob on success. 658 1.1 riastrad */ 659 1.1 riastrad struct drm_property_blob *drm_property_lookup_blob(struct drm_device *dev, 660 1.1 riastrad uint32_t id) 661 1.1 riastrad { 662 1.1 riastrad struct drm_mode_object *obj; 663 1.1 riastrad struct drm_property_blob *blob = NULL; 664 1.1 riastrad 665 1.1 riastrad obj = __drm_mode_object_find(dev, NULL, id, DRM_MODE_OBJECT_BLOB); 666 1.1 riastrad if (obj) 667 1.1 riastrad blob = obj_to_blob(obj); 668 1.1 riastrad return blob; 669 1.1 riastrad } 670 1.1 riastrad EXPORT_SYMBOL(drm_property_lookup_blob); 671 1.1 riastrad 672 1.1 riastrad /** 673 1.1 riastrad * drm_property_replace_global_blob - replace existing blob property 674 1.1 riastrad * @dev: drm device 675 1.1 riastrad * @replace: location of blob property pointer to be replaced 676 1.1 riastrad * @length: length of data for new blob, or 0 for no data 677 1.1 riastrad * @data: content for new blob, or NULL for no data 678 1.1 riastrad * @obj_holds_id: optional object for property holding blob ID 679 1.1 riastrad * @prop_holds_id: optional property holding blob ID 680 1.1 riastrad * @return 0 on success or error on failure 681 1.1 riastrad * 682 1.1 riastrad * This function will replace a global property in the blob list, optionally 683 1.1 riastrad * updating a property which holds the ID of that property. 684 1.1 riastrad * 685 1.1 riastrad * If length is 0 or data is NULL, no new blob will be created, and the holding 686 1.1 riastrad * property, if specified, will be set to 0. 687 1.1 riastrad * 688 1.1 riastrad * Access to the replace pointer is assumed to be protected by the caller, e.g. 689 1.1 riastrad * by holding the relevant modesetting object lock for its parent. 690 1.1 riastrad * 691 1.1 riastrad * For example, a drm_connector has a 'PATH' property, which contains the ID 692 1.1 riastrad * of a blob property with the value of the MST path information. Calling this 693 1.1 riastrad * function with replace pointing to the connector's path_blob_ptr, length and 694 1.1 riastrad * data set for the new path information, obj_holds_id set to the connector's 695 1.1 riastrad * base object, and prop_holds_id set to the path property name, will perform 696 1.1 riastrad * a completely atomic update. The access to path_blob_ptr is protected by the 697 1.1 riastrad * caller holding a lock on the connector. 698 1.1 riastrad */ 699 1.1 riastrad int drm_property_replace_global_blob(struct drm_device *dev, 700 1.1 riastrad struct drm_property_blob **replace, 701 1.1 riastrad size_t length, 702 1.1 riastrad const void *data, 703 1.1 riastrad struct drm_mode_object *obj_holds_id, 704 1.1 riastrad struct drm_property *prop_holds_id) 705 1.1 riastrad { 706 1.1 riastrad struct drm_property_blob *new_blob = NULL; 707 1.1 riastrad struct drm_property_blob *old_blob = NULL; 708 1.1 riastrad int ret; 709 1.1 riastrad 710 1.1 riastrad WARN_ON(replace == NULL); 711 1.1 riastrad 712 1.1 riastrad old_blob = *replace; 713 1.1 riastrad 714 1.1 riastrad if (length && data) { 715 1.1 riastrad new_blob = drm_property_create_blob(dev, length, data); 716 1.1 riastrad if (IS_ERR(new_blob)) 717 1.1 riastrad return PTR_ERR(new_blob); 718 1.1 riastrad } 719 1.1 riastrad 720 1.1 riastrad if (obj_holds_id) { 721 1.1 riastrad ret = drm_object_property_set_value(obj_holds_id, 722 1.1 riastrad prop_holds_id, 723 1.1 riastrad new_blob ? 724 1.1 riastrad new_blob->base.id : 0); 725 1.1 riastrad if (ret != 0) 726 1.1 riastrad goto err_created; 727 1.1 riastrad } 728 1.1 riastrad 729 1.1 riastrad drm_property_blob_put(old_blob); 730 1.1 riastrad *replace = new_blob; 731 1.1 riastrad 732 1.1 riastrad return 0; 733 1.1 riastrad 734 1.1 riastrad err_created: 735 1.1 riastrad drm_property_blob_put(new_blob); 736 1.1 riastrad return ret; 737 1.1 riastrad } 738 1.1 riastrad EXPORT_SYMBOL(drm_property_replace_global_blob); 739 1.1 riastrad 740 1.1 riastrad /** 741 1.1 riastrad * drm_property_replace_blob - replace a blob property 742 1.1 riastrad * @blob: a pointer to the member blob to be replaced 743 1.1 riastrad * @new_blob: the new blob to replace with 744 1.1 riastrad * 745 1.1 riastrad * Return: true if the blob was in fact replaced. 746 1.1 riastrad */ 747 1.1 riastrad bool drm_property_replace_blob(struct drm_property_blob **blob, 748 1.1 riastrad struct drm_property_blob *new_blob) 749 1.1 riastrad { 750 1.1 riastrad struct drm_property_blob *old_blob = *blob; 751 1.1 riastrad 752 1.1 riastrad if (old_blob == new_blob) 753 1.1 riastrad return false; 754 1.1 riastrad 755 1.1 riastrad drm_property_blob_put(old_blob); 756 1.1 riastrad if (new_blob) 757 1.1 riastrad drm_property_blob_get(new_blob); 758 1.1 riastrad *blob = new_blob; 759 1.1 riastrad return true; 760 1.1 riastrad } 761 1.1 riastrad EXPORT_SYMBOL(drm_property_replace_blob); 762 1.1 riastrad 763 1.1 riastrad int drm_mode_getblob_ioctl(struct drm_device *dev, 764 1.1 riastrad void *data, struct drm_file *file_priv) 765 1.1 riastrad { 766 1.1 riastrad struct drm_mode_get_blob *out_resp = data; 767 1.1 riastrad struct drm_property_blob *blob; 768 1.1 riastrad int ret = 0; 769 1.1 riastrad 770 1.1 riastrad if (!drm_core_check_feature(dev, DRIVER_MODESET)) 771 1.1 riastrad return -EOPNOTSUPP; 772 1.1 riastrad 773 1.1 riastrad blob = drm_property_lookup_blob(dev, out_resp->blob_id); 774 1.1 riastrad if (!blob) 775 1.1 riastrad return -ENOENT; 776 1.1 riastrad 777 1.1 riastrad if (out_resp->length == blob->length) { 778 1.1 riastrad if (copy_to_user(u64_to_user_ptr(out_resp->data), 779 1.1 riastrad blob->data, 780 1.1 riastrad blob->length)) { 781 1.1 riastrad ret = -EFAULT; 782 1.1 riastrad goto unref; 783 1.1 riastrad } 784 1.1 riastrad } 785 1.1 riastrad out_resp->length = blob->length; 786 1.1 riastrad unref: 787 1.1 riastrad drm_property_blob_put(blob); 788 1.1 riastrad 789 1.1 riastrad return ret; 790 1.1 riastrad } 791 1.1 riastrad 792 1.1 riastrad int drm_mode_createblob_ioctl(struct drm_device *dev, 793 1.1 riastrad void *data, struct drm_file *file_priv) 794 1.1 riastrad { 795 1.1 riastrad struct drm_mode_create_blob *out_resp = data; 796 1.1 riastrad struct drm_property_blob *blob; 797 1.1 riastrad int ret = 0; 798 1.1 riastrad 799 1.1 riastrad if (!drm_core_check_feature(dev, DRIVER_MODESET)) 800 1.1 riastrad return -EOPNOTSUPP; 801 1.1 riastrad 802 1.1 riastrad blob = drm_property_create_blob(dev, out_resp->length, NULL); 803 1.1 riastrad if (IS_ERR(blob)) 804 1.1 riastrad return PTR_ERR(blob); 805 1.1 riastrad 806 1.1 riastrad if (copy_from_user(blob->data, 807 1.1 riastrad u64_to_user_ptr(out_resp->data), 808 1.1 riastrad out_resp->length)) { 809 1.1 riastrad ret = -EFAULT; 810 1.1 riastrad goto out_blob; 811 1.1 riastrad } 812 1.1 riastrad 813 1.1 riastrad /* Dropping the lock between create_blob and our access here is safe 814 1.1 riastrad * as only the same file_priv can remove the blob; at this point, it is 815 1.1 riastrad * not associated with any file_priv. */ 816 1.1 riastrad mutex_lock(&dev->mode_config.blob_lock); 817 1.1 riastrad out_resp->blob_id = blob->base.id; 818 1.1 riastrad list_add_tail(&blob->head_file, &file_priv->blobs); 819 1.1 riastrad mutex_unlock(&dev->mode_config.blob_lock); 820 1.1 riastrad 821 1.1 riastrad return 0; 822 1.1 riastrad 823 1.1 riastrad out_blob: 824 1.1 riastrad drm_property_blob_put(blob); 825 1.1 riastrad return ret; 826 1.1 riastrad } 827 1.1 riastrad 828 1.1 riastrad int drm_mode_destroyblob_ioctl(struct drm_device *dev, 829 1.1 riastrad void *data, struct drm_file *file_priv) 830 1.1 riastrad { 831 1.1 riastrad struct drm_mode_destroy_blob *out_resp = data; 832 1.1 riastrad struct drm_property_blob *blob = NULL, *bt; 833 1.1 riastrad bool found = false; 834 1.1 riastrad int ret = 0; 835 1.1 riastrad 836 1.1 riastrad if (!drm_core_check_feature(dev, DRIVER_MODESET)) 837 1.1 riastrad return -EOPNOTSUPP; 838 1.1 riastrad 839 1.1 riastrad blob = drm_property_lookup_blob(dev, out_resp->blob_id); 840 1.1 riastrad if (!blob) 841 1.1 riastrad return -ENOENT; 842 1.1 riastrad 843 1.1 riastrad mutex_lock(&dev->mode_config.blob_lock); 844 1.1 riastrad /* Ensure the property was actually created by this user. */ 845 1.1 riastrad list_for_each_entry(bt, &file_priv->blobs, head_file) { 846 1.1 riastrad if (bt == blob) { 847 1.1 riastrad found = true; 848 1.1 riastrad break; 849 1.1 riastrad } 850 1.1 riastrad } 851 1.1 riastrad 852 1.1 riastrad if (!found) { 853 1.1 riastrad ret = -EPERM; 854 1.1 riastrad goto err; 855 1.1 riastrad } 856 1.1 riastrad 857 1.1 riastrad /* We must drop head_file here, because we may not be the last 858 1.1 riastrad * reference on the blob. */ 859 1.1 riastrad list_del_init(&blob->head_file); 860 1.1 riastrad mutex_unlock(&dev->mode_config.blob_lock); 861 1.1 riastrad 862 1.1 riastrad /* One reference from lookup, and one from the filp. */ 863 1.1 riastrad drm_property_blob_put(blob); 864 1.1 riastrad drm_property_blob_put(blob); 865 1.1 riastrad 866 1.1 riastrad return 0; 867 1.1 riastrad 868 1.1 riastrad err: 869 1.1 riastrad mutex_unlock(&dev->mode_config.blob_lock); 870 1.1 riastrad drm_property_blob_put(blob); 871 1.1 riastrad 872 1.1 riastrad return ret; 873 1.1 riastrad } 874 1.1 riastrad 875 1.1 riastrad /* Some properties could refer to dynamic refcnt'd objects, or things that 876 1.1 riastrad * need special locking to handle lifetime issues (ie. to ensure the prop 877 1.1 riastrad * value doesn't become invalid part way through the property update due to 878 1.1 riastrad * race). The value returned by reference via 'obj' should be passed back 879 1.1 riastrad * to drm_property_change_valid_put() after the property is set (and the 880 1.1 riastrad * object to which the property is attached has a chance to take its own 881 1.1 riastrad * reference). 882 1.1 riastrad */ 883 1.1 riastrad bool drm_property_change_valid_get(struct drm_property *property, 884 1.1 riastrad uint64_t value, struct drm_mode_object **ref) 885 1.1 riastrad { 886 1.1 riastrad int i; 887 1.1 riastrad 888 1.1 riastrad if (property->flags & DRM_MODE_PROP_IMMUTABLE) 889 1.1 riastrad return false; 890 1.1 riastrad 891 1.1 riastrad *ref = NULL; 892 1.1 riastrad 893 1.1 riastrad if (drm_property_type_is(property, DRM_MODE_PROP_RANGE)) { 894 1.1 riastrad if (value < property->values[0] || value > property->values[1]) 895 1.1 riastrad return false; 896 1.1 riastrad return true; 897 1.1 riastrad } else if (drm_property_type_is(property, DRM_MODE_PROP_SIGNED_RANGE)) { 898 1.1 riastrad int64_t svalue = U642I64(value); 899 1.1 riastrad 900 1.1 riastrad if (svalue < U642I64(property->values[0]) || 901 1.1 riastrad svalue > U642I64(property->values[1])) 902 1.1 riastrad return false; 903 1.1 riastrad return true; 904 1.1 riastrad } else if (drm_property_type_is(property, DRM_MODE_PROP_BITMASK)) { 905 1.1 riastrad uint64_t valid_mask = 0; 906 1.1 riastrad 907 1.1 riastrad for (i = 0; i < property->num_values; i++) 908 1.1 riastrad valid_mask |= (1ULL << property->values[i]); 909 1.1 riastrad return !(value & ~valid_mask); 910 1.1 riastrad } else if (drm_property_type_is(property, DRM_MODE_PROP_BLOB)) { 911 1.1 riastrad struct drm_property_blob *blob; 912 1.1 riastrad 913 1.1 riastrad if (value == 0) 914 1.1 riastrad return true; 915 1.1 riastrad 916 1.1 riastrad blob = drm_property_lookup_blob(property->dev, value); 917 1.1 riastrad if (blob) { 918 1.1 riastrad *ref = &blob->base; 919 1.1 riastrad return true; 920 1.1 riastrad } else { 921 1.1 riastrad return false; 922 1.1 riastrad } 923 1.1 riastrad } else if (drm_property_type_is(property, DRM_MODE_PROP_OBJECT)) { 924 1.1 riastrad /* a zero value for an object property translates to null: */ 925 1.1 riastrad if (value == 0) 926 1.1 riastrad return true; 927 1.1 riastrad 928 1.1 riastrad *ref = __drm_mode_object_find(property->dev, NULL, value, 929 1.1 riastrad property->values[0]); 930 1.1 riastrad return *ref != NULL; 931 1.1 riastrad } 932 1.1 riastrad 933 1.1 riastrad for (i = 0; i < property->num_values; i++) 934 1.1 riastrad if (property->values[i] == value) 935 1.1 riastrad return true; 936 1.1 riastrad return false; 937 1.1 riastrad } 938 1.1 riastrad 939 1.1 riastrad void drm_property_change_valid_put(struct drm_property *property, 940 1.1 riastrad struct drm_mode_object *ref) 941 1.1 riastrad { 942 1.1 riastrad if (!ref) 943 1.1 riastrad return; 944 1.1 riastrad 945 1.1 riastrad if (drm_property_type_is(property, DRM_MODE_PROP_OBJECT)) { 946 1.1 riastrad drm_mode_object_put(ref); 947 1.1 riastrad } else if (drm_property_type_is(property, DRM_MODE_PROP_BLOB)) 948 1.1 riastrad drm_property_blob_put(obj_to_blob(ref)); 949 1.1 riastrad } 950