From: Daniel Vetter Date: Wed, 17 Dec 2014 19:24:02 +0000 (+0100) Subject: Merge branch 'topic/core-stuff' into topic/atomic-core X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=72a3697097b8dc92f5b8362598f5730a9986eb83;p=GitHub%2FLineageOS%2Fandroid_kernel_motorola_exynos9610.git Merge branch 'topic/core-stuff' into topic/atomic-core Backmerge my drm-misc branch because of conflicts. Just simple stuff but better to clear this out before I merge the other atomic patches. Conflicts: drivers/gpu/drm/drm_crtc.c drivers/gpu/drm/drm_edid.c Signed-off-by: Daniel Vetter --- 72a3697097b8dc92f5b8362598f5730a9986eb83 diff --cc drivers/gpu/drm/drm_crtc.c index 481bb2598b62,6700ebafef16..303c9918a2d5 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@@ -4197,17 -4132,11 +4192,19 @@@ int drm_mode_connector_update_edid_prop } EXPORT_SYMBOL(drm_mode_connector_update_edid_property); -static bool drm_property_change_is_valid(struct drm_property *property, - uint64_t value) +/* Some properties could refer to dynamic refcnt'd objects, or things that + * need special locking to handle lifetime issues (ie. to ensure the prop + * value doesn't become invalid part way through the property update due to + * race). The value returned by reference via 'obj' should be passed back + * to drm_property_change_valid_put() after the property is set (and the + * object to which the property is attached has a chance to take it's own + * reference). + */ +static bool drm_property_change_valid_get(struct drm_property *property, + uint64_t value, struct drm_mode_object **ref) { + int i; + if (property->flags & DRM_MODE_PROP_IMMUTABLE) return false; @@@ -4236,41 -4164,25 +4234,46 @@@ /* a zero value for an object property translates to null: */ if (value == 0) return true; - /* - * NOTE: use _object_find() directly to bypass restriction on - * looking up refcnt'd objects (ie. fb's). For a refcnt'd - * object this could race against object finalization, so it - * simply tells us that the object *was* valid. Which is good - * enough. - */ - obj = _object_find(property->dev, value, property->values[0]); - return obj != NULL; + + /* handle refcnt'd objects specially: */ + if (property->values[0] == DRM_MODE_OBJECT_FB) { + struct drm_framebuffer *fb; + fb = drm_framebuffer_lookup(property->dev, value); + if (fb) { + *ref = &fb->base; + return true; + } else { + return false; + } + } else { + return _object_find(property->dev, value, property->values[0]) != NULL; + } + } else { + int i; + for (i = 0; i < property->num_values; i++) + if (property->values[i] == value) + return true; + return false; } + + for (i = 0; i < property->num_values; i++) + if (property->values[i] == value) + return true; + return false; } +static void drm_property_change_valid_put(struct drm_property *property, + struct drm_mode_object *ref) +{ + if (!ref) + return; + + if (drm_property_type_is(property, DRM_MODE_PROP_OBJECT)) { + if (property->values[0] == DRM_MODE_OBJECT_FB) + drm_framebuffer_unreference(obj_to_fb(ref)); + } +} + /** * drm_mode_connector_property_set_ioctl - set the current value of a connector property * @dev: DRM device