diff options
Diffstat (limited to 'drivers/gpu/drm/drm_atomic.c')
-rw-r--r-- | drivers/gpu/drm/drm_atomic.c | 42 |
1 files changed, 36 insertions, 6 deletions
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 34b7d420e555..7d25c42f22db 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c | |||
@@ -391,8 +391,7 @@ int drm_atomic_set_mode_prop_for_crtc(struct drm_crtc_state *state, | |||
391 | if (blob) { | 391 | if (blob) { |
392 | if (blob->length != sizeof(struct drm_mode_modeinfo) || | 392 | if (blob->length != sizeof(struct drm_mode_modeinfo) || |
393 | drm_mode_convert_umode(state->crtc->dev, &state->mode, | 393 | drm_mode_convert_umode(state->crtc->dev, &state->mode, |
394 | (const struct drm_mode_modeinfo *) | 394 | blob->data)) |
395 | blob->data)) | ||
396 | return -EINVAL; | 395 | return -EINVAL; |
397 | 396 | ||
398 | state->mode_blob = drm_property_blob_get(blob); | 397 | state->mode_blob = drm_property_blob_get(blob); |
@@ -409,11 +408,36 @@ int drm_atomic_set_mode_prop_for_crtc(struct drm_crtc_state *state, | |||
409 | } | 408 | } |
410 | EXPORT_SYMBOL(drm_atomic_set_mode_prop_for_crtc); | 409 | EXPORT_SYMBOL(drm_atomic_set_mode_prop_for_crtc); |
411 | 410 | ||
411 | /** | ||
412 | * drm_atomic_replace_property_blob_from_id - lookup the new blob and replace the old one with it | ||
413 | * @dev: DRM device | ||
414 | * @blob: a pointer to the member blob to be replaced | ||
415 | * @blob_id: ID of the new blob | ||
416 | * @expected_size: total expected size of the blob data (in bytes) | ||
417 | * @expected_elem_size: expected element size of the blob data (in bytes) | ||
418 | * @replaced: did the blob get replaced? | ||
419 | * | ||
420 | * Replace @blob with another blob with the ID @blob_id. If @blob_id is zero | ||
421 | * @blob becomes NULL. | ||
422 | * | ||
423 | * If @expected_size is positive the new blob length is expected to be equal | ||
424 | * to @expected_size bytes. If @expected_elem_size is positive the new blob | ||
425 | * length is expected to be a multiple of @expected_elem_size bytes. Otherwise | ||
426 | * an error is returned. | ||
427 | * | ||
428 | * @replaced will indicate to the caller whether the blob was replaced or not. | ||
429 | * If the old and new blobs were in fact the same blob @replaced will be false | ||
430 | * otherwise it will be true. | ||
431 | * | ||
432 | * RETURNS: | ||
433 | * Zero on success, error code on failure. | ||
434 | */ | ||
412 | static int | 435 | static int |
413 | drm_atomic_replace_property_blob_from_id(struct drm_device *dev, | 436 | drm_atomic_replace_property_blob_from_id(struct drm_device *dev, |
414 | struct drm_property_blob **blob, | 437 | struct drm_property_blob **blob, |
415 | uint64_t blob_id, | 438 | uint64_t blob_id, |
416 | ssize_t expected_size, | 439 | ssize_t expected_size, |
440 | ssize_t expected_elem_size, | ||
417 | bool *replaced) | 441 | bool *replaced) |
418 | { | 442 | { |
419 | struct drm_property_blob *new_blob = NULL; | 443 | struct drm_property_blob *new_blob = NULL; |
@@ -423,7 +447,13 @@ drm_atomic_replace_property_blob_from_id(struct drm_device *dev, | |||
423 | if (new_blob == NULL) | 447 | if (new_blob == NULL) |
424 | return -EINVAL; | 448 | return -EINVAL; |
425 | 449 | ||
426 | if (expected_size > 0 && expected_size != new_blob->length) { | 450 | if (expected_size > 0 && |
451 | new_blob->length != expected_size) { | ||
452 | drm_property_blob_put(new_blob); | ||
453 | return -EINVAL; | ||
454 | } | ||
455 | if (expected_elem_size > 0 && | ||
456 | new_blob->length % expected_elem_size != 0) { | ||
427 | drm_property_blob_put(new_blob); | 457 | drm_property_blob_put(new_blob); |
428 | return -EINVAL; | 458 | return -EINVAL; |
429 | } | 459 | } |
@@ -471,7 +501,7 @@ int drm_atomic_crtc_set_property(struct drm_crtc *crtc, | |||
471 | ret = drm_atomic_replace_property_blob_from_id(dev, | 501 | ret = drm_atomic_replace_property_blob_from_id(dev, |
472 | &state->degamma_lut, | 502 | &state->degamma_lut, |
473 | val, | 503 | val, |
474 | -1, | 504 | -1, sizeof(struct drm_color_lut), |
475 | &replaced); | 505 | &replaced); |
476 | state->color_mgmt_changed |= replaced; | 506 | state->color_mgmt_changed |= replaced; |
477 | return ret; | 507 | return ret; |
@@ -479,7 +509,7 @@ int drm_atomic_crtc_set_property(struct drm_crtc *crtc, | |||
479 | ret = drm_atomic_replace_property_blob_from_id(dev, | 509 | ret = drm_atomic_replace_property_blob_from_id(dev, |
480 | &state->ctm, | 510 | &state->ctm, |
481 | val, | 511 | val, |
482 | sizeof(struct drm_color_ctm), | 512 | sizeof(struct drm_color_ctm), -1, |
483 | &replaced); | 513 | &replaced); |
484 | state->color_mgmt_changed |= replaced; | 514 | state->color_mgmt_changed |= replaced; |
485 | return ret; | 515 | return ret; |
@@ -487,7 +517,7 @@ int drm_atomic_crtc_set_property(struct drm_crtc *crtc, | |||
487 | ret = drm_atomic_replace_property_blob_from_id(dev, | 517 | ret = drm_atomic_replace_property_blob_from_id(dev, |
488 | &state->gamma_lut, | 518 | &state->gamma_lut, |
489 | val, | 519 | val, |
490 | -1, | 520 | -1, sizeof(struct drm_color_lut), |
491 | &replaced); | 521 | &replaced); |
492 | state->color_mgmt_changed |= replaced; | 522 | state->color_mgmt_changed |= replaced; |
493 | return ret; | 523 | return ret; |