Flag for range property types indicating that the value is a signed
integer rather than unsigned.  For range properties, the signed flag
will trigger use of signed integer comparisions, to handle negative
values properly.
---
 drivers/gpu/drm/drm_crtc.c  | 15 +++++++++++----
 include/drm/drm_crtc.h      |  9 +++++++++
 include/uapi/drm/drm_mode.h |  2 ++
 3 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 4d33816..61ce72d 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -3263,11 +3263,18 @@ EXPORT_SYMBOL(drm_mode_connector_update_edid_property);
 static bool drm_property_change_is_valid(struct drm_property *property,
                                         uint64_t value)
 {
-       if (property->flags & DRM_MODE_PROP_IMMUTABLE)
+       if (property->flags & DRM_MODE_PROP_IMMUTABLE) {
                return false;
-       if (property->flags & DRM_MODE_PROP_RANGE) {
-               if (value < property->values[0] || value > property->values[1])
-                       return false;
+       } else if (property->flags & DRM_MODE_PROP_RANGE) {
+               if (property->flags & DRM_MODE_PROP_SIGNED) {
+                       int64_t svalue = U642I64(value);
+                       if (svalue < U642I64(property->values[0]) ||
+                                       svalue > U642I64(property->values[1]))
+                               return false;
+               } else {
+                       if (value < property->values[0] || value > 
property->values[1])
+                               return false;
+               }
                return true;
        } else if (property->flags & DRM_MODE_PROP_BITMASK) {
                int i;
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 4141074..a9b9977 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -65,6 +65,15 @@ struct drm_object_properties {
        uint64_t values[DRM_OBJECT_MAX_PROPERTY];
 };

+static inline int64_t U642I64(uint64_t val)
+{
+       return (int64_t)*((int64_t *)&val);
+}
+static inline uint64_t I642U64(int64_t val)
+{
+       return (uint64_t)*((uint64_t *)&val);
+}
+
 /*
  * Note on terminology:  here, for brevity and convenience, we refer to 
connector
  * control chips as 'CRTCs'.  They can control any type of connector, VGA, 
LVDS,
diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
index 536897a..9fed70e 100644
--- a/include/uapi/drm/drm_mode.h
+++ b/include/uapi/drm/drm_mode.h
@@ -260,6 +260,8 @@ struct drm_mode_get_connector {
  * be changed dynamically, assuming the pixel format does not change.
  */
 #define DRM_MODE_PROP_DYNAMIC  (1<<24)
+/* Indicates that numeric property values are signed rather than unsigned: */
+#define DRM_MODE_PROP_SIGNED   (1<<25)

 struct drm_mode_property_enum {
        __u64 value;
-- 
1.8.4.2

Reply via email to