Storing the properties associated to a connector in a
list allows us to drop the current limitation on a
maximum number of properties per connector.

Signed-off-by: Sascha Hauer <s.ha...@pengutronix.de>
---
 drivers/gpu/drm/drm_crtc.c |  109 ++++++++++++++++++++-----------------------
 include/drm/drm_crtc.h     |    5 +-
 2 files changed, 53 insertions(+), 61 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 1ebcedf..b815e69 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -140,6 +140,12 @@ struct drm_conn_prop_enum_list {
        int count;
 };
 
+struct drm_connector_property {
+       struct drm_property *base;
+       uint64_t val;
+       struct list_head list;
+};
+
 /*
  * Connector and encoder types.
  */
@@ -470,6 +476,7 @@ void drm_connector_init(struct drm_device *dev,
        INIT_LIST_HEAD(&connector->user_modes);
        INIT_LIST_HEAD(&connector->probed_modes);
        INIT_LIST_HEAD(&connector->modes);
+       INIT_LIST_HEAD(&connector->properties);
        connector->edid_blob_ptr = NULL;
 
        list_add_tail(&connector->head, &dev->mode_config.connector_list);
@@ -954,6 +961,7 @@ void drm_mode_config_cleanup(struct drm_device *dev)
        struct drm_framebuffer *fb, *fbt;
        struct drm_property *property, *pt;
        struct drm_plane *plane, *plt;
+       struct drm_connector_property *cprop, *cpt;
 
        list_for_each_entry_safe(encoder, enct, &dev->mode_config.encoder_list,
                                 head) {
@@ -962,6 +970,10 @@ void drm_mode_config_cleanup(struct drm_device *dev)
 
        list_for_each_entry_safe(connector, ot,
                                 &dev->mode_config.connector_list, head) {
+               list_for_each_entry_safe(cprop, cpt, &connector->properties, 
list) {
+                       list_del(&cprop->list);
+                       kfree(cprop);
+               }
                connector->funcs->destroy(connector);
        }
 
@@ -1324,6 +1336,7 @@ int drm_mode_getconnector(struct drm_device *dev, void 
*data,
        struct drm_mode_object *obj;
        struct drm_connector *connector;
        struct drm_display_mode *mode;
+       struct drm_connector_property *cprop;
        int mode_count = 0;
        int props_count = 0;
        int encoders_count = 0;
@@ -1353,11 +1366,8 @@ int drm_mode_getconnector(struct drm_device *dev, void 
*data,
        }
        connector = obj_to_connector(obj);
 
-       for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) {
-               if (connector->property_ids[i] != 0) {
-                       props_count++;
-               }
-       }
+       list_for_each_entry(cprop, &connector->properties, list)
+               props_count++;
 
        for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
                if (connector->encoder_ids[i] != 0) {
@@ -1410,21 +1420,17 @@ int drm_mode_getconnector(struct drm_device *dev, void 
*data,
                copied = 0;
                prop_ptr = (uint32_t __user *)(unsigned 
long)(out_resp->props_ptr);
                prop_values = (uint64_t __user *)(unsigned 
long)(out_resp->prop_values_ptr);
-               for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) {
-                       if (connector->property_ids[i] != 0) {
-                               if (put_user(connector->property_ids[i],
-                                            prop_ptr + copied)) {
-                                       ret = -EFAULT;
-                                       goto out;
-                               }
+               list_for_each_entry(cprop, &connector->properties, list) {
+                       if (put_user(cprop->base->base.id, prop_ptr + copied)) {
+                               ret = -EFAULT;
+                               goto out;
+                       }
 
-                               if (put_user(connector->property_values[i],
-                                            prop_values + copied)) {
-                                       ret = -EFAULT;
-                                       goto out;
-                               }
-                               copied++;
+                       if (put_user(cprop->val, prop_values + copied)) {
+                               ret = -EFAULT;
+                               goto out;
                        }
+                       copied++;
                }
        }
        out_resp->count_props = props_count;
@@ -2662,18 +2668,16 @@ EXPORT_SYMBOL(drm_property_destroy);
 int drm_connector_attach_property(struct drm_connector *connector,
                               struct drm_property *property, uint64_t init_val)
 {
-       int i;
+       struct drm_connector_property *cprop;
 
-       for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) {
-               if (connector->property_ids[i] == 0) {
-                       connector->property_ids[i] = property->base.id;
-                       connector->property_values[i] = init_val;
-                       break;
-               }
-       }
+       cprop = kzalloc(sizeof(*cprop), GFP_KERNEL);
+       if (!cprop)
+               return -ENOMEM;
+
+       cprop->val = init_val;
+       cprop->base = property;
+       list_add_tail(&cprop->list, &connector->properties);
 
-       if (i == DRM_CONNECTOR_MAX_PROPERTY)
-               return -EINVAL;
        return 0;
 }
 EXPORT_SYMBOL(drm_connector_attach_property);
@@ -2681,36 +2685,32 @@ EXPORT_SYMBOL(drm_connector_attach_property);
 int drm_connector_property_set_value(struct drm_connector *connector,
                                  struct drm_property *property, uint64_t value)
 {
-       int i;
+       struct drm_connector_property *cprop;
 
-       for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) {
-               if (connector->property_ids[i] == property->base.id) {
-                       connector->property_values[i] = value;
-                       break;
+       list_for_each_entry(cprop, &connector->properties, list) {
+               if (cprop->base->base.id == property->base.id) {
+                       cprop->val = value;
+                       return 0;
                }
        }
 
-       if (i == DRM_CONNECTOR_MAX_PROPERTY)
-               return -EINVAL;
-       return 0;
+       return -EINVAL;
 }
 EXPORT_SYMBOL(drm_connector_property_set_value);
 
 int drm_connector_property_get_value(struct drm_connector *connector,
                                  struct drm_property *property, uint64_t *val)
 {
-       int i;
+       struct drm_connector_property *cprop;
 
-       for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) {
-               if (connector->property_ids[i] == property->base.id) {
-                       *val = connector->property_values[i];
-                       break;
+       list_for_each_entry(cprop, &connector->properties, list) {
+               if (cprop->base->base.id == property->base.id) {
+                       *val = cprop->val;
+                       return 0;
                }
        }
 
-       if (i == DRM_CONNECTOR_MAX_PROPERTY)
-               return -EINVAL;
-       return 0;
+       return -EINVAL;
 }
 EXPORT_SYMBOL(drm_connector_property_get_value);
 
@@ -2916,6 +2916,7 @@ int drm_mode_connector_property_set_ioctl(struct 
drm_device *dev,
        struct drm_mode_connector_set_property *out_resp = data;
        struct drm_mode_object *obj;
        struct drm_property *property;
+       struct drm_connector_property *cprop;
        struct drm_connector *connector;
        int ret = -EINVAL;
        int i;
@@ -2931,20 +2932,12 @@ int drm_mode_connector_property_set_ioctl(struct 
drm_device *dev,
        }
        connector = obj_to_connector(obj);
 
-       for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) {
-               if (connector->property_ids[i] == out_resp->prop_id)
-                       break;
-       }
-
-       if (i == DRM_CONNECTOR_MAX_PROPERTY) {
-               goto out;
-       }
-
-       obj = drm_mode_object_find(dev, out_resp->prop_id, 
DRM_MODE_OBJECT_PROPERTY);
-       if (!obj) {
-               goto out;
-       }
-       property = obj_to_property(obj);
+       list_for_each_entry(cprop, &connector->properties, list)
+               if (cprop->base->base.id == out_resp->prop_id)
+                       goto found;
+       goto out;
+found:
+       property = cprop->base;
 
        if (property->flags & DRM_MODE_PROP_IMMUTABLE)
                goto out;
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index c03ad9a..40f2107 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -451,7 +451,6 @@ struct drm_encoder_funcs {
 };
 
 #define DRM_CONNECTOR_MAX_UMODES 16
-#define DRM_CONNECTOR_MAX_PROPERTY 16
 #define DRM_CONNECTOR_LEN 32
 #define DRM_CONNECTOR_MAX_ENCODER 3
 
@@ -565,8 +564,8 @@ struct drm_connector {
 
        struct list_head user_modes;
        struct drm_property_blob *edid_blob_ptr;
-       u32 property_ids[DRM_CONNECTOR_MAX_PROPERTY];
-       uint64_t property_values[DRM_CONNECTOR_MAX_PROPERTY];
+
+       struct list_head properties;
 
        uint8_t polled; /* DRM_CONNECTOR_POLL_* */
 
-- 
1.7.8.3

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to