[PATCH 16/20] drm: store connector properties in list

Sascha Hauer s.hauer at pengutronix.de
Wed Feb 1 02:38:34 PST 2012


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.hauer at 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



More information about the dri-devel mailing list