Skip to content

Commit 5ea22f2

Browse files
robclarkairlied
authored andcommitted
drm: add extended property types
If we continue to use bitmask for type, we will quickly run out of room to add new types. Split this up so existing part of bitmask range continues to function as before, but reserve a chunk of the remaining space for an integer type-id. Wrap this all up in some type-check helpers to keep the backwards-compat uglyness contained. Signed-off-by: Rob Clark <robdclark@gmail.com> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
1 parent a2b34e2 commit 5ea22f2

File tree

3 files changed

+47
-9
lines changed

3 files changed

+47
-9
lines changed

drivers/gpu/drm/drm_crtc.c

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3094,6 +3094,9 @@ struct drm_property *drm_property_create(struct drm_device *dev, int flags,
30943094
}
30953095

30963096
list_add_tail(&property->head, &dev->mode_config.property_list);
3097+
3098+
WARN_ON(!drm_property_type_valid(property));
3099+
30973100
return property;
30983101
fail:
30993102
kfree(property->values);
@@ -3251,14 +3254,16 @@ int drm_property_add_enum(struct drm_property *property, int index,
32513254
{
32523255
struct drm_property_enum *prop_enum;
32533256

3254-
if (!(property->flags & (DRM_MODE_PROP_ENUM | DRM_MODE_PROP_BITMASK)))
3257+
if (!(drm_property_type_is(property, DRM_MODE_PROP_ENUM) ||
3258+
drm_property_type_is(property, DRM_MODE_PROP_BITMASK)))
32553259
return -EINVAL;
32563260

32573261
/*
32583262
* Bitmask enum properties have the additional constraint of values
32593263
* from 0 to 63
32603264
*/
3261-
if ((property->flags & DRM_MODE_PROP_BITMASK) && (value > 63))
3265+
if (drm_property_type_is(property, DRM_MODE_PROP_BITMASK) &&
3266+
(value > 63))
32623267
return -EINVAL;
32633268

32643269
if (!list_empty(&property->enum_blob_list)) {
@@ -3439,10 +3444,11 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev,
34393444
goto done;
34403445
}
34413446

3442-
if (property->flags & (DRM_MODE_PROP_ENUM | DRM_MODE_PROP_BITMASK)) {
3447+
if (drm_property_type_is(property, DRM_MODE_PROP_ENUM) ||
3448+
drm_property_type_is(property, DRM_MODE_PROP_BITMASK)) {
34433449
list_for_each_entry(prop_enum, &property->enum_blob_list, head)
34443450
enum_count++;
3445-
} else if (property->flags & DRM_MODE_PROP_BLOB) {
3451+
} else if (drm_property_type_is(property, DRM_MODE_PROP_BLOB)) {
34463452
list_for_each_entry(prop_blob, &property->enum_blob_list, head)
34473453
blob_count++;
34483454
}
@@ -3464,7 +3470,8 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev,
34643470
}
34653471
out_resp->count_values = value_count;
34663472

3467-
if (property->flags & (DRM_MODE_PROP_ENUM | DRM_MODE_PROP_BITMASK)) {
3473+
if (drm_property_type_is(property, DRM_MODE_PROP_ENUM) ||
3474+
drm_property_type_is(property, DRM_MODE_PROP_BITMASK)) {
34683475
if ((out_resp->count_enum_blobs >= enum_count) && enum_count) {
34693476
copied = 0;
34703477
enum_ptr = (struct drm_mode_property_enum __user *)(unsigned long)out_resp->enum_blob_ptr;
@@ -3486,7 +3493,7 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev,
34863493
out_resp->count_enum_blobs = enum_count;
34873494
}
34883495

3489-
if (property->flags & DRM_MODE_PROP_BLOB) {
3496+
if (drm_property_type_is(property, DRM_MODE_PROP_BLOB)) {
34903497
if ((out_resp->count_enum_blobs >= blob_count) && blob_count) {
34913498
copied = 0;
34923499
blob_id_ptr = (uint32_t __user *)(unsigned long)out_resp->enum_blob_ptr;
@@ -3640,17 +3647,18 @@ static bool drm_property_change_is_valid(struct drm_property *property,
36403647
{
36413648
if (property->flags & DRM_MODE_PROP_IMMUTABLE)
36423649
return false;
3643-
if (property->flags & DRM_MODE_PROP_RANGE) {
3650+
3651+
if (drm_property_type_is(property, DRM_MODE_PROP_RANGE)) {
36443652
if (value < property->values[0] || value > property->values[1])
36453653
return false;
36463654
return true;
3647-
} else if (property->flags & DRM_MODE_PROP_BITMASK) {
3655+
} else if (drm_property_type_is(property, DRM_MODE_PROP_BITMASK)) {
36483656
int i;
36493657
uint64_t valid_mask = 0;
36503658
for (i = 0; i < property->num_values; i++)
36513659
valid_mask |= (1ULL << property->values[i]);
36523660
return !(value & ~valid_mask);
3653-
} else if (property->flags & DRM_MODE_PROP_BLOB) {
3661+
} else if (drm_property_type_is(property, DRM_MODE_PROP_BLOB)) {
36543662
/* Only the driver knows */
36553663
return true;
36563664
} else {

include/drm/drm_crtc.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -930,6 +930,23 @@ extern void drm_mode_config_cleanup(struct drm_device *dev);
930930

931931
extern int drm_mode_connector_update_edid_property(struct drm_connector *connector,
932932
struct edid *edid);
933+
934+
static inline bool drm_property_type_is(struct drm_property *property,
935+
uint32_t type)
936+
{
937+
/* instanceof for props.. handles extended type vs original types: */
938+
if (property->flags & DRM_MODE_PROP_EXTENDED_TYPE)
939+
return (property->flags & DRM_MODE_PROP_EXTENDED_TYPE) == type;
940+
return property->flags & type;
941+
}
942+
943+
static inline bool drm_property_type_valid(struct drm_property *property)
944+
{
945+
if (property->flags & DRM_MODE_PROP_EXTENDED_TYPE)
946+
return !(property->flags & DRM_MODE_PROP_LEGACY_TYPE);
947+
return !!(property->flags & DRM_MODE_PROP_LEGACY_TYPE);
948+
}
949+
933950
extern int drm_object_property_set_value(struct drm_mode_object *obj,
934951
struct drm_property *property,
935952
uint64_t val);

include/uapi/drm/drm_mode.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,19 @@ struct drm_mode_get_connector {
252252
#define DRM_MODE_PROP_BLOB (1<<4)
253253
#define DRM_MODE_PROP_BITMASK (1<<5) /* bitmask of enumerated types */
254254

255+
/* non-extended types: legacy bitmask, one bit per type: */
256+
#define DRM_MODE_PROP_LEGACY_TYPE ( \
257+
DRM_MODE_PROP_RANGE | \
258+
DRM_MODE_PROP_ENUM | \
259+
DRM_MODE_PROP_BLOB | \
260+
DRM_MODE_PROP_BITMASK)
261+
262+
/* extended-types: rather than continue to consume a bit per type,
263+
* grab a chunk of the bits to use as integer type id.
264+
*/
265+
#define DRM_MODE_PROP_EXTENDED_TYPE 0x0000ffc0
266+
#define DRM_MODE_PROP_TYPE(n) ((n) << 6)
267+
255268
struct drm_mode_property_enum {
256269
__u64 value;
257270
char name[DRM_PROP_NAME_LEN];

0 commit comments

Comments
 (0)