[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