[PATCH 1/2] drm: add bitmask property type
From: Rob ClarkA bitmask property is similar to an enum. The enum value is a bit position (0-63), and valid property values consist of a mask of zero or more of (1 << enum_val[n]). Signed-off-by: Rob Clark Reviewed-by: Paulo Zanoni --- v1: original v2: added comments to new fields in drm_plane_funcs and drm_plane drivers/gpu/drm/drm_crtc.c | 47 +--- include/drm/drm_crtc.h |4 include/drm/drm_mode.h |1 + 3 files changed, 49 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 75661c8..bf2bb9b 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -2707,6 +2707,34 @@ struct drm_property *drm_property_create_enum(struct drm_device *dev, int flags, } EXPORT_SYMBOL(drm_property_create_enum); +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) +{ + struct drm_property *property; + int i, ret; + + flags |= DRM_MODE_PROP_BITMASK; + + property = drm_property_create(dev, flags, name, num_values); + if (!property) + return NULL; + + for (i = 0; i < num_values; i++) { + ret = drm_property_add_enum(property, i, + props[i].type, + props[i].name); + if (ret) { + drm_property_destroy(dev, property); + return NULL; + } + } + + return property; +} +EXPORT_SYMBOL(drm_property_create_bitmask); + struct drm_property *drm_property_create_range(struct drm_device *dev, int flags, const char *name, uint64_t min, uint64_t max) @@ -2731,7 +2759,14 @@ int drm_property_add_enum(struct drm_property *property, int index, { struct drm_property_enum *prop_enum; - if (!(property->flags & DRM_MODE_PROP_ENUM)) + if (!(property->flags & (DRM_MODE_PROP_ENUM | DRM_MODE_PROP_BITMASK))) + return -EINVAL; + + /* +* Bitmask enum properties have the additional constraint of values +* from 0 to 63 +*/ + if ((property->flags & DRM_MODE_PROP_BITMASK) && (value > 63)) return -EINVAL; if (!list_empty(>enum_blob_list)) { @@ -2875,7 +2910,7 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev, } property = obj_to_property(obj); - if (property->flags & DRM_MODE_PROP_ENUM) { + if (property->flags & (DRM_MODE_PROP_ENUM | DRM_MODE_PROP_BITMASK)) { list_for_each_entry(prop_enum, >enum_blob_list, head) enum_count++; } else if (property->flags & DRM_MODE_PROP_BLOB) { @@ -2900,7 +2935,7 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev, } out_resp->count_values = value_count; - if (property->flags & DRM_MODE_PROP_ENUM) { + if (property->flags & (DRM_MODE_PROP_ENUM | DRM_MODE_PROP_BITMASK)) { if ((out_resp->count_enum_blobs >= enum_count) && enum_count) { copied = 0; enum_ptr = (struct drm_mode_property_enum __user *)(unsigned long)out_resp->enum_blob_ptr; @@ -3055,6 +3090,12 @@ static bool drm_property_change_is_valid(struct drm_property *property, if (value < property->values[0] || value > property->values[1]) return false; return true; + } else if (property->flags & DRM_MODE_PROP_BITMASK) { + int i; + __u64 valid_mask = 0; + for (i = 0; i < property->num_values; i++) + valid_mask |= (1LL << property->values[i]); + return !(value & ~valid_mask); } else { int i; for (i = 0; i < property->num_values; i++) diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index e194c78..9b53c14 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -940,6 +940,10 @@ extern struct drm_property *drm_property_create_enum(struct drm_device *dev, int const char *name, const struct drm_prop_enum_list *props, int num_values); +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); struct drm_property *drm_property_create_range(struct drm_device *dev, int flags,
[PATCH 1/2] drm: add bitmask property type
From: Rob Clark r...@ti.com A bitmask property is similar to an enum. The enum value is a bit position (0-63), and valid property values consist of a mask of zero or more of (1 enum_val[n]). Signed-off-by: Rob Clark r...@ti.com Reviewed-by: Paulo Zanoni paulo.r.zan...@intel.com --- v1: original v2: added comments to new fields in drm_plane_funcs and drm_plane drivers/gpu/drm/drm_crtc.c | 47 +--- include/drm/drm_crtc.h |4 include/drm/drm_mode.h |1 + 3 files changed, 49 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 75661c8..bf2bb9b 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -2707,6 +2707,34 @@ struct drm_property *drm_property_create_enum(struct drm_device *dev, int flags, } EXPORT_SYMBOL(drm_property_create_enum); +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) +{ + struct drm_property *property; + int i, ret; + + flags |= DRM_MODE_PROP_BITMASK; + + property = drm_property_create(dev, flags, name, num_values); + if (!property) + return NULL; + + for (i = 0; i num_values; i++) { + ret = drm_property_add_enum(property, i, + props[i].type, + props[i].name); + if (ret) { + drm_property_destroy(dev, property); + return NULL; + } + } + + return property; +} +EXPORT_SYMBOL(drm_property_create_bitmask); + struct drm_property *drm_property_create_range(struct drm_device *dev, int flags, const char *name, uint64_t min, uint64_t max) @@ -2731,7 +2759,14 @@ int drm_property_add_enum(struct drm_property *property, int index, { struct drm_property_enum *prop_enum; - if (!(property-flags DRM_MODE_PROP_ENUM)) + if (!(property-flags (DRM_MODE_PROP_ENUM | DRM_MODE_PROP_BITMASK))) + return -EINVAL; + + /* +* Bitmask enum properties have the additional constraint of values +* from 0 to 63 +*/ + if ((property-flags DRM_MODE_PROP_BITMASK) (value 63)) return -EINVAL; if (!list_empty(property-enum_blob_list)) { @@ -2875,7 +2910,7 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev, } property = obj_to_property(obj); - if (property-flags DRM_MODE_PROP_ENUM) { + if (property-flags (DRM_MODE_PROP_ENUM | DRM_MODE_PROP_BITMASK)) { list_for_each_entry(prop_enum, property-enum_blob_list, head) enum_count++; } else if (property-flags DRM_MODE_PROP_BLOB) { @@ -2900,7 +2935,7 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev, } out_resp-count_values = value_count; - if (property-flags DRM_MODE_PROP_ENUM) { + if (property-flags (DRM_MODE_PROP_ENUM | DRM_MODE_PROP_BITMASK)) { if ((out_resp-count_enum_blobs = enum_count) enum_count) { copied = 0; enum_ptr = (struct drm_mode_property_enum __user *)(unsigned long)out_resp-enum_blob_ptr; @@ -3055,6 +3090,12 @@ static bool drm_property_change_is_valid(struct drm_property *property, if (value property-values[0] || value property-values[1]) return false; return true; + } else if (property-flags DRM_MODE_PROP_BITMASK) { + int i; + __u64 valid_mask = 0; + for (i = 0; i property-num_values; i++) + valid_mask |= (1LL property-values[i]); + return !(value ~valid_mask); } else { int i; for (i = 0; i property-num_values; i++) diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index e194c78..9b53c14 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -940,6 +940,10 @@ extern struct drm_property *drm_property_create_enum(struct drm_device *dev, int const char *name, const struct drm_prop_enum_list *props, int num_values); +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); struct drm_property *drm_property_create_range(struct drm_device *dev, int flags,
[PATCH 1/2] drm: add bitmask property type
2012/5/16 Rob Clark : > From: Rob Clark > > A bitmask property is similar to an enum. ?The enum value is a bit > position (0-63), and valid property values consist of a mask of > zero or more of (1 << enum_val[n]). > > Signed-off-by: Rob Clark "int num_values" appears after column 80 in 2 places Reviewed-by: Paulo Zanoni > --- > ?drivers/gpu/drm/drm_crtc.c | ? 46 > +--- > ?include/drm/drm_crtc.h ? ? | ? ?3 +++ > ?include/drm/drm_mode.h ? ? | ? ?1 + > ?3 files changed, 47 insertions(+), 3 deletions(-) > > diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c > index 75661c8..022873e 100644 > --- a/drivers/gpu/drm/drm_crtc.c > +++ b/drivers/gpu/drm/drm_crtc.c > @@ -2707,6 +2707,33 @@ struct drm_property *drm_property_create_enum(struct > drm_device *dev, int flags, > ?} > ?EXPORT_SYMBOL(drm_property_create_enum); > > +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) > +{ > + ? ? ? struct drm_property *property; > + ? ? ? int i, ret; > + > + ? ? ? flags |= DRM_MODE_PROP_BITMASK; > + > + ? ? ? property = drm_property_create(dev, flags, name, num_values); > + ? ? ? if (!property) > + ? ? ? ? ? ? ? return NULL; > + > + ? ? ? for (i = 0; i < num_values; i++) { > + ? ? ? ? ? ? ? ret = drm_property_add_enum(property, i, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? props[i].type, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? props[i].name); > + ? ? ? ? ? ? ? if (ret) { > + ? ? ? ? ? ? ? ? ? ? ? drm_property_destroy(dev, property); > + ? ? ? ? ? ? ? ? ? ? ? return NULL; > + ? ? ? ? ? ? ? } > + ? ? ? } > + > + ? ? ? return property; > +} > +EXPORT_SYMBOL(drm_property_create_bitmask); > + > ?struct drm_property *drm_property_create_range(struct drm_device *dev, int > flags, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? const char *name, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? uint64_t min, uint64_t max) > @@ -2731,7 +2758,14 @@ int drm_property_add_enum(struct drm_property > *property, int index, > ?{ > ? ? ? ?struct drm_property_enum *prop_enum; > > - ? ? ? if (!(property->flags & DRM_MODE_PROP_ENUM)) > + ? ? ? if (!(property->flags & (DRM_MODE_PROP_ENUM | DRM_MODE_PROP_BITMASK))) > + ? ? ? ? ? ? ? return -EINVAL; > + > + ? ? ? /* > + ? ? ? ?* Bitmask enum properties have the additional constraint of values > + ? ? ? ?* from 0 to 63 > + ? ? ? ?*/ > + ? ? ? if ((property->flags & DRM_MODE_PROP_BITMASK) && (value > 63)) > ? ? ? ? ? ? ? ?return -EINVAL; > > ? ? ? ?if (!list_empty(>enum_blob_list)) { > @@ -2875,7 +2909,7 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev, > ? ? ? ?} > ? ? ? ?property = obj_to_property(obj); > > - ? ? ? if (property->flags & DRM_MODE_PROP_ENUM) { > + ? ? ? if (property->flags & (DRM_MODE_PROP_ENUM | DRM_MODE_PROP_BITMASK)) { > ? ? ? ? ? ? ? ?list_for_each_entry(prop_enum, >enum_blob_list, head) > ? ? ? ? ? ? ? ? ? ? ? ?enum_count++; > ? ? ? ?} else if (property->flags & DRM_MODE_PROP_BLOB) { > @@ -2900,7 +2934,7 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev, > ? ? ? ?} > ? ? ? ?out_resp->count_values = value_count; > > - ? ? ? if (property->flags & DRM_MODE_PROP_ENUM) { > + ? ? ? if (property->flags & (DRM_MODE_PROP_ENUM | DRM_MODE_PROP_BITMASK)) { > ? ? ? ? ? ? ? ?if ((out_resp->count_enum_blobs >= enum_count) && enum_count) { > ? ? ? ? ? ? ? ? ? ? ? ?copied = 0; > ? ? ? ? ? ? ? ? ? ? ? ?enum_ptr = (struct drm_mode_property_enum __user > *)(unsigned long)out_resp->enum_blob_ptr; > @@ -3055,6 +3089,12 @@ static bool drm_property_change_is_valid(struct > drm_property *property, > ? ? ? ? ? ? ? ?if (value < property->values[0] || value > property->values[1]) > ? ? ? ? ? ? ? ? ? ? ? ?return false; > ? ? ? ? ? ? ? ?return true; > + ? ? ? } else if (property->flags & DRM_MODE_PROP_BITMASK) { > + ? ? ? ? ? ? ? int i; > + ? ? ? ? ? ? ? __u64 valid_mask = 0; > + ? ? ? ? ? ? ? for (i = 0; i < property->num_values; i++) > + ? ? ? ? ? ? ? ? ? ? ? valid_mask |= (1LL << property->values[i]); > + ? ? ? ? ? ? ? return !(value & ~valid_mask); > ? ? ? ?} else { > ? ? ? ? ? ? ? ?int i; > ? ? ? ? ? ? ? ?for (i = 0; i < property->num_values; i++) > diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h > index e194c78..39e3e1c 100644 > --- a/include/drm/drm_crtc.h > +++ b/include/drm/drm_crtc.h > @@ -940,6 +940,9 @@ extern struct drm_property > *drm_property_create_enum(struct drm_device *dev, int > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? const char *name, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? const struct drm_prop_enum_list > *props, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? int num_values); > +struct drm_property *drm_property_create_bitmask(struct drm_device *dev, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?int flags, const char *name, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?const struct drm_prop_enum_list > *props, int
[PATCH 1/2] drm: add bitmask property type
From: Rob ClarkA bitmask property is similar to an enum. The enum value is a bit position (0-63), and valid property values consist of a mask of zero or more of (1 << enum_val[n]). Signed-off-by: Rob Clark --- drivers/gpu/drm/drm_crtc.c | 46 +--- include/drm/drm_crtc.h |3 +++ include/drm/drm_mode.h |1 + 3 files changed, 47 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 75661c8..022873e 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -2707,6 +2707,33 @@ struct drm_property *drm_property_create_enum(struct drm_device *dev, int flags, } EXPORT_SYMBOL(drm_property_create_enum); +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) +{ + struct drm_property *property; + int i, ret; + + flags |= DRM_MODE_PROP_BITMASK; + + property = drm_property_create(dev, flags, name, num_values); + if (!property) + return NULL; + + for (i = 0; i < num_values; i++) { + ret = drm_property_add_enum(property, i, + props[i].type, + props[i].name); + if (ret) { + drm_property_destroy(dev, property); + return NULL; + } + } + + return property; +} +EXPORT_SYMBOL(drm_property_create_bitmask); + struct drm_property *drm_property_create_range(struct drm_device *dev, int flags, const char *name, uint64_t min, uint64_t max) @@ -2731,7 +2758,14 @@ int drm_property_add_enum(struct drm_property *property, int index, { struct drm_property_enum *prop_enum; - if (!(property->flags & DRM_MODE_PROP_ENUM)) + if (!(property->flags & (DRM_MODE_PROP_ENUM | DRM_MODE_PROP_BITMASK))) + return -EINVAL; + + /* +* Bitmask enum properties have the additional constraint of values +* from 0 to 63 +*/ + if ((property->flags & DRM_MODE_PROP_BITMASK) && (value > 63)) return -EINVAL; if (!list_empty(>enum_blob_list)) { @@ -2875,7 +2909,7 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev, } property = obj_to_property(obj); - if (property->flags & DRM_MODE_PROP_ENUM) { + if (property->flags & (DRM_MODE_PROP_ENUM | DRM_MODE_PROP_BITMASK)) { list_for_each_entry(prop_enum, >enum_blob_list, head) enum_count++; } else if (property->flags & DRM_MODE_PROP_BLOB) { @@ -2900,7 +2934,7 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev, } out_resp->count_values = value_count; - if (property->flags & DRM_MODE_PROP_ENUM) { + if (property->flags & (DRM_MODE_PROP_ENUM | DRM_MODE_PROP_BITMASK)) { if ((out_resp->count_enum_blobs >= enum_count) && enum_count) { copied = 0; enum_ptr = (struct drm_mode_property_enum __user *)(unsigned long)out_resp->enum_blob_ptr; @@ -3055,6 +3089,12 @@ static bool drm_property_change_is_valid(struct drm_property *property, if (value < property->values[0] || value > property->values[1]) return false; return true; + } else if (property->flags & DRM_MODE_PROP_BITMASK) { + int i; + __u64 valid_mask = 0; + for (i = 0; i < property->num_values; i++) + valid_mask |= (1LL << property->values[i]); + return !(value & ~valid_mask); } else { int i; for (i = 0; i < property->num_values; i++) diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index e194c78..39e3e1c 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -940,6 +940,9 @@ extern struct drm_property *drm_property_create_enum(struct drm_device *dev, int const char *name, const struct drm_prop_enum_list *props, int num_values); +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); struct drm_property *drm_property_create_range(struct drm_device *dev, int flags, const char *name, uint64_t min, uint64_t max); diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h index
[PATCH 1/2] drm: add bitmask property type
From: Rob Clark r...@ti.com A bitmask property is similar to an enum. The enum value is a bit position (0-63), and valid property values consist of a mask of zero or more of (1 enum_val[n]). Signed-off-by: Rob Clark r...@ti.com --- drivers/gpu/drm/drm_crtc.c | 46 +--- include/drm/drm_crtc.h |3 +++ include/drm/drm_mode.h |1 + 3 files changed, 47 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 75661c8..022873e 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -2707,6 +2707,33 @@ struct drm_property *drm_property_create_enum(struct drm_device *dev, int flags, } EXPORT_SYMBOL(drm_property_create_enum); +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) +{ + struct drm_property *property; + int i, ret; + + flags |= DRM_MODE_PROP_BITMASK; + + property = drm_property_create(dev, flags, name, num_values); + if (!property) + return NULL; + + for (i = 0; i num_values; i++) { + ret = drm_property_add_enum(property, i, + props[i].type, + props[i].name); + if (ret) { + drm_property_destroy(dev, property); + return NULL; + } + } + + return property; +} +EXPORT_SYMBOL(drm_property_create_bitmask); + struct drm_property *drm_property_create_range(struct drm_device *dev, int flags, const char *name, uint64_t min, uint64_t max) @@ -2731,7 +2758,14 @@ int drm_property_add_enum(struct drm_property *property, int index, { struct drm_property_enum *prop_enum; - if (!(property-flags DRM_MODE_PROP_ENUM)) + if (!(property-flags (DRM_MODE_PROP_ENUM | DRM_MODE_PROP_BITMASK))) + return -EINVAL; + + /* +* Bitmask enum properties have the additional constraint of values +* from 0 to 63 +*/ + if ((property-flags DRM_MODE_PROP_BITMASK) (value 63)) return -EINVAL; if (!list_empty(property-enum_blob_list)) { @@ -2875,7 +2909,7 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev, } property = obj_to_property(obj); - if (property-flags DRM_MODE_PROP_ENUM) { + if (property-flags (DRM_MODE_PROP_ENUM | DRM_MODE_PROP_BITMASK)) { list_for_each_entry(prop_enum, property-enum_blob_list, head) enum_count++; } else if (property-flags DRM_MODE_PROP_BLOB) { @@ -2900,7 +2934,7 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev, } out_resp-count_values = value_count; - if (property-flags DRM_MODE_PROP_ENUM) { + if (property-flags (DRM_MODE_PROP_ENUM | DRM_MODE_PROP_BITMASK)) { if ((out_resp-count_enum_blobs = enum_count) enum_count) { copied = 0; enum_ptr = (struct drm_mode_property_enum __user *)(unsigned long)out_resp-enum_blob_ptr; @@ -3055,6 +3089,12 @@ static bool drm_property_change_is_valid(struct drm_property *property, if (value property-values[0] || value property-values[1]) return false; return true; + } else if (property-flags DRM_MODE_PROP_BITMASK) { + int i; + __u64 valid_mask = 0; + for (i = 0; i property-num_values; i++) + valid_mask |= (1LL property-values[i]); + return !(value ~valid_mask); } else { int i; for (i = 0; i property-num_values; i++) diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index e194c78..39e3e1c 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -940,6 +940,9 @@ extern struct drm_property *drm_property_create_enum(struct drm_device *dev, int const char *name, const struct drm_prop_enum_list *props, int num_values); +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); struct drm_property *drm_property_create_range(struct drm_device *dev, int flags, const char *name, uint64_t min, uint64_t max); diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h index 326f2be..5581980 100644
Re: [PATCH 1/2] drm: add bitmask property type
2012/5/16 Rob Clark rob.cl...@linaro.org: From: Rob Clark r...@ti.com A bitmask property is similar to an enum. The enum value is a bit position (0-63), and valid property values consist of a mask of zero or more of (1 enum_val[n]). Signed-off-by: Rob Clark r...@ti.com Bikeshedding int num_values appears after column 80 in 2 places /Bikeshedding Reviewed-by: Paulo Zanoni paulo.r.zan...@intel.com --- drivers/gpu/drm/drm_crtc.c | 46 +--- include/drm/drm_crtc.h | 3 +++ include/drm/drm_mode.h | 1 + 3 files changed, 47 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 75661c8..022873e 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -2707,6 +2707,33 @@ struct drm_property *drm_property_create_enum(struct drm_device *dev, int flags, } EXPORT_SYMBOL(drm_property_create_enum); +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) +{ + struct drm_property *property; + int i, ret; + + flags |= DRM_MODE_PROP_BITMASK; + + property = drm_property_create(dev, flags, name, num_values); + if (!property) + return NULL; + + for (i = 0; i num_values; i++) { + ret = drm_property_add_enum(property, i, + props[i].type, + props[i].name); + if (ret) { + drm_property_destroy(dev, property); + return NULL; + } + } + + return property; +} +EXPORT_SYMBOL(drm_property_create_bitmask); + struct drm_property *drm_property_create_range(struct drm_device *dev, int flags, const char *name, uint64_t min, uint64_t max) @@ -2731,7 +2758,14 @@ int drm_property_add_enum(struct drm_property *property, int index, { struct drm_property_enum *prop_enum; - if (!(property-flags DRM_MODE_PROP_ENUM)) + if (!(property-flags (DRM_MODE_PROP_ENUM | DRM_MODE_PROP_BITMASK))) + return -EINVAL; + + /* + * Bitmask enum properties have the additional constraint of values + * from 0 to 63 + */ + if ((property-flags DRM_MODE_PROP_BITMASK) (value 63)) return -EINVAL; if (!list_empty(property-enum_blob_list)) { @@ -2875,7 +2909,7 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev, } property = obj_to_property(obj); - if (property-flags DRM_MODE_PROP_ENUM) { + if (property-flags (DRM_MODE_PROP_ENUM | DRM_MODE_PROP_BITMASK)) { list_for_each_entry(prop_enum, property-enum_blob_list, head) enum_count++; } else if (property-flags DRM_MODE_PROP_BLOB) { @@ -2900,7 +2934,7 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev, } out_resp-count_values = value_count; - if (property-flags DRM_MODE_PROP_ENUM) { + if (property-flags (DRM_MODE_PROP_ENUM | DRM_MODE_PROP_BITMASK)) { if ((out_resp-count_enum_blobs = enum_count) enum_count) { copied = 0; enum_ptr = (struct drm_mode_property_enum __user *)(unsigned long)out_resp-enum_blob_ptr; @@ -3055,6 +3089,12 @@ static bool drm_property_change_is_valid(struct drm_property *property, if (value property-values[0] || value property-values[1]) return false; return true; + } else if (property-flags DRM_MODE_PROP_BITMASK) { + int i; + __u64 valid_mask = 0; + for (i = 0; i property-num_values; i++) + valid_mask |= (1LL property-values[i]); + return !(value ~valid_mask); } else { int i; for (i = 0; i property-num_values; i++) diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index e194c78..39e3e1c 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -940,6 +940,9 @@ extern struct drm_property *drm_property_create_enum(struct drm_device *dev, int const char *name, const struct drm_prop_enum_list *props, int num_values); +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); struct drm_property