diff options
-rw-r--r-- | drivers/gpu/drm/drm_crtc.c | 47 | ||||
-rw-r--r-- | include/drm/drm_crtc.h | 4 | ||||
-rw-r--r-- | 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 6cb47d9f0ca2..e3135c7ee87a 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c | |||
@@ -2748,6 +2748,34 @@ struct drm_property *drm_property_create_enum(struct drm_device *dev, int flags, | |||
2748 | } | 2748 | } |
2749 | EXPORT_SYMBOL(drm_property_create_enum); | 2749 | EXPORT_SYMBOL(drm_property_create_enum); |
2750 | 2750 | ||
2751 | struct drm_property *drm_property_create_bitmask(struct drm_device *dev, | ||
2752 | int flags, const char *name, | ||
2753 | const struct drm_prop_enum_list *props, | ||
2754 | int num_values) | ||
2755 | { | ||
2756 | struct drm_property *property; | ||
2757 | int i, ret; | ||
2758 | |||
2759 | flags |= DRM_MODE_PROP_BITMASK; | ||
2760 | |||
2761 | property = drm_property_create(dev, flags, name, num_values); | ||
2762 | if (!property) | ||
2763 | return NULL; | ||
2764 | |||
2765 | for (i = 0; i < num_values; i++) { | ||
2766 | ret = drm_property_add_enum(property, i, | ||
2767 | props[i].type, | ||
2768 | props[i].name); | ||
2769 | if (ret) { | ||
2770 | drm_property_destroy(dev, property); | ||
2771 | return NULL; | ||
2772 | } | ||
2773 | } | ||
2774 | |||
2775 | return property; | ||
2776 | } | ||
2777 | EXPORT_SYMBOL(drm_property_create_bitmask); | ||
2778 | |||
2751 | struct drm_property *drm_property_create_range(struct drm_device *dev, int flags, | 2779 | struct drm_property *drm_property_create_range(struct drm_device *dev, int flags, |
2752 | const char *name, | 2780 | const char *name, |
2753 | uint64_t min, uint64_t max) | 2781 | uint64_t min, uint64_t max) |
@@ -2772,7 +2800,14 @@ int drm_property_add_enum(struct drm_property *property, int index, | |||
2772 | { | 2800 | { |
2773 | struct drm_property_enum *prop_enum; | 2801 | struct drm_property_enum *prop_enum; |
2774 | 2802 | ||
2775 | if (!(property->flags & DRM_MODE_PROP_ENUM)) | 2803 | if (!(property->flags & (DRM_MODE_PROP_ENUM | DRM_MODE_PROP_BITMASK))) |
2804 | return -EINVAL; | ||
2805 | |||
2806 | /* | ||
2807 | * Bitmask enum properties have the additional constraint of values | ||
2808 | * from 0 to 63 | ||
2809 | */ | ||
2810 | if ((property->flags & DRM_MODE_PROP_BITMASK) && (value > 63)) | ||
2776 | return -EINVAL; | 2811 | return -EINVAL; |
2777 | 2812 | ||
2778 | if (!list_empty(&property->enum_blob_list)) { | 2813 | if (!list_empty(&property->enum_blob_list)) { |
@@ -2918,7 +2953,7 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev, | |||
2918 | } | 2953 | } |
2919 | property = obj_to_property(obj); | 2954 | property = obj_to_property(obj); |
2920 | 2955 | ||
2921 | if (property->flags & DRM_MODE_PROP_ENUM) { | 2956 | if (property->flags & (DRM_MODE_PROP_ENUM | DRM_MODE_PROP_BITMASK)) { |
2922 | list_for_each_entry(prop_enum, &property->enum_blob_list, head) | 2957 | list_for_each_entry(prop_enum, &property->enum_blob_list, head) |
2923 | enum_count++; | 2958 | enum_count++; |
2924 | } else if (property->flags & DRM_MODE_PROP_BLOB) { | 2959 | } else if (property->flags & DRM_MODE_PROP_BLOB) { |
@@ -2943,7 +2978,7 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev, | |||
2943 | } | 2978 | } |
2944 | out_resp->count_values = value_count; | 2979 | out_resp->count_values = value_count; |
2945 | 2980 | ||
2946 | if (property->flags & DRM_MODE_PROP_ENUM) { | 2981 | if (property->flags & (DRM_MODE_PROP_ENUM | DRM_MODE_PROP_BITMASK)) { |
2947 | if ((out_resp->count_enum_blobs >= enum_count) && enum_count) { | 2982 | if ((out_resp->count_enum_blobs >= enum_count) && enum_count) { |
2948 | copied = 0; | 2983 | copied = 0; |
2949 | enum_ptr = (struct drm_mode_property_enum __user *)(unsigned long)out_resp->enum_blob_ptr; | 2984 | enum_ptr = (struct drm_mode_property_enum __user *)(unsigned long)out_resp->enum_blob_ptr; |
@@ -3098,6 +3133,12 @@ static bool drm_property_change_is_valid(struct drm_property *property, | |||
3098 | if (value < property->values[0] || value > property->values[1]) | 3133 | if (value < property->values[0] || value > property->values[1]) |
3099 | return false; | 3134 | return false; |
3100 | return true; | 3135 | return true; |
3136 | } else if (property->flags & DRM_MODE_PROP_BITMASK) { | ||
3137 | int i; | ||
3138 | __u64 valid_mask = 0; | ||
3139 | for (i = 0; i < property->num_values; i++) | ||
3140 | valid_mask |= (1ULL << property->values[i]); | ||
3141 | return !(value & ~valid_mask); | ||
3101 | } else { | 3142 | } else { |
3102 | int i; | 3143 | int i; |
3103 | for (i = 0; i < property->num_values; i++) | 3144 | for (i = 0; i < property->num_values; i++) |
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index b88b28f45f9e..9b33629e654c 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h | |||
@@ -933,6 +933,10 @@ extern struct drm_property *drm_property_create_enum(struct drm_device *dev, int | |||
933 | const char *name, | 933 | const char *name, |
934 | const struct drm_prop_enum_list *props, | 934 | const struct drm_prop_enum_list *props, |
935 | int num_values); | 935 | int num_values); |
936 | struct drm_property *drm_property_create_bitmask(struct drm_device *dev, | ||
937 | int flags, const char *name, | ||
938 | const struct drm_prop_enum_list *props, | ||
939 | int num_values); | ||
936 | struct drm_property *drm_property_create_range(struct drm_device *dev, int flags, | 940 | struct drm_property *drm_property_create_range(struct drm_device *dev, int flags, |
937 | const char *name, | 941 | const char *name, |
938 | uint64_t min, uint64_t max); | 942 | uint64_t min, uint64_t max); |
diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h index 326f2be0d497..5581980b14f6 100644 --- a/include/drm/drm_mode.h +++ b/include/drm/drm_mode.h | |||
@@ -230,6 +230,7 @@ struct drm_mode_get_connector { | |||
230 | #define DRM_MODE_PROP_IMMUTABLE (1<<2) | 230 | #define DRM_MODE_PROP_IMMUTABLE (1<<2) |
231 | #define DRM_MODE_PROP_ENUM (1<<3) /* enumerated type with text strings */ | 231 | #define DRM_MODE_PROP_ENUM (1<<3) /* enumerated type with text strings */ |
232 | #define DRM_MODE_PROP_BLOB (1<<4) | 232 | #define DRM_MODE_PROP_BLOB (1<<4) |
233 | #define DRM_MODE_PROP_BITMASK (1<<5) /* bitmask of enumerated types */ | ||
233 | 234 | ||
234 | struct drm_mode_property_enum { | 235 | struct drm_mode_property_enum { |
235 | __u64 value; | 236 | __u64 value; |