diff mbox

[9/9] drm/doc: Polish docs for drm_property&drm_property_blob

Message ID 20160829082757.17913-9-daniel.vetter@ffwll.ch (mailing list archive)
State New, archived
Headers show

Commit Message

Daniel Vetter Aug. 29, 2016, 8:27 a.m. UTC
- remove kerneldoc for drm-internal functions
- drm_property_replace_global_blob isn't actually atomic, and doesn't
  need to be. Update docs&comments to match
- document all the types and try to link things a bit better
- nits all over

v2: Appease checkpatch in the moved code (Archit)

Reviewed-by: Archit Taneja <architt@codeaurora.org>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 Documentation/gpu/drm-kms.rst  |  88 +-----------------
 drivers/gpu/drm/drm_property.c | 153 ++++++++++++--------------------
 include/drm/drm_property.h     | 196 ++++++++++++++++++++++++++++++++++++++---
 3 files changed, 244 insertions(+), 193 deletions(-)

Comments

Archit Taneja Aug. 29, 2016, 1:14 p.m. UTC | #1
On 08/29/2016 01:57 PM, Daniel Vetter wrote:
> - remove kerneldoc for drm-internal functions
> - drm_property_replace_global_blob isn't actually atomic, and doesn't
>    need to be. Update docs&comments to match
> - document all the types and try to link things a bit better
> - nits all over
>

Reviewed-by: Archit Taneja <architt@codeaurora.org>

> v2: Appease checkpatch in the moved code (Archit)
>
> Reviewed-by: Archit Taneja <architt@codeaurora.org>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> ---
>   Documentation/gpu/drm-kms.rst  |  88 +-----------------
>   drivers/gpu/drm/drm_property.c | 153 ++++++++++++--------------------
>   include/drm/drm_property.h     | 196 ++++++++++++++++++++++++++++++++++++++---
>   3 files changed, 244 insertions(+), 193 deletions(-)
>
> diff --git a/Documentation/gpu/drm-kms.rst b/Documentation/gpu/drm-kms.rst
> index e07a2667ab61..f9a991bb87d4 100644
> --- a/Documentation/gpu/drm-kms.rst
> +++ b/Documentation/gpu/drm-kms.rst
> @@ -304,94 +304,12 @@ KMS Locking
>   KMS Properties
>   ==============
>
> -Drivers may need to expose additional parameters to applications than
> -those described in the previous sections. KMS supports attaching
> -properties to CRTCs, connectors and planes and offers a userspace API to
> -list, get and set the property values.
> -
> -Properties are identified by a name that uniquely defines the property
> -purpose, and store an associated value. For all property types except
> -blob properties the value is a 64-bit unsigned integer.
> -
> -KMS differentiates between properties and property instances. Drivers
> -first create properties and then create and associate individual
> -instances of those properties to objects. A property can be instantiated
> -multiple times and associated with different objects. Values are stored
> -in property instances, and all other property information are stored in
> -the property and shared between all instances of the property.
> -
> -Every property is created with a type that influences how the KMS core
> -handles the property. Supported property types are
> -
> -DRM_MODE_PROP_RANGE
> -    Range properties report their minimum and maximum admissible values.
> -    The KMS core verifies that values set by application fit in that
> -    range.
> -
> -DRM_MODE_PROP_ENUM
> -    Enumerated properties take a numerical value that ranges from 0 to
> -    the number of enumerated values defined by the property minus one,
> -    and associate a free-formed string name to each value. Applications
> -    can retrieve the list of defined value-name pairs and use the
> -    numerical value to get and set property instance values.
> -
> -DRM_MODE_PROP_BITMASK
> -    Bitmask properties are enumeration properties that additionally
> -    restrict all enumerated values to the 0..63 range. Bitmask property
> -    instance values combine one or more of the enumerated bits defined
> -    by the property.
> -
> -DRM_MODE_PROP_BLOB
> -    Blob properties store a binary blob without any format restriction.
> -    The binary blobs are created as KMS standalone objects, and blob
> -    property instance values store the ID of their associated blob
> -    object.
> -
> -    Blob properties are only used for the connector EDID property and
> -    cannot be created by drivers.
> -
> -To create a property drivers call one of the following functions
> -depending on the property type. All property creation functions take
> -property flags and name, as well as type-specific arguments.
> -
> --  struct drm_property \*drm_property_create_range(struct
> -   drm_device \*dev, int flags, const char \*name, uint64_t min,
> -   uint64_t max);
> -   Create a range property with the given minimum and maximum values.
> -
> --  struct drm_property \*drm_property_create_enum(struct drm_device
> -   \*dev, int flags, const char \*name, const struct
> -   drm_prop_enum_list \*props, int num_values);
> -   Create an enumerated property. The ``props`` argument points to an
> -   array of ``num_values`` value-name pairs.
> -
> --  struct drm_property \*drm_property_create_bitmask(struct
> -   drm_device \*dev, int flags, const char \*name, const struct
> -   drm_prop_enum_list \*props, int num_values);
> -   Create a bitmask property. The ``props`` argument points to an array
> -   of ``num_values`` value-name pairs.
> -
> -Properties can additionally be created as immutable, in which case they
> -will be read-only for applications but can be modified by the driver. To
> -create an immutable property drivers must set the
> -DRM_MODE_PROP_IMMUTABLE flag at property creation time.
> -
> -When no array of value-name pairs is readily available at property
> -creation time for enumerated or range properties, drivers can create the
> -property using the :c:func:`drm_property_create()` function and
> -manually add enumeration value-name pairs by calling the
> -:c:func:`drm_property_add_enum()` function. Care must be taken to
> -properly specify the property type through the ``flags`` argument.
> -
> -After creating properties drivers can attach property instances to CRTC,
> -connector and plane objects by calling the
> -:c:func:`drm_object_attach_property()`. The function takes a
> -pointer to the target object, a pointer to the previously created
> -property and an initial instance value.
> -
>   Property Types and Blob Property Support
>   ----------------------------------------
>
> +.. kernel-doc:: drivers/gpu/drm/drm_property.c
> +   :doc: overview
> +
>   .. kernel-doc:: include/drm/drm_property.h
>      :internal:
>
> diff --git a/drivers/gpu/drm/drm_property.c b/drivers/gpu/drm/drm_property.c
> index b5521f705b1c..4139afbcc267 100644
> --- a/drivers/gpu/drm/drm_property.c
> +++ b/drivers/gpu/drm/drm_property.c
> @@ -26,6 +26,30 @@
>
>   #include "drm_crtc_internal.h"
>
> +/**
> + * DOC: overview
> + *
> + * Properties as represented by &drm_property are used to extend the modeset
> + * interface exposed to userspace. For the atomic modeset IOCTL properties are
> + * even the only way to transport metadata about the desired new modeset
> + * configuration from userspace to the kernel. Properties have a well-defined
> + * value range, which is enforced by the drm core. See the documentation of the
> + * flags member of struct &drm_property for an overview of the different
> + * property types and ranges.
> + *
> + * Properties don't store the current value directly, but need to be
> + * instatiated by attaching them to a &drm_mode_object with
> + * drm_object_attach_property().
> + *
> + * Property values are only 64bit. To support bigger piles of data (like gamma
> + * tables, color correction matrizes or large structures) a property can instead
> + * point at a &drm_property_blob with that additional data
> + *
> + * Properties are defined by their symbolic name, userspace must keep a
> + * per-object mapping from those names to the property ID used in the atomic
> + * IOCTL and in the get/set property IOCTL.
> + */
> +
>   static bool drm_property_type_valid(struct drm_property *property)
>   {
>   	if (property->flags & DRM_MODE_PROP_EXTENDED_TYPE)
> @@ -42,11 +66,8 @@ static bool drm_property_type_valid(struct drm_property *property)
>    *
>    * This creates a new generic drm property which can then be attached to a drm
>    * object with drm_object_attach_property. The returned property object must be
> - * freed with drm_property_destroy.
> - *
> - * Note that the DRM core keeps a per-device list of properties and that, if
> - * drm_mode_config_cleanup() is called, it will destroy all properties created
> - * by the driver.
> + * freed with drm_property_destroy(), which is done automatically when calling
> + * drm_mode_config_cleanup().
>    *
>    * Returns:
>    * A pointer to the newly created property on success, NULL on failure.
> @@ -105,7 +126,8 @@ EXPORT_SYMBOL(drm_property_create);
>    *
>    * This creates a new generic drm property which can then be attached to a drm
>    * object with drm_object_attach_property. The returned property object must be
> - * freed with drm_property_destroy.
> + * freed with drm_property_destroy(), which is done automatically when calling
> + * drm_mode_config_cleanup().
>    *
>    * Userspace is only allowed to set one of the predefined values for enumeration
>    * properties.
> @@ -152,7 +174,8 @@ EXPORT_SYMBOL(drm_property_create_enum);
>    *
>    * This creates a new bitmask drm property which can then be attached to a drm
>    * object with drm_object_attach_property. The returned property object must be
> - * freed with drm_property_destroy.
> + * freed with drm_property_destroy(), which is done automatically when calling
> + * drm_mode_config_cleanup().
>    *
>    * Compared to plain enumeration properties userspace is allowed to set any
>    * or'ed together combination of the predefined property bitflag values
> @@ -223,7 +246,8 @@ static struct drm_property *property_create_range(struct drm_device *dev,
>    *
>    * This creates a new generic drm property which can then be attached to a drm
>    * object with drm_object_attach_property. The returned property object must be
> - * freed with drm_property_destroy.
> + * freed with drm_property_destroy(), which is done automatically when calling
> + * drm_mode_config_cleanup().
>    *
>    * Userspace is allowed to set any unsigned integer value in the (min, max)
>    * range inclusive.
> @@ -250,7 +274,8 @@ EXPORT_SYMBOL(drm_property_create_range);
>    *
>    * This creates a new generic drm property which can then be attached to a drm
>    * object with drm_object_attach_property. The returned property object must be
> - * freed with drm_property_destroy.
> + * freed with drm_property_destroy(), which is done automatically when calling
> + * drm_mode_config_cleanup().
>    *
>    * Userspace is allowed to set any signed integer value in the (min, max)
>    * range inclusive.
> @@ -276,7 +301,8 @@ EXPORT_SYMBOL(drm_property_create_signed_range);
>    *
>    * This creates a new generic drm property which can then be attached to a drm
>    * object with drm_object_attach_property. The returned property object must be
> - * freed with drm_property_destroy.
> + * freed with drm_property_destroy(), which is done automatically when calling
> + * drm_mode_config_cleanup().
>    *
>    * Userspace is only allowed to set this to any property value of the given
>    * @type. Only useful for atomic properties, which is enforced.
> @@ -285,7 +311,8 @@ EXPORT_SYMBOL(drm_property_create_signed_range);
>    * A pointer to the newly created property on success, NULL on failure.
>    */
>   struct drm_property *drm_property_create_object(struct drm_device *dev,
> -					 int flags, const char *name, uint32_t type)
> +						int flags, const char *name,
> +						uint32_t type)
>   {
>   	struct drm_property *property;
>
> @@ -312,7 +339,8 @@ EXPORT_SYMBOL(drm_property_create_object);
>    *
>    * This creates a new generic drm property which can then be attached to a drm
>    * object with drm_object_attach_property. The returned property object must be
> - * freed with drm_property_destroy.
> + * freed with drm_property_destroy(), which is done automatically when calling
> + * drm_mode_config_cleanup().
>    *
>    * This is implemented as a ranged property with only {0, 1} as valid values.
>    *
> @@ -320,7 +348,7 @@ EXPORT_SYMBOL(drm_property_create_object);
>    * A pointer to the newly created property on success, NULL on failure.
>    */
>   struct drm_property *drm_property_create_bool(struct drm_device *dev, int flags,
> -					 const char *name)
> +					      const char *name)
>   {
>   	return drm_property_create_range(dev, flags, name, 0, 1);
>   }
> @@ -407,22 +435,6 @@ void drm_property_destroy(struct drm_device *dev, struct drm_property *property)
>   }
>   EXPORT_SYMBOL(drm_property_destroy);
>
> -/**
> - * drm_mode_getproperty_ioctl - get the property metadata
> - * @dev: DRM device
> - * @data: ioctl data
> - * @file_priv: DRM file info
> - *
> - * This function retrieves the metadata for a given property, like the different
> - * possible values for an enum property or the limits for a range property.
> - *
> - * Blob properties are special
> - *
> - * Called by the user via ioctl.
> - *
> - * Returns:
> - * Zero on success, negative errno on failure.
> - */
>   int drm_mode_getproperty_ioctl(struct drm_device *dev,
>   			       void *data, struct drm_file *file_priv)
>   {
> @@ -523,14 +535,14 @@ static void drm_property_free_blob(struct kref *kref)
>
>   /**
>    * drm_property_create_blob - Create new blob property
> - *
> - * Creates a new blob property for a specified DRM device, optionally
> - * copying data.
> - *
>    * @dev: DRM device to create property for
>    * @length: Length to allocate for blob data
>    * @data: If specified, copies data into blob
>    *
> + * Creates a new blob property for a specified DRM device, optionally
> + * copying data. Note that blob properties are meant to be invariant, hence the
> + * data must be filled out before the blob is used as the value of any property.
> + *
>    * Returns:
>    * New blob property with a single reference on success, or an ERR_PTR
>    * value on failure.
> @@ -576,10 +588,9 @@ EXPORT_SYMBOL(drm_property_create_blob);
>
>   /**
>    * drm_property_unreference_blob - Unreference a blob property
> + * @blob: Pointer to blob property
>    *
>    * Drop a reference on a blob property. May free the object.
> - *
> - * @blob: Pointer to blob property
>    */
>   void drm_property_unreference_blob(struct drm_property_blob *blob)
>   {
> @@ -590,11 +601,6 @@ void drm_property_unreference_blob(struct drm_property_blob *blob)
>   }
>   EXPORT_SYMBOL(drm_property_unreference_blob);
>
> -/**
> - * drm_property_destroy_user_blobs - destroy all blobs created by this client
> - * @dev:       DRM device
> - * @file_priv: destroy all blobs owned by this file handle
> - */
>   void drm_property_destroy_user_blobs(struct drm_device *dev,
>   				     struct drm_file *file_priv)
>   {
> @@ -612,10 +618,10 @@ void drm_property_destroy_user_blobs(struct drm_device *dev,
>
>   /**
>    * drm_property_reference_blob - Take a reference on an existing property
> - *
> - * Take a new reference on an existing blob property.
> - *
>    * @blob: Pointer to blob property
> + *
> + * Take a new reference on an existing blob property. Returns @blob, which
> + * allows this to be used as a shorthand in assignments.
>    */
>   struct drm_property_blob *drm_property_reference_blob(struct drm_property_blob *blob)
>   {
> @@ -632,6 +638,9 @@ EXPORT_SYMBOL(drm_property_reference_blob);
>    * If successful, this takes an additional reference to the blob property.
>    * callers need to make sure to eventually unreference the returned property
>    * again, using @drm_property_unreference_blob.
> + *
> + * Return:
> + * NULL on failure, pointer to the blob on success.
>    */
>   struct drm_property_blob *drm_property_lookup_blob(struct drm_device *dev,
>   					           uint32_t id)
> @@ -647,7 +656,7 @@ struct drm_property_blob *drm_property_lookup_blob(struct drm_device *dev,
>   EXPORT_SYMBOL(drm_property_lookup_blob);
>
>   /**
> - * drm_property_replace_global_blob - atomically replace existing blob property
> + * drm_property_replace_global_blob - replace existing blob property
>    * @dev: drm device
>    * @replace: location of blob property pointer to be replaced
>    * @length: length of data for new blob, or 0 for no data
> @@ -656,11 +665,8 @@ EXPORT_SYMBOL(drm_property_lookup_blob);
>    * @prop_holds_id: optional property holding blob ID
>    * @return 0 on success or error on failure
>    *
> - * This function will atomically replace a global property in the blob list,
> - * optionally updating a property which holds the ID of that property. It is
> - * guaranteed to be atomic: no caller will be allowed to see intermediate
> - * results, and either the entire operation will succeed and clean up the
> - * previous property, or it will fail and the state will be unchanged.
> + * This function will replace a global property in the blob list, optionally
> + * updating a property which holds the ID of that property.
>    *
>    * If length is 0 or data is NULL, no new blob will be created, and the holding
>    * property, if specified, will be set to 0.
> @@ -697,11 +703,6 @@ int drm_property_replace_global_blob(struct drm_device *dev,
>   			return PTR_ERR(new_blob);
>   	}
>
> -	/* This does not need to be synchronised with blob_lock, as the
> -	 * get_properties ioctl locks all modesetting objects, and
> -	 * obj_holds_id must be locked before calling here, so we cannot
> -	 * have its value out of sync with the list membership modified
> -	 * below under blob_lock. */
>   	if (obj_holds_id) {
>   		ret = drm_object_property_set_value(obj_holds_id,
>   						    prop_holds_id,
> @@ -722,20 +723,6 @@ err_created:
>   }
>   EXPORT_SYMBOL(drm_property_replace_global_blob);
>
> -/**
> - * drm_mode_getblob_ioctl - get the contents of a blob property value
> - * @dev: DRM device
> - * @data: ioctl data
> - * @file_priv: DRM file info
> - *
> - * This function retrieves the contents of a blob property. The value stored in
> - * an object's blob property is just a normal modeset object id.
> - *
> - * Called by the user via ioctl.
> - *
> - * Returns:
> - * Zero on success, negative errno on failure.
> - */
>   int drm_mode_getblob_ioctl(struct drm_device *dev,
>   			   void *data, struct drm_file *file_priv)
>   {
> @@ -765,21 +752,6 @@ unref:
>   	return ret;
>   }
>
> -/**
> - * drm_mode_createblob_ioctl - create a new blob property
> - * @dev: DRM device
> - * @data: ioctl data
> - * @file_priv: DRM file info
> - *
> - * This function creates a new blob property with user-defined values. In order
> - * to give us sensible validation and checking when creating, rather than at
> - * every potential use, we also require a type to be provided upfront.
> - *
> - * Called by the user via ioctl.
> - *
> - * Returns:
> - * Zero on success, negative errno on failure.
> - */
>   int drm_mode_createblob_ioctl(struct drm_device *dev,
>   			      void *data, struct drm_file *file_priv)
>   {
> @@ -816,19 +788,6 @@ out_blob:
>   	return ret;
>   }
>
> -/**
> - * drm_mode_destroyblob_ioctl - destroy a user blob property
> - * @dev: DRM device
> - * @data: ioctl data
> - * @file_priv: DRM file info
> - *
> - * Destroy an existing user-defined blob property.
> - *
> - * Called by the user via ioctl.
> - *
> - * Returns:
> - * Zero on success, negative errno on failure.
> - */
>   int drm_mode_destroyblob_ioctl(struct drm_device *dev,
>   			       void *data, struct drm_file *file_priv)
>   {
> @@ -885,7 +844,7 @@ err:
>    * reference).
>    */
>   bool drm_property_change_valid_get(struct drm_property *property,
> -					 uint64_t value, struct drm_mode_object **ref)
> +				   uint64_t value, struct drm_mode_object **ref)
>   {
>   	int i;
>
> diff --git a/include/drm/drm_property.h b/include/drm/drm_property.h
> index ac40069358c7..30ab289be05d 100644
> --- a/include/drm/drm_property.h
> +++ b/include/drm/drm_property.h
> @@ -27,33 +27,192 @@
>   #include <linux/ctype.h>
>   #include <drm/drm_mode_object.h>
>
> -struct drm_property_blob {
> -	struct drm_mode_object base;
> -	struct drm_device *dev;
> -	struct list_head head_global;
> -	struct list_head head_file;
> -	size_t length;
> -	unsigned char data[];
> -};
> -
> +/**
> + * struct drm_property_enum - symbolic values for enumerations
> + * @value: numeric property value for this enum entry
> + * @head: list of enum values, linked to enum_list in &drm_property
> + * @name: symbolic name for the enum
> + *
> + * For enumeration and bitmask properties this structure stores the symbolic
> + * decoding for each value. This is used for example for the rotation property.
> + */
>   struct drm_property_enum {
>   	uint64_t value;
>   	struct list_head head;
>   	char name[DRM_PROP_NAME_LEN];
>   };
>
> +/**
> + * struct drm_property - modeset object property
> + *
> + * This structure represent a modeset object property. It combines both the name
> + * of the property with the set of permissible values. This means that when a
> + * driver wants to use a property with the same name on different objects, but
> + * with different value ranges, then it must create property for each one. An
> + * example would be rotation of &drm_plane, when e.g. the primary plane cannot
> + * be rotated. But if both the name and the value range match, then the same
> + * property structure can be instantiated multiple times for the same object.
> + * Userspace must be able to cope with this and cannot assume that the same
> + * symbolic property will have the same modeset object ID on all modeset
> + * objects.
> + *
> + * Properties are created by one of the special functions, as explained in
> + * detail in the @flags structure member.
> + *
> + * To actually expose a property it must be attached to each object using
> + * drm_object_attach_property(). Currently properties can only be attached to
> + * &drm_connector, &drm_crtc and &drm_plane.
> + *
> + * Properties are also used as the generic metadatatransport for the atomic
> + * IOCTL. Everything that was set directly in structures in the legacy modeset
> + * IOCTLs (like the plane source or destination windows, or e.g. the links to
> + * the CRTC) is exposed as a property with the DRM_MODE_PROP_ATOMIC flag set.
> + */
>   struct drm_property {
> +	/**
> +	 * @head: per-device list of properties, for cleanup.
> +	 */
>   	struct list_head head;
> +
> +	/**
> +	 * @base: base KMS object
> +	 */
>   	struct drm_mode_object base;
> +
> +	/**
> +	 * @flags:
> +	 *
> +	 * Property flags and type. A property needs to be one of the following
> +	 * types:
> +	 *
> +	 * DRM_MODE_PROP_RANGE
> +	 *     Range properties report their minimum and maximum admissible unsigned values.
> +	 *     The KMS core verifies that values set by application fit in that
> +	 *     range. The range is unsigned. Range properties are created using
> +	 *     drm_property_create_range().
> +	 *
> +	 * DRM_MODE_PROP_SIGNED_RANGE
> +	 *     Range properties report their minimum and maximum admissible unsigned values.
> +	 *     The KMS core verifies that values set by application fit in that
> +	 *     range. The range is signed. Range properties are created using
> +	 *     drm_property_create_signed_range().
> +	 *
> +	 * DRM_MODE_PROP_ENUM
> +	 *     Enumerated properties take a numerical value that ranges from 0 to
> +	 *     the number of enumerated values defined by the property minus one,
> +	 *     and associate a free-formed string name to each value. Applications
> +	 *     can retrieve the list of defined value-name pairs and use the
> +	 *     numerical value to get and set property instance values. Enum
> +	 *     properties are created using drm_property_create_enum().
> +	 *
> +	 * DRM_MODE_PROP_BITMASK
> +	 *     Bitmask properties are enumeration properties that additionally
> +	 *     restrict all enumerated values to the 0..63 range. Bitmask property
> +	 *     instance values combine one or more of the enumerated bits defined
> +	 *     by the property. Bitmask properties are created using
> +	 *     drm_property_create_bitmask().
> +	 *
> +	 * DRM_MODE_PROB_OBJECT
> +	 *     Object properties are used to link modeset objects. This is used
> +	 *     extensively in the atomic support to create the display pipeline,
> +	 *     by linking &drm_framebuffer to &drm_plane, &drm_plane to
> +	 *     &drm_crtc and &drm_connector to &drm_crtc. An object property can
> +	 *     only link to a specific type of &drm_mode_object, this limit is
> +	 *     enforced by the core. Object properties are created using
> +	 *     drm_property_create_object().
> +	 *
> +	 *     Object properties work like blob properties, but in a more
> +	 *     general fashion. They are limited to atomic drivers and must have
> +	 *     the DRM_MODE_PROP_ATOMIC flag set.
> +	 *
> +	 * DRM_MODE_PROP_BLOB
> +	 *     Blob properties store a binary blob without any format restriction.
> +	 *     The binary blobs are created as KMS standalone objects, and blob
> +	 *     property instance values store the ID of their associated blob
> +	 *     object. Blob properties are created by calling
> +	 *     drm_property_create() with DRM_MODE_PROP_BLOB as the type.
> +	 *
> +	 *     Actual blob objects to contain blob data are created using
> +	 *     drm_property_create_blob(), or through the corresponding IOCTL.
> +	 *
> +	 *     Besides the built-in limit to only accept blob objects blob
> +	 *     properties work exactly like object properties. The only reasons
> +	 *     blob properties exist is backwards compatibility with existing
> +	 *     userspace.
> +	 *
> +	 * In addition a property can have any combination of the below flags:
> +	 *
> +	 * DRM_MODE_PROP_ATOMIC
> +	 *     Set for properties which encode atomic modeset state. Such
> +	 *     properties are not exposed to legacy userspace.
> +	 *
> +	 * DRM_MODE_PROP_IMMUTABLE
> +	 *     Set for properties where userspace cannot be changed by
> +	 *     userspace. The kernel is allowed to update the value of these
> +	 *     properties. This is generally used to expose probe state to
> +	 *     usersapce, e.g. the EDID, or the connector path property on DP
> +	 *     MST sinks.
> +	 */
>   	uint32_t flags;
> +
> +	/**
> +	 * @name: symbolic name of the properties
> +	 */
>   	char name[DRM_PROP_NAME_LEN];
> +
> +	/**
> +	 * @num_values: size of the @values array.
> +	 */
>   	uint32_t num_values;
> +
> +	/**
> +	 * @values:
> +	 *
> +	 * Array with limits and values for the property. The
> +	 * interpretation of these limits is dependent upon the type per @flags.
> +	 */
>   	uint64_t *values;
> +
> +	/**
> +	 * @dev: DRM device
> +	 */
>   	struct drm_device *dev;
>
> +	/**
> +	 * @enum_list:
> +	 *
> +	 * List of &drm_prop_enum_list structures with the symbolic names for
> +	 * enum and bitmask values.
> +	 */
>   	struct list_head enum_list;
>   };
>
> +/**
> + * struct drm_property_blob - Blob data for &drm_property
> + * @base: base KMS object
> + * @dev: DRM device
> + * @head_global: entry on the global blob list in &drm_mode_config
> + *	property_blob_list.
> + * @head_file: entry on the per-file blob list in &drm_file blobs list.
> + * @length: size of the blob in bytes, invariant over the lifetime of the object
> + * @data: actual data, embedded at the end of this structure
> + *
> + * Blobs are used to store bigger values than what fits directly into the 64
> + * bits available for a &drm_property.
> + *
> + * Blobs are reference counted using drm_property_reference_blob() and
> + * drm_property_unreference_blob(). They are created using
> + * drm_property_create_blob().
> + */
> +struct drm_property_blob {
> +	struct drm_mode_object base;
> +	struct drm_device *dev;
> +	struct list_head head_global;
> +	struct list_head head_file;
> +	size_t length;
> +	unsigned char data[];
> +};
> +
>   struct drm_prop_enum_list {
>   	int type;
>   	char *name;
> @@ -61,8 +220,16 @@ struct drm_prop_enum_list {
>
>   #define obj_to_property(x) container_of(x, struct drm_property, base)
>
> +/**
> + * drm_property_type_is - check the type of a property
> + * @property: property to check
> + * @type: property type to compare with
> + *
> + * This is a helper function becauase the uapi encoding of property types is
> + * a bit special for historical reasons.
> + */
>   static inline bool drm_property_type_is(struct drm_property *property,
> -		uint32_t type)
> +					uint32_t type)
>   {
>   	/* instanceof for props.. handles extended type vs original types: */
>   	if (property->flags & DRM_MODE_PROP_EXTENDED_TYPE)
> @@ -109,8 +276,15 @@ int drm_property_replace_global_blob(struct drm_device *dev,
>   struct drm_property_blob *drm_property_reference_blob(struct drm_property_blob *blob);
>   void drm_property_unreference_blob(struct drm_property_blob *blob);
>
> +/**
> + * drm_connector_find - find property object
> + * @dev: DRM device
> + * @id: property object id
> + *
> + * This function looks up the property object specified by id and returns it.
> + */
>   static inline struct drm_property *drm_property_find(struct drm_device *dev,
> -		uint32_t id)
> +						     uint32_t id)
>   {
>   	struct drm_mode_object *mo;
>   	mo = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_PROPERTY);
>
Daniel Vetter Aug. 29, 2016, 2:04 p.m. UTC | #2
On Mon, Aug 29, 2016 at 06:44:46PM +0530, Archit Taneja wrote:
> 
> 
> On 08/29/2016 01:57 PM, Daniel Vetter wrote:
> > - remove kerneldoc for drm-internal functions
> > - drm_property_replace_global_blob isn't actually atomic, and doesn't
> >    need to be. Update docs&comments to match
> > - document all the types and try to link things a bit better
> > - nits all over
> > 
> 
> Reviewed-by: Archit Taneja <architt@codeaurora.org>

All applied to drm-misc, thanks for your review.
-Daniel

> 
> > v2: Appease checkpatch in the moved code (Archit)
> > 
> > Reviewed-by: Archit Taneja <architt@codeaurora.org>
> > Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> > ---
> >   Documentation/gpu/drm-kms.rst  |  88 +-----------------
> >   drivers/gpu/drm/drm_property.c | 153 ++++++++++++--------------------
> >   include/drm/drm_property.h     | 196 ++++++++++++++++++++++++++++++++++++++---
> >   3 files changed, 244 insertions(+), 193 deletions(-)
> > 
> > diff --git a/Documentation/gpu/drm-kms.rst b/Documentation/gpu/drm-kms.rst
> > index e07a2667ab61..f9a991bb87d4 100644
> > --- a/Documentation/gpu/drm-kms.rst
> > +++ b/Documentation/gpu/drm-kms.rst
> > @@ -304,94 +304,12 @@ KMS Locking
> >   KMS Properties
> >   ==============
> > 
> > -Drivers may need to expose additional parameters to applications than
> > -those described in the previous sections. KMS supports attaching
> > -properties to CRTCs, connectors and planes and offers a userspace API to
> > -list, get and set the property values.
> > -
> > -Properties are identified by a name that uniquely defines the property
> > -purpose, and store an associated value. For all property types except
> > -blob properties the value is a 64-bit unsigned integer.
> > -
> > -KMS differentiates between properties and property instances. Drivers
> > -first create properties and then create and associate individual
> > -instances of those properties to objects. A property can be instantiated
> > -multiple times and associated with different objects. Values are stored
> > -in property instances, and all other property information are stored in
> > -the property and shared between all instances of the property.
> > -
> > -Every property is created with a type that influences how the KMS core
> > -handles the property. Supported property types are
> > -
> > -DRM_MODE_PROP_RANGE
> > -    Range properties report their minimum and maximum admissible values.
> > -    The KMS core verifies that values set by application fit in that
> > -    range.
> > -
> > -DRM_MODE_PROP_ENUM
> > -    Enumerated properties take a numerical value that ranges from 0 to
> > -    the number of enumerated values defined by the property minus one,
> > -    and associate a free-formed string name to each value. Applications
> > -    can retrieve the list of defined value-name pairs and use the
> > -    numerical value to get and set property instance values.
> > -
> > -DRM_MODE_PROP_BITMASK
> > -    Bitmask properties are enumeration properties that additionally
> > -    restrict all enumerated values to the 0..63 range. Bitmask property
> > -    instance values combine one or more of the enumerated bits defined
> > -    by the property.
> > -
> > -DRM_MODE_PROP_BLOB
> > -    Blob properties store a binary blob without any format restriction.
> > -    The binary blobs are created as KMS standalone objects, and blob
> > -    property instance values store the ID of their associated blob
> > -    object.
> > -
> > -    Blob properties are only used for the connector EDID property and
> > -    cannot be created by drivers.
> > -
> > -To create a property drivers call one of the following functions
> > -depending on the property type. All property creation functions take
> > -property flags and name, as well as type-specific arguments.
> > -
> > --  struct drm_property \*drm_property_create_range(struct
> > -   drm_device \*dev, int flags, const char \*name, uint64_t min,
> > -   uint64_t max);
> > -   Create a range property with the given minimum and maximum values.
> > -
> > --  struct drm_property \*drm_property_create_enum(struct drm_device
> > -   \*dev, int flags, const char \*name, const struct
> > -   drm_prop_enum_list \*props, int num_values);
> > -   Create an enumerated property. The ``props`` argument points to an
> > -   array of ``num_values`` value-name pairs.
> > -
> > --  struct drm_property \*drm_property_create_bitmask(struct
> > -   drm_device \*dev, int flags, const char \*name, const struct
> > -   drm_prop_enum_list \*props, int num_values);
> > -   Create a bitmask property. The ``props`` argument points to an array
> > -   of ``num_values`` value-name pairs.
> > -
> > -Properties can additionally be created as immutable, in which case they
> > -will be read-only for applications but can be modified by the driver. To
> > -create an immutable property drivers must set the
> > -DRM_MODE_PROP_IMMUTABLE flag at property creation time.
> > -
> > -When no array of value-name pairs is readily available at property
> > -creation time for enumerated or range properties, drivers can create the
> > -property using the :c:func:`drm_property_create()` function and
> > -manually add enumeration value-name pairs by calling the
> > -:c:func:`drm_property_add_enum()` function. Care must be taken to
> > -properly specify the property type through the ``flags`` argument.
> > -
> > -After creating properties drivers can attach property instances to CRTC,
> > -connector and plane objects by calling the
> > -:c:func:`drm_object_attach_property()`. The function takes a
> > -pointer to the target object, a pointer to the previously created
> > -property and an initial instance value.
> > -
> >   Property Types and Blob Property Support
> >   ----------------------------------------
> > 
> > +.. kernel-doc:: drivers/gpu/drm/drm_property.c
> > +   :doc: overview
> > +
> >   .. kernel-doc:: include/drm/drm_property.h
> >      :internal:
> > 
> > diff --git a/drivers/gpu/drm/drm_property.c b/drivers/gpu/drm/drm_property.c
> > index b5521f705b1c..4139afbcc267 100644
> > --- a/drivers/gpu/drm/drm_property.c
> > +++ b/drivers/gpu/drm/drm_property.c
> > @@ -26,6 +26,30 @@
> > 
> >   #include "drm_crtc_internal.h"
> > 
> > +/**
> > + * DOC: overview
> > + *
> > + * Properties as represented by &drm_property are used to extend the modeset
> > + * interface exposed to userspace. For the atomic modeset IOCTL properties are
> > + * even the only way to transport metadata about the desired new modeset
> > + * configuration from userspace to the kernel. Properties have a well-defined
> > + * value range, which is enforced by the drm core. See the documentation of the
> > + * flags member of struct &drm_property for an overview of the different
> > + * property types and ranges.
> > + *
> > + * Properties don't store the current value directly, but need to be
> > + * instatiated by attaching them to a &drm_mode_object with
> > + * drm_object_attach_property().
> > + *
> > + * Property values are only 64bit. To support bigger piles of data (like gamma
> > + * tables, color correction matrizes or large structures) a property can instead
> > + * point at a &drm_property_blob with that additional data
> > + *
> > + * Properties are defined by their symbolic name, userspace must keep a
> > + * per-object mapping from those names to the property ID used in the atomic
> > + * IOCTL and in the get/set property IOCTL.
> > + */
> > +
> >   static bool drm_property_type_valid(struct drm_property *property)
> >   {
> >   	if (property->flags & DRM_MODE_PROP_EXTENDED_TYPE)
> > @@ -42,11 +66,8 @@ static bool drm_property_type_valid(struct drm_property *property)
> >    *
> >    * This creates a new generic drm property which can then be attached to a drm
> >    * object with drm_object_attach_property. The returned property object must be
> > - * freed with drm_property_destroy.
> > - *
> > - * Note that the DRM core keeps a per-device list of properties and that, if
> > - * drm_mode_config_cleanup() is called, it will destroy all properties created
> > - * by the driver.
> > + * freed with drm_property_destroy(), which is done automatically when calling
> > + * drm_mode_config_cleanup().
> >    *
> >    * Returns:
> >    * A pointer to the newly created property on success, NULL on failure.
> > @@ -105,7 +126,8 @@ EXPORT_SYMBOL(drm_property_create);
> >    *
> >    * This creates a new generic drm property which can then be attached to a drm
> >    * object with drm_object_attach_property. The returned property object must be
> > - * freed with drm_property_destroy.
> > + * freed with drm_property_destroy(), which is done automatically when calling
> > + * drm_mode_config_cleanup().
> >    *
> >    * Userspace is only allowed to set one of the predefined values for enumeration
> >    * properties.
> > @@ -152,7 +174,8 @@ EXPORT_SYMBOL(drm_property_create_enum);
> >    *
> >    * This creates a new bitmask drm property which can then be attached to a drm
> >    * object with drm_object_attach_property. The returned property object must be
> > - * freed with drm_property_destroy.
> > + * freed with drm_property_destroy(), which is done automatically when calling
> > + * drm_mode_config_cleanup().
> >    *
> >    * Compared to plain enumeration properties userspace is allowed to set any
> >    * or'ed together combination of the predefined property bitflag values
> > @@ -223,7 +246,8 @@ static struct drm_property *property_create_range(struct drm_device *dev,
> >    *
> >    * This creates a new generic drm property which can then be attached to a drm
> >    * object with drm_object_attach_property. The returned property object must be
> > - * freed with drm_property_destroy.
> > + * freed with drm_property_destroy(), which is done automatically when calling
> > + * drm_mode_config_cleanup().
> >    *
> >    * Userspace is allowed to set any unsigned integer value in the (min, max)
> >    * range inclusive.
> > @@ -250,7 +274,8 @@ EXPORT_SYMBOL(drm_property_create_range);
> >    *
> >    * This creates a new generic drm property which can then be attached to a drm
> >    * object with drm_object_attach_property. The returned property object must be
> > - * freed with drm_property_destroy.
> > + * freed with drm_property_destroy(), which is done automatically when calling
> > + * drm_mode_config_cleanup().
> >    *
> >    * Userspace is allowed to set any signed integer value in the (min, max)
> >    * range inclusive.
> > @@ -276,7 +301,8 @@ EXPORT_SYMBOL(drm_property_create_signed_range);
> >    *
> >    * This creates a new generic drm property which can then be attached to a drm
> >    * object with drm_object_attach_property. The returned property object must be
> > - * freed with drm_property_destroy.
> > + * freed with drm_property_destroy(), which is done automatically when calling
> > + * drm_mode_config_cleanup().
> >    *
> >    * Userspace is only allowed to set this to any property value of the given
> >    * @type. Only useful for atomic properties, which is enforced.
> > @@ -285,7 +311,8 @@ EXPORT_SYMBOL(drm_property_create_signed_range);
> >    * A pointer to the newly created property on success, NULL on failure.
> >    */
> >   struct drm_property *drm_property_create_object(struct drm_device *dev,
> > -					 int flags, const char *name, uint32_t type)
> > +						int flags, const char *name,
> > +						uint32_t type)
> >   {
> >   	struct drm_property *property;
> > 
> > @@ -312,7 +339,8 @@ EXPORT_SYMBOL(drm_property_create_object);
> >    *
> >    * This creates a new generic drm property which can then be attached to a drm
> >    * object with drm_object_attach_property. The returned property object must be
> > - * freed with drm_property_destroy.
> > + * freed with drm_property_destroy(), which is done automatically when calling
> > + * drm_mode_config_cleanup().
> >    *
> >    * This is implemented as a ranged property with only {0, 1} as valid values.
> >    *
> > @@ -320,7 +348,7 @@ EXPORT_SYMBOL(drm_property_create_object);
> >    * A pointer to the newly created property on success, NULL on failure.
> >    */
> >   struct drm_property *drm_property_create_bool(struct drm_device *dev, int flags,
> > -					 const char *name)
> > +					      const char *name)
> >   {
> >   	return drm_property_create_range(dev, flags, name, 0, 1);
> >   }
> > @@ -407,22 +435,6 @@ void drm_property_destroy(struct drm_device *dev, struct drm_property *property)
> >   }
> >   EXPORT_SYMBOL(drm_property_destroy);
> > 
> > -/**
> > - * drm_mode_getproperty_ioctl - get the property metadata
> > - * @dev: DRM device
> > - * @data: ioctl data
> > - * @file_priv: DRM file info
> > - *
> > - * This function retrieves the metadata for a given property, like the different
> > - * possible values for an enum property or the limits for a range property.
> > - *
> > - * Blob properties are special
> > - *
> > - * Called by the user via ioctl.
> > - *
> > - * Returns:
> > - * Zero on success, negative errno on failure.
> > - */
> >   int drm_mode_getproperty_ioctl(struct drm_device *dev,
> >   			       void *data, struct drm_file *file_priv)
> >   {
> > @@ -523,14 +535,14 @@ static void drm_property_free_blob(struct kref *kref)
> > 
> >   /**
> >    * drm_property_create_blob - Create new blob property
> > - *
> > - * Creates a new blob property for a specified DRM device, optionally
> > - * copying data.
> > - *
> >    * @dev: DRM device to create property for
> >    * @length: Length to allocate for blob data
> >    * @data: If specified, copies data into blob
> >    *
> > + * Creates a new blob property for a specified DRM device, optionally
> > + * copying data. Note that blob properties are meant to be invariant, hence the
> > + * data must be filled out before the blob is used as the value of any property.
> > + *
> >    * Returns:
> >    * New blob property with a single reference on success, or an ERR_PTR
> >    * value on failure.
> > @@ -576,10 +588,9 @@ EXPORT_SYMBOL(drm_property_create_blob);
> > 
> >   /**
> >    * drm_property_unreference_blob - Unreference a blob property
> > + * @blob: Pointer to blob property
> >    *
> >    * Drop a reference on a blob property. May free the object.
> > - *
> > - * @blob: Pointer to blob property
> >    */
> >   void drm_property_unreference_blob(struct drm_property_blob *blob)
> >   {
> > @@ -590,11 +601,6 @@ void drm_property_unreference_blob(struct drm_property_blob *blob)
> >   }
> >   EXPORT_SYMBOL(drm_property_unreference_blob);
> > 
> > -/**
> > - * drm_property_destroy_user_blobs - destroy all blobs created by this client
> > - * @dev:       DRM device
> > - * @file_priv: destroy all blobs owned by this file handle
> > - */
> >   void drm_property_destroy_user_blobs(struct drm_device *dev,
> >   				     struct drm_file *file_priv)
> >   {
> > @@ -612,10 +618,10 @@ void drm_property_destroy_user_blobs(struct drm_device *dev,
> > 
> >   /**
> >    * drm_property_reference_blob - Take a reference on an existing property
> > - *
> > - * Take a new reference on an existing blob property.
> > - *
> >    * @blob: Pointer to blob property
> > + *
> > + * Take a new reference on an existing blob property. Returns @blob, which
> > + * allows this to be used as a shorthand in assignments.
> >    */
> >   struct drm_property_blob *drm_property_reference_blob(struct drm_property_blob *blob)
> >   {
> > @@ -632,6 +638,9 @@ EXPORT_SYMBOL(drm_property_reference_blob);
> >    * If successful, this takes an additional reference to the blob property.
> >    * callers need to make sure to eventually unreference the returned property
> >    * again, using @drm_property_unreference_blob.
> > + *
> > + * Return:
> > + * NULL on failure, pointer to the blob on success.
> >    */
> >   struct drm_property_blob *drm_property_lookup_blob(struct drm_device *dev,
> >   					           uint32_t id)
> > @@ -647,7 +656,7 @@ struct drm_property_blob *drm_property_lookup_blob(struct drm_device *dev,
> >   EXPORT_SYMBOL(drm_property_lookup_blob);
> > 
> >   /**
> > - * drm_property_replace_global_blob - atomically replace existing blob property
> > + * drm_property_replace_global_blob - replace existing blob property
> >    * @dev: drm device
> >    * @replace: location of blob property pointer to be replaced
> >    * @length: length of data for new blob, or 0 for no data
> > @@ -656,11 +665,8 @@ EXPORT_SYMBOL(drm_property_lookup_blob);
> >    * @prop_holds_id: optional property holding blob ID
> >    * @return 0 on success or error on failure
> >    *
> > - * This function will atomically replace a global property in the blob list,
> > - * optionally updating a property which holds the ID of that property. It is
> > - * guaranteed to be atomic: no caller will be allowed to see intermediate
> > - * results, and either the entire operation will succeed and clean up the
> > - * previous property, or it will fail and the state will be unchanged.
> > + * This function will replace a global property in the blob list, optionally
> > + * updating a property which holds the ID of that property.
> >    *
> >    * If length is 0 or data is NULL, no new blob will be created, and the holding
> >    * property, if specified, will be set to 0.
> > @@ -697,11 +703,6 @@ int drm_property_replace_global_blob(struct drm_device *dev,
> >   			return PTR_ERR(new_blob);
> >   	}
> > 
> > -	/* This does not need to be synchronised with blob_lock, as the
> > -	 * get_properties ioctl locks all modesetting objects, and
> > -	 * obj_holds_id must be locked before calling here, so we cannot
> > -	 * have its value out of sync with the list membership modified
> > -	 * below under blob_lock. */
> >   	if (obj_holds_id) {
> >   		ret = drm_object_property_set_value(obj_holds_id,
> >   						    prop_holds_id,
> > @@ -722,20 +723,6 @@ err_created:
> >   }
> >   EXPORT_SYMBOL(drm_property_replace_global_blob);
> > 
> > -/**
> > - * drm_mode_getblob_ioctl - get the contents of a blob property value
> > - * @dev: DRM device
> > - * @data: ioctl data
> > - * @file_priv: DRM file info
> > - *
> > - * This function retrieves the contents of a blob property. The value stored in
> > - * an object's blob property is just a normal modeset object id.
> > - *
> > - * Called by the user via ioctl.
> > - *
> > - * Returns:
> > - * Zero on success, negative errno on failure.
> > - */
> >   int drm_mode_getblob_ioctl(struct drm_device *dev,
> >   			   void *data, struct drm_file *file_priv)
> >   {
> > @@ -765,21 +752,6 @@ unref:
> >   	return ret;
> >   }
> > 
> > -/**
> > - * drm_mode_createblob_ioctl - create a new blob property
> > - * @dev: DRM device
> > - * @data: ioctl data
> > - * @file_priv: DRM file info
> > - *
> > - * This function creates a new blob property with user-defined values. In order
> > - * to give us sensible validation and checking when creating, rather than at
> > - * every potential use, we also require a type to be provided upfront.
> > - *
> > - * Called by the user via ioctl.
> > - *
> > - * Returns:
> > - * Zero on success, negative errno on failure.
> > - */
> >   int drm_mode_createblob_ioctl(struct drm_device *dev,
> >   			      void *data, struct drm_file *file_priv)
> >   {
> > @@ -816,19 +788,6 @@ out_blob:
> >   	return ret;
> >   }
> > 
> > -/**
> > - * drm_mode_destroyblob_ioctl - destroy a user blob property
> > - * @dev: DRM device
> > - * @data: ioctl data
> > - * @file_priv: DRM file info
> > - *
> > - * Destroy an existing user-defined blob property.
> > - *
> > - * Called by the user via ioctl.
> > - *
> > - * Returns:
> > - * Zero on success, negative errno on failure.
> > - */
> >   int drm_mode_destroyblob_ioctl(struct drm_device *dev,
> >   			       void *data, struct drm_file *file_priv)
> >   {
> > @@ -885,7 +844,7 @@ err:
> >    * reference).
> >    */
> >   bool drm_property_change_valid_get(struct drm_property *property,
> > -					 uint64_t value, struct drm_mode_object **ref)
> > +				   uint64_t value, struct drm_mode_object **ref)
> >   {
> >   	int i;
> > 
> > diff --git a/include/drm/drm_property.h b/include/drm/drm_property.h
> > index ac40069358c7..30ab289be05d 100644
> > --- a/include/drm/drm_property.h
> > +++ b/include/drm/drm_property.h
> > @@ -27,33 +27,192 @@
> >   #include <linux/ctype.h>
> >   #include <drm/drm_mode_object.h>
> > 
> > -struct drm_property_blob {
> > -	struct drm_mode_object base;
> > -	struct drm_device *dev;
> > -	struct list_head head_global;
> > -	struct list_head head_file;
> > -	size_t length;
> > -	unsigned char data[];
> > -};
> > -
> > +/**
> > + * struct drm_property_enum - symbolic values for enumerations
> > + * @value: numeric property value for this enum entry
> > + * @head: list of enum values, linked to enum_list in &drm_property
> > + * @name: symbolic name for the enum
> > + *
> > + * For enumeration and bitmask properties this structure stores the symbolic
> > + * decoding for each value. This is used for example for the rotation property.
> > + */
> >   struct drm_property_enum {
> >   	uint64_t value;
> >   	struct list_head head;
> >   	char name[DRM_PROP_NAME_LEN];
> >   };
> > 
> > +/**
> > + * struct drm_property - modeset object property
> > + *
> > + * This structure represent a modeset object property. It combines both the name
> > + * of the property with the set of permissible values. This means that when a
> > + * driver wants to use a property with the same name on different objects, but
> > + * with different value ranges, then it must create property for each one. An
> > + * example would be rotation of &drm_plane, when e.g. the primary plane cannot
> > + * be rotated. But if both the name and the value range match, then the same
> > + * property structure can be instantiated multiple times for the same object.
> > + * Userspace must be able to cope with this and cannot assume that the same
> > + * symbolic property will have the same modeset object ID on all modeset
> > + * objects.
> > + *
> > + * Properties are created by one of the special functions, as explained in
> > + * detail in the @flags structure member.
> > + *
> > + * To actually expose a property it must be attached to each object using
> > + * drm_object_attach_property(). Currently properties can only be attached to
> > + * &drm_connector, &drm_crtc and &drm_plane.
> > + *
> > + * Properties are also used as the generic metadatatransport for the atomic
> > + * IOCTL. Everything that was set directly in structures in the legacy modeset
> > + * IOCTLs (like the plane source or destination windows, or e.g. the links to
> > + * the CRTC) is exposed as a property with the DRM_MODE_PROP_ATOMIC flag set.
> > + */
> >   struct drm_property {
> > +	/**
> > +	 * @head: per-device list of properties, for cleanup.
> > +	 */
> >   	struct list_head head;
> > +
> > +	/**
> > +	 * @base: base KMS object
> > +	 */
> >   	struct drm_mode_object base;
> > +
> > +	/**
> > +	 * @flags:
> > +	 *
> > +	 * Property flags and type. A property needs to be one of the following
> > +	 * types:
> > +	 *
> > +	 * DRM_MODE_PROP_RANGE
> > +	 *     Range properties report their minimum and maximum admissible unsigned values.
> > +	 *     The KMS core verifies that values set by application fit in that
> > +	 *     range. The range is unsigned. Range properties are created using
> > +	 *     drm_property_create_range().
> > +	 *
> > +	 * DRM_MODE_PROP_SIGNED_RANGE
> > +	 *     Range properties report their minimum and maximum admissible unsigned values.
> > +	 *     The KMS core verifies that values set by application fit in that
> > +	 *     range. The range is signed. Range properties are created using
> > +	 *     drm_property_create_signed_range().
> > +	 *
> > +	 * DRM_MODE_PROP_ENUM
> > +	 *     Enumerated properties take a numerical value that ranges from 0 to
> > +	 *     the number of enumerated values defined by the property minus one,
> > +	 *     and associate a free-formed string name to each value. Applications
> > +	 *     can retrieve the list of defined value-name pairs and use the
> > +	 *     numerical value to get and set property instance values. Enum
> > +	 *     properties are created using drm_property_create_enum().
> > +	 *
> > +	 * DRM_MODE_PROP_BITMASK
> > +	 *     Bitmask properties are enumeration properties that additionally
> > +	 *     restrict all enumerated values to the 0..63 range. Bitmask property
> > +	 *     instance values combine one or more of the enumerated bits defined
> > +	 *     by the property. Bitmask properties are created using
> > +	 *     drm_property_create_bitmask().
> > +	 *
> > +	 * DRM_MODE_PROB_OBJECT
> > +	 *     Object properties are used to link modeset objects. This is used
> > +	 *     extensively in the atomic support to create the display pipeline,
> > +	 *     by linking &drm_framebuffer to &drm_plane, &drm_plane to
> > +	 *     &drm_crtc and &drm_connector to &drm_crtc. An object property can
> > +	 *     only link to a specific type of &drm_mode_object, this limit is
> > +	 *     enforced by the core. Object properties are created using
> > +	 *     drm_property_create_object().
> > +	 *
> > +	 *     Object properties work like blob properties, but in a more
> > +	 *     general fashion. They are limited to atomic drivers and must have
> > +	 *     the DRM_MODE_PROP_ATOMIC flag set.
> > +	 *
> > +	 * DRM_MODE_PROP_BLOB
> > +	 *     Blob properties store a binary blob without any format restriction.
> > +	 *     The binary blobs are created as KMS standalone objects, and blob
> > +	 *     property instance values store the ID of their associated blob
> > +	 *     object. Blob properties are created by calling
> > +	 *     drm_property_create() with DRM_MODE_PROP_BLOB as the type.
> > +	 *
> > +	 *     Actual blob objects to contain blob data are created using
> > +	 *     drm_property_create_blob(), or through the corresponding IOCTL.
> > +	 *
> > +	 *     Besides the built-in limit to only accept blob objects blob
> > +	 *     properties work exactly like object properties. The only reasons
> > +	 *     blob properties exist is backwards compatibility with existing
> > +	 *     userspace.
> > +	 *
> > +	 * In addition a property can have any combination of the below flags:
> > +	 *
> > +	 * DRM_MODE_PROP_ATOMIC
> > +	 *     Set for properties which encode atomic modeset state. Such
> > +	 *     properties are not exposed to legacy userspace.
> > +	 *
> > +	 * DRM_MODE_PROP_IMMUTABLE
> > +	 *     Set for properties where userspace cannot be changed by
> > +	 *     userspace. The kernel is allowed to update the value of these
> > +	 *     properties. This is generally used to expose probe state to
> > +	 *     usersapce, e.g. the EDID, or the connector path property on DP
> > +	 *     MST sinks.
> > +	 */
> >   	uint32_t flags;
> > +
> > +	/**
> > +	 * @name: symbolic name of the properties
> > +	 */
> >   	char name[DRM_PROP_NAME_LEN];
> > +
> > +	/**
> > +	 * @num_values: size of the @values array.
> > +	 */
> >   	uint32_t num_values;
> > +
> > +	/**
> > +	 * @values:
> > +	 *
> > +	 * Array with limits and values for the property. The
> > +	 * interpretation of these limits is dependent upon the type per @flags.
> > +	 */
> >   	uint64_t *values;
> > +
> > +	/**
> > +	 * @dev: DRM device
> > +	 */
> >   	struct drm_device *dev;
> > 
> > +	/**
> > +	 * @enum_list:
> > +	 *
> > +	 * List of &drm_prop_enum_list structures with the symbolic names for
> > +	 * enum and bitmask values.
> > +	 */
> >   	struct list_head enum_list;
> >   };
> > 
> > +/**
> > + * struct drm_property_blob - Blob data for &drm_property
> > + * @base: base KMS object
> > + * @dev: DRM device
> > + * @head_global: entry on the global blob list in &drm_mode_config
> > + *	property_blob_list.
> > + * @head_file: entry on the per-file blob list in &drm_file blobs list.
> > + * @length: size of the blob in bytes, invariant over the lifetime of the object
> > + * @data: actual data, embedded at the end of this structure
> > + *
> > + * Blobs are used to store bigger values than what fits directly into the 64
> > + * bits available for a &drm_property.
> > + *
> > + * Blobs are reference counted using drm_property_reference_blob() and
> > + * drm_property_unreference_blob(). They are created using
> > + * drm_property_create_blob().
> > + */
> > +struct drm_property_blob {
> > +	struct drm_mode_object base;
> > +	struct drm_device *dev;
> > +	struct list_head head_global;
> > +	struct list_head head_file;
> > +	size_t length;
> > +	unsigned char data[];
> > +};
> > +
> >   struct drm_prop_enum_list {
> >   	int type;
> >   	char *name;
> > @@ -61,8 +220,16 @@ struct drm_prop_enum_list {
> > 
> >   #define obj_to_property(x) container_of(x, struct drm_property, base)
> > 
> > +/**
> > + * drm_property_type_is - check the type of a property
> > + * @property: property to check
> > + * @type: property type to compare with
> > + *
> > + * This is a helper function becauase the uapi encoding of property types is
> > + * a bit special for historical reasons.
> > + */
> >   static inline bool drm_property_type_is(struct drm_property *property,
> > -		uint32_t type)
> > +					uint32_t type)
> >   {
> >   	/* instanceof for props.. handles extended type vs original types: */
> >   	if (property->flags & DRM_MODE_PROP_EXTENDED_TYPE)
> > @@ -109,8 +276,15 @@ int drm_property_replace_global_blob(struct drm_device *dev,
> >   struct drm_property_blob *drm_property_reference_blob(struct drm_property_blob *blob);
> >   void drm_property_unreference_blob(struct drm_property_blob *blob);
> > 
> > +/**
> > + * drm_connector_find - find property object
> > + * @dev: DRM device
> > + * @id: property object id
> > + *
> > + * This function looks up the property object specified by id and returns it.
> > + */
> >   static inline struct drm_property *drm_property_find(struct drm_device *dev,
> > -		uint32_t id)
> > +						     uint32_t id)
> >   {
> >   	struct drm_mode_object *mo;
> >   	mo = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_PROPERTY);
> > 
> 
> -- 
> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
> a Linux Foundation Collaborative Project
diff mbox

Patch

diff --git a/Documentation/gpu/drm-kms.rst b/Documentation/gpu/drm-kms.rst
index e07a2667ab61..f9a991bb87d4 100644
--- a/Documentation/gpu/drm-kms.rst
+++ b/Documentation/gpu/drm-kms.rst
@@ -304,94 +304,12 @@  KMS Locking
 KMS Properties
 ==============
 
-Drivers may need to expose additional parameters to applications than
-those described in the previous sections. KMS supports attaching
-properties to CRTCs, connectors and planes and offers a userspace API to
-list, get and set the property values.
-
-Properties are identified by a name that uniquely defines the property
-purpose, and store an associated value. For all property types except
-blob properties the value is a 64-bit unsigned integer.
-
-KMS differentiates between properties and property instances. Drivers
-first create properties and then create and associate individual
-instances of those properties to objects. A property can be instantiated
-multiple times and associated with different objects. Values are stored
-in property instances, and all other property information are stored in
-the property and shared between all instances of the property.
-
-Every property is created with a type that influences how the KMS core
-handles the property. Supported property types are
-
-DRM_MODE_PROP_RANGE
-    Range properties report their minimum and maximum admissible values.
-    The KMS core verifies that values set by application fit in that
-    range.
-
-DRM_MODE_PROP_ENUM
-    Enumerated properties take a numerical value that ranges from 0 to
-    the number of enumerated values defined by the property minus one,
-    and associate a free-formed string name to each value. Applications
-    can retrieve the list of defined value-name pairs and use the
-    numerical value to get and set property instance values.
-
-DRM_MODE_PROP_BITMASK
-    Bitmask properties are enumeration properties that additionally
-    restrict all enumerated values to the 0..63 range. Bitmask property
-    instance values combine one or more of the enumerated bits defined
-    by the property.
-
-DRM_MODE_PROP_BLOB
-    Blob properties store a binary blob without any format restriction.
-    The binary blobs are created as KMS standalone objects, and blob
-    property instance values store the ID of their associated blob
-    object.
-
-    Blob properties are only used for the connector EDID property and
-    cannot be created by drivers.
-
-To create a property drivers call one of the following functions
-depending on the property type. All property creation functions take
-property flags and name, as well as type-specific arguments.
-
--  struct drm_property \*drm_property_create_range(struct
-   drm_device \*dev, int flags, const char \*name, uint64_t min,
-   uint64_t max);
-   Create a range property with the given minimum and maximum values.
-
--  struct drm_property \*drm_property_create_enum(struct drm_device
-   \*dev, int flags, const char \*name, const struct
-   drm_prop_enum_list \*props, int num_values);
-   Create an enumerated property. The ``props`` argument points to an
-   array of ``num_values`` value-name pairs.
-
--  struct drm_property \*drm_property_create_bitmask(struct
-   drm_device \*dev, int flags, const char \*name, const struct
-   drm_prop_enum_list \*props, int num_values);
-   Create a bitmask property. The ``props`` argument points to an array
-   of ``num_values`` value-name pairs.
-
-Properties can additionally be created as immutable, in which case they
-will be read-only for applications but can be modified by the driver. To
-create an immutable property drivers must set the
-DRM_MODE_PROP_IMMUTABLE flag at property creation time.
-
-When no array of value-name pairs is readily available at property
-creation time for enumerated or range properties, drivers can create the
-property using the :c:func:`drm_property_create()` function and
-manually add enumeration value-name pairs by calling the
-:c:func:`drm_property_add_enum()` function. Care must be taken to
-properly specify the property type through the ``flags`` argument.
-
-After creating properties drivers can attach property instances to CRTC,
-connector and plane objects by calling the
-:c:func:`drm_object_attach_property()`. The function takes a
-pointer to the target object, a pointer to the previously created
-property and an initial instance value.
-
 Property Types and Blob Property Support
 ----------------------------------------
 
+.. kernel-doc:: drivers/gpu/drm/drm_property.c
+   :doc: overview
+
 .. kernel-doc:: include/drm/drm_property.h
    :internal:
 
diff --git a/drivers/gpu/drm/drm_property.c b/drivers/gpu/drm/drm_property.c
index b5521f705b1c..4139afbcc267 100644
--- a/drivers/gpu/drm/drm_property.c
+++ b/drivers/gpu/drm/drm_property.c
@@ -26,6 +26,30 @@ 
 
 #include "drm_crtc_internal.h"
 
+/**
+ * DOC: overview
+ *
+ * Properties as represented by &drm_property are used to extend the modeset
+ * interface exposed to userspace. For the atomic modeset IOCTL properties are
+ * even the only way to transport metadata about the desired new modeset
+ * configuration from userspace to the kernel. Properties have a well-defined
+ * value range, which is enforced by the drm core. See the documentation of the
+ * flags member of struct &drm_property for an overview of the different
+ * property types and ranges.
+ *
+ * Properties don't store the current value directly, but need to be
+ * instatiated by attaching them to a &drm_mode_object with
+ * drm_object_attach_property().
+ *
+ * Property values are only 64bit. To support bigger piles of data (like gamma
+ * tables, color correction matrizes or large structures) a property can instead
+ * point at a &drm_property_blob with that additional data
+ *
+ * Properties are defined by their symbolic name, userspace must keep a
+ * per-object mapping from those names to the property ID used in the atomic
+ * IOCTL and in the get/set property IOCTL.
+ */
+
 static bool drm_property_type_valid(struct drm_property *property)
 {
 	if (property->flags & DRM_MODE_PROP_EXTENDED_TYPE)
@@ -42,11 +66,8 @@  static bool drm_property_type_valid(struct drm_property *property)
  *
  * This creates a new generic drm property which can then be attached to a drm
  * object with drm_object_attach_property. The returned property object must be
- * freed with drm_property_destroy.
- *
- * Note that the DRM core keeps a per-device list of properties and that, if
- * drm_mode_config_cleanup() is called, it will destroy all properties created
- * by the driver.
+ * freed with drm_property_destroy(), which is done automatically when calling
+ * drm_mode_config_cleanup().
  *
  * Returns:
  * A pointer to the newly created property on success, NULL on failure.
@@ -105,7 +126,8 @@  EXPORT_SYMBOL(drm_property_create);
  *
  * This creates a new generic drm property which can then be attached to a drm
  * object with drm_object_attach_property. The returned property object must be
- * freed with drm_property_destroy.
+ * freed with drm_property_destroy(), which is done automatically when calling
+ * drm_mode_config_cleanup().
  *
  * Userspace is only allowed to set one of the predefined values for enumeration
  * properties.
@@ -152,7 +174,8 @@  EXPORT_SYMBOL(drm_property_create_enum);
  *
  * This creates a new bitmask drm property which can then be attached to a drm
  * object with drm_object_attach_property. The returned property object must be
- * freed with drm_property_destroy.
+ * freed with drm_property_destroy(), which is done automatically when calling
+ * drm_mode_config_cleanup().
  *
  * Compared to plain enumeration properties userspace is allowed to set any
  * or'ed together combination of the predefined property bitflag values
@@ -223,7 +246,8 @@  static struct drm_property *property_create_range(struct drm_device *dev,
  *
  * This creates a new generic drm property which can then be attached to a drm
  * object with drm_object_attach_property. The returned property object must be
- * freed with drm_property_destroy.
+ * freed with drm_property_destroy(), which is done automatically when calling
+ * drm_mode_config_cleanup().
  *
  * Userspace is allowed to set any unsigned integer value in the (min, max)
  * range inclusive.
@@ -250,7 +274,8 @@  EXPORT_SYMBOL(drm_property_create_range);
  *
  * This creates a new generic drm property which can then be attached to a drm
  * object with drm_object_attach_property. The returned property object must be
- * freed with drm_property_destroy.
+ * freed with drm_property_destroy(), which is done automatically when calling
+ * drm_mode_config_cleanup().
  *
  * Userspace is allowed to set any signed integer value in the (min, max)
  * range inclusive.
@@ -276,7 +301,8 @@  EXPORT_SYMBOL(drm_property_create_signed_range);
  *
  * This creates a new generic drm property which can then be attached to a drm
  * object with drm_object_attach_property. The returned property object must be
- * freed with drm_property_destroy.
+ * freed with drm_property_destroy(), which is done automatically when calling
+ * drm_mode_config_cleanup().
  *
  * Userspace is only allowed to set this to any property value of the given
  * @type. Only useful for atomic properties, which is enforced.
@@ -285,7 +311,8 @@  EXPORT_SYMBOL(drm_property_create_signed_range);
  * A pointer to the newly created property on success, NULL on failure.
  */
 struct drm_property *drm_property_create_object(struct drm_device *dev,
-					 int flags, const char *name, uint32_t type)
+						int flags, const char *name,
+						uint32_t type)
 {
 	struct drm_property *property;
 
@@ -312,7 +339,8 @@  EXPORT_SYMBOL(drm_property_create_object);
  *
  * This creates a new generic drm property which can then be attached to a drm
  * object with drm_object_attach_property. The returned property object must be
- * freed with drm_property_destroy.
+ * freed with drm_property_destroy(), which is done automatically when calling
+ * drm_mode_config_cleanup().
  *
  * This is implemented as a ranged property with only {0, 1} as valid values.
  *
@@ -320,7 +348,7 @@  EXPORT_SYMBOL(drm_property_create_object);
  * A pointer to the newly created property on success, NULL on failure.
  */
 struct drm_property *drm_property_create_bool(struct drm_device *dev, int flags,
-					 const char *name)
+					      const char *name)
 {
 	return drm_property_create_range(dev, flags, name, 0, 1);
 }
@@ -407,22 +435,6 @@  void drm_property_destroy(struct drm_device *dev, struct drm_property *property)
 }
 EXPORT_SYMBOL(drm_property_destroy);
 
-/**
- * drm_mode_getproperty_ioctl - get the property metadata
- * @dev: DRM device
- * @data: ioctl data
- * @file_priv: DRM file info
- *
- * This function retrieves the metadata for a given property, like the different
- * possible values for an enum property or the limits for a range property.
- *
- * Blob properties are special
- *
- * Called by the user via ioctl.
- *
- * Returns:
- * Zero on success, negative errno on failure.
- */
 int drm_mode_getproperty_ioctl(struct drm_device *dev,
 			       void *data, struct drm_file *file_priv)
 {
@@ -523,14 +535,14 @@  static void drm_property_free_blob(struct kref *kref)
 
 /**
  * drm_property_create_blob - Create new blob property
- *
- * Creates a new blob property for a specified DRM device, optionally
- * copying data.
- *
  * @dev: DRM device to create property for
  * @length: Length to allocate for blob data
  * @data: If specified, copies data into blob
  *
+ * Creates a new blob property for a specified DRM device, optionally
+ * copying data. Note that blob properties are meant to be invariant, hence the
+ * data must be filled out before the blob is used as the value of any property.
+ *
  * Returns:
  * New blob property with a single reference on success, or an ERR_PTR
  * value on failure.
@@ -576,10 +588,9 @@  EXPORT_SYMBOL(drm_property_create_blob);
 
 /**
  * drm_property_unreference_blob - Unreference a blob property
+ * @blob: Pointer to blob property
  *
  * Drop a reference on a blob property. May free the object.
- *
- * @blob: Pointer to blob property
  */
 void drm_property_unreference_blob(struct drm_property_blob *blob)
 {
@@ -590,11 +601,6 @@  void drm_property_unreference_blob(struct drm_property_blob *blob)
 }
 EXPORT_SYMBOL(drm_property_unreference_blob);
 
-/**
- * drm_property_destroy_user_blobs - destroy all blobs created by this client
- * @dev:       DRM device
- * @file_priv: destroy all blobs owned by this file handle
- */
 void drm_property_destroy_user_blobs(struct drm_device *dev,
 				     struct drm_file *file_priv)
 {
@@ -612,10 +618,10 @@  void drm_property_destroy_user_blobs(struct drm_device *dev,
 
 /**
  * drm_property_reference_blob - Take a reference on an existing property
- *
- * Take a new reference on an existing blob property.
- *
  * @blob: Pointer to blob property
+ *
+ * Take a new reference on an existing blob property. Returns @blob, which
+ * allows this to be used as a shorthand in assignments.
  */
 struct drm_property_blob *drm_property_reference_blob(struct drm_property_blob *blob)
 {
@@ -632,6 +638,9 @@  EXPORT_SYMBOL(drm_property_reference_blob);
  * If successful, this takes an additional reference to the blob property.
  * callers need to make sure to eventually unreference the returned property
  * again, using @drm_property_unreference_blob.
+ *
+ * Return:
+ * NULL on failure, pointer to the blob on success.
  */
 struct drm_property_blob *drm_property_lookup_blob(struct drm_device *dev,
 					           uint32_t id)
@@ -647,7 +656,7 @@  struct drm_property_blob *drm_property_lookup_blob(struct drm_device *dev,
 EXPORT_SYMBOL(drm_property_lookup_blob);
 
 /**
- * drm_property_replace_global_blob - atomically replace existing blob property
+ * drm_property_replace_global_blob - replace existing blob property
  * @dev: drm device
  * @replace: location of blob property pointer to be replaced
  * @length: length of data for new blob, or 0 for no data
@@ -656,11 +665,8 @@  EXPORT_SYMBOL(drm_property_lookup_blob);
  * @prop_holds_id: optional property holding blob ID
  * @return 0 on success or error on failure
  *
- * This function will atomically replace a global property in the blob list,
- * optionally updating a property which holds the ID of that property. It is
- * guaranteed to be atomic: no caller will be allowed to see intermediate
- * results, and either the entire operation will succeed and clean up the
- * previous property, or it will fail and the state will be unchanged.
+ * This function will replace a global property in the blob list, optionally
+ * updating a property which holds the ID of that property.
  *
  * If length is 0 or data is NULL, no new blob will be created, and the holding
  * property, if specified, will be set to 0.
@@ -697,11 +703,6 @@  int drm_property_replace_global_blob(struct drm_device *dev,
 			return PTR_ERR(new_blob);
 	}
 
-	/* This does not need to be synchronised with blob_lock, as the
-	 * get_properties ioctl locks all modesetting objects, and
-	 * obj_holds_id must be locked before calling here, so we cannot
-	 * have its value out of sync with the list membership modified
-	 * below under blob_lock. */
 	if (obj_holds_id) {
 		ret = drm_object_property_set_value(obj_holds_id,
 						    prop_holds_id,
@@ -722,20 +723,6 @@  err_created:
 }
 EXPORT_SYMBOL(drm_property_replace_global_blob);
 
-/**
- * drm_mode_getblob_ioctl - get the contents of a blob property value
- * @dev: DRM device
- * @data: ioctl data
- * @file_priv: DRM file info
- *
- * This function retrieves the contents of a blob property. The value stored in
- * an object's blob property is just a normal modeset object id.
- *
- * Called by the user via ioctl.
- *
- * Returns:
- * Zero on success, negative errno on failure.
- */
 int drm_mode_getblob_ioctl(struct drm_device *dev,
 			   void *data, struct drm_file *file_priv)
 {
@@ -765,21 +752,6 @@  unref:
 	return ret;
 }
 
-/**
- * drm_mode_createblob_ioctl - create a new blob property
- * @dev: DRM device
- * @data: ioctl data
- * @file_priv: DRM file info
- *
- * This function creates a new blob property with user-defined values. In order
- * to give us sensible validation and checking when creating, rather than at
- * every potential use, we also require a type to be provided upfront.
- *
- * Called by the user via ioctl.
- *
- * Returns:
- * Zero on success, negative errno on failure.
- */
 int drm_mode_createblob_ioctl(struct drm_device *dev,
 			      void *data, struct drm_file *file_priv)
 {
@@ -816,19 +788,6 @@  out_blob:
 	return ret;
 }
 
-/**
- * drm_mode_destroyblob_ioctl - destroy a user blob property
- * @dev: DRM device
- * @data: ioctl data
- * @file_priv: DRM file info
- *
- * Destroy an existing user-defined blob property.
- *
- * Called by the user via ioctl.
- *
- * Returns:
- * Zero on success, negative errno on failure.
- */
 int drm_mode_destroyblob_ioctl(struct drm_device *dev,
 			       void *data, struct drm_file *file_priv)
 {
@@ -885,7 +844,7 @@  err:
  * reference).
  */
 bool drm_property_change_valid_get(struct drm_property *property,
-					 uint64_t value, struct drm_mode_object **ref)
+				   uint64_t value, struct drm_mode_object **ref)
 {
 	int i;
 
diff --git a/include/drm/drm_property.h b/include/drm/drm_property.h
index ac40069358c7..30ab289be05d 100644
--- a/include/drm/drm_property.h
+++ b/include/drm/drm_property.h
@@ -27,33 +27,192 @@ 
 #include <linux/ctype.h>
 #include <drm/drm_mode_object.h>
 
-struct drm_property_blob {
-	struct drm_mode_object base;
-	struct drm_device *dev;
-	struct list_head head_global;
-	struct list_head head_file;
-	size_t length;
-	unsigned char data[];
-};
-
+/**
+ * struct drm_property_enum - symbolic values for enumerations
+ * @value: numeric property value for this enum entry
+ * @head: list of enum values, linked to enum_list in &drm_property
+ * @name: symbolic name for the enum
+ *
+ * For enumeration and bitmask properties this structure stores the symbolic
+ * decoding for each value. This is used for example for the rotation property.
+ */
 struct drm_property_enum {
 	uint64_t value;
 	struct list_head head;
 	char name[DRM_PROP_NAME_LEN];
 };
 
+/**
+ * struct drm_property - modeset object property
+ *
+ * This structure represent a modeset object property. It combines both the name
+ * of the property with the set of permissible values. This means that when a
+ * driver wants to use a property with the same name on different objects, but
+ * with different value ranges, then it must create property for each one. An
+ * example would be rotation of &drm_plane, when e.g. the primary plane cannot
+ * be rotated. But if both the name and the value range match, then the same
+ * property structure can be instantiated multiple times for the same object.
+ * Userspace must be able to cope with this and cannot assume that the same
+ * symbolic property will have the same modeset object ID on all modeset
+ * objects.
+ *
+ * Properties are created by one of the special functions, as explained in
+ * detail in the @flags structure member.
+ *
+ * To actually expose a property it must be attached to each object using
+ * drm_object_attach_property(). Currently properties can only be attached to
+ * &drm_connector, &drm_crtc and &drm_plane.
+ *
+ * Properties are also used as the generic metadatatransport for the atomic
+ * IOCTL. Everything that was set directly in structures in the legacy modeset
+ * IOCTLs (like the plane source or destination windows, or e.g. the links to
+ * the CRTC) is exposed as a property with the DRM_MODE_PROP_ATOMIC flag set.
+ */
 struct drm_property {
+	/**
+	 * @head: per-device list of properties, for cleanup.
+	 */
 	struct list_head head;
+
+	/**
+	 * @base: base KMS object
+	 */
 	struct drm_mode_object base;
+
+	/**
+	 * @flags:
+	 *
+	 * Property flags and type. A property needs to be one of the following
+	 * types:
+	 *
+	 * DRM_MODE_PROP_RANGE
+	 *     Range properties report their minimum and maximum admissible unsigned values.
+	 *     The KMS core verifies that values set by application fit in that
+	 *     range. The range is unsigned. Range properties are created using
+	 *     drm_property_create_range().
+	 *
+	 * DRM_MODE_PROP_SIGNED_RANGE
+	 *     Range properties report their minimum and maximum admissible unsigned values.
+	 *     The KMS core verifies that values set by application fit in that
+	 *     range. The range is signed. Range properties are created using
+	 *     drm_property_create_signed_range().
+	 *
+	 * DRM_MODE_PROP_ENUM
+	 *     Enumerated properties take a numerical value that ranges from 0 to
+	 *     the number of enumerated values defined by the property minus one,
+	 *     and associate a free-formed string name to each value. Applications
+	 *     can retrieve the list of defined value-name pairs and use the
+	 *     numerical value to get and set property instance values. Enum
+	 *     properties are created using drm_property_create_enum().
+	 *
+	 * DRM_MODE_PROP_BITMASK
+	 *     Bitmask properties are enumeration properties that additionally
+	 *     restrict all enumerated values to the 0..63 range. Bitmask property
+	 *     instance values combine one or more of the enumerated bits defined
+	 *     by the property. Bitmask properties are created using
+	 *     drm_property_create_bitmask().
+	 *
+	 * DRM_MODE_PROB_OBJECT
+	 *     Object properties are used to link modeset objects. This is used
+	 *     extensively in the atomic support to create the display pipeline,
+	 *     by linking &drm_framebuffer to &drm_plane, &drm_plane to
+	 *     &drm_crtc and &drm_connector to &drm_crtc. An object property can
+	 *     only link to a specific type of &drm_mode_object, this limit is
+	 *     enforced by the core. Object properties are created using
+	 *     drm_property_create_object().
+	 *
+	 *     Object properties work like blob properties, but in a more
+	 *     general fashion. They are limited to atomic drivers and must have
+	 *     the DRM_MODE_PROP_ATOMIC flag set.
+	 *
+	 * DRM_MODE_PROP_BLOB
+	 *     Blob properties store a binary blob without any format restriction.
+	 *     The binary blobs are created as KMS standalone objects, and blob
+	 *     property instance values store the ID of their associated blob
+	 *     object. Blob properties are created by calling
+	 *     drm_property_create() with DRM_MODE_PROP_BLOB as the type.
+	 *
+	 *     Actual blob objects to contain blob data are created using
+	 *     drm_property_create_blob(), or through the corresponding IOCTL.
+	 *
+	 *     Besides the built-in limit to only accept blob objects blob
+	 *     properties work exactly like object properties. The only reasons
+	 *     blob properties exist is backwards compatibility with existing
+	 *     userspace.
+	 *
+	 * In addition a property can have any combination of the below flags:
+	 *
+	 * DRM_MODE_PROP_ATOMIC
+	 *     Set for properties which encode atomic modeset state. Such
+	 *     properties are not exposed to legacy userspace.
+	 *
+	 * DRM_MODE_PROP_IMMUTABLE
+	 *     Set for properties where userspace cannot be changed by
+	 *     userspace. The kernel is allowed to update the value of these
+	 *     properties. This is generally used to expose probe state to
+	 *     usersapce, e.g. the EDID, or the connector path property on DP
+	 *     MST sinks.
+	 */
 	uint32_t flags;
+
+	/**
+	 * @name: symbolic name of the properties
+	 */
 	char name[DRM_PROP_NAME_LEN];
+
+	/**
+	 * @num_values: size of the @values array.
+	 */
 	uint32_t num_values;
+
+	/**
+	 * @values:
+	 *
+	 * Array with limits and values for the property. The
+	 * interpretation of these limits is dependent upon the type per @flags.
+	 */
 	uint64_t *values;
+
+	/**
+	 * @dev: DRM device
+	 */
 	struct drm_device *dev;
 
+	/**
+	 * @enum_list:
+	 *
+	 * List of &drm_prop_enum_list structures with the symbolic names for
+	 * enum and bitmask values.
+	 */
 	struct list_head enum_list;
 };
 
+/**
+ * struct drm_property_blob - Blob data for &drm_property
+ * @base: base KMS object
+ * @dev: DRM device
+ * @head_global: entry on the global blob list in &drm_mode_config
+ *	property_blob_list.
+ * @head_file: entry on the per-file blob list in &drm_file blobs list.
+ * @length: size of the blob in bytes, invariant over the lifetime of the object
+ * @data: actual data, embedded at the end of this structure
+ *
+ * Blobs are used to store bigger values than what fits directly into the 64
+ * bits available for a &drm_property.
+ *
+ * Blobs are reference counted using drm_property_reference_blob() and
+ * drm_property_unreference_blob(). They are created using
+ * drm_property_create_blob().
+ */
+struct drm_property_blob {
+	struct drm_mode_object base;
+	struct drm_device *dev;
+	struct list_head head_global;
+	struct list_head head_file;
+	size_t length;
+	unsigned char data[];
+};
+
 struct drm_prop_enum_list {
 	int type;
 	char *name;
@@ -61,8 +220,16 @@  struct drm_prop_enum_list {
 
 #define obj_to_property(x) container_of(x, struct drm_property, base)
 
+/**
+ * drm_property_type_is - check the type of a property
+ * @property: property to check
+ * @type: property type to compare with
+ *
+ * This is a helper function becauase the uapi encoding of property types is
+ * a bit special for historical reasons.
+ */
 static inline bool drm_property_type_is(struct drm_property *property,
-		uint32_t type)
+					uint32_t type)
 {
 	/* instanceof for props.. handles extended type vs original types: */
 	if (property->flags & DRM_MODE_PROP_EXTENDED_TYPE)
@@ -109,8 +276,15 @@  int drm_property_replace_global_blob(struct drm_device *dev,
 struct drm_property_blob *drm_property_reference_blob(struct drm_property_blob *blob);
 void drm_property_unreference_blob(struct drm_property_blob *blob);
 
+/**
+ * drm_connector_find - find property object
+ * @dev: DRM device
+ * @id: property object id
+ *
+ * This function looks up the property object specified by id and returns it.
+ */
 static inline struct drm_property *drm_property_find(struct drm_device *dev,
-		uint32_t id)
+						     uint32_t id)
 {
 	struct drm_mode_object *mo;
 	mo = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_PROPERTY);