diff mbox

drm: Add a generic function to change connector type/id of connector dynamically

Message ID 1264576567-11236-1-git-send-email-yakui.zhao@intel.com (mailing list archive)
State Rejected
Headers show

Commit Message

Zhao, Yakui Jan. 27, 2010, 7:16 a.m. UTC
None
diff mbox

Patch

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 5124401..a64e389 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -39,6 +39,11 @@  struct drm_prop_enum_list {
 	char *name;
 };
 
+struct connector_type_id {
+	struct list_head head;
+	int connector_type;
+	int connector_id;
+};
 /* Avoid boilerplate.  I'm tired of typing. */
 #define DRM_ENUM_NAME_FN(fnname, list)				\
 	char *fnname(int val)					\
@@ -443,6 +448,13 @@  void drm_connector_init(struct drm_device *dev,
 		     const struct drm_connector_funcs *funcs,
 		     int connector_type)
 {
+	struct connector_type_id *p_type_id = NULL;
+
+	p_type_id = kzalloc(sizeof(*p_type_id), GFP_KERNEL);
+
+	if (!p_type_id)
+		DRM_DEBUG_KMS("Can't allocate the memory\n");
+
 	mutex_lock(&dev->mode_config.mutex);
 
 	connector->dev = dev;
@@ -465,11 +477,73 @@  void drm_connector_init(struct drm_device *dev,
 	drm_connector_attach_property(connector,
 				      dev->mode_config.dpms_property, 0);
 
+	INIT_LIST_HEAD(&connector->connector_type_list);
+	if (p_type_id) {
+		p_type_id->connector_type = connector_type;
+		p_type_id->connector_id = connector->connector_type_id;
+		list_add_tail(&p_type_id->head,
+					&connector->connector_type_list);
+	}
 	mutex_unlock(&dev->mode_config.mutex);
 }
 EXPORT_SYMBOL(drm_connector_init);
 
 /**
+ * drm_rename_connector_type - Rename the connector type for one connector
+ * @connector: the connector to be named
+ * @target_type: the renamed target connector type
+ *
+ * Rename the connector type for one connector. Sometimes we will
+ * need get a new connector type id.
+ *
+ * RETURNS:
+ * Zero on success, errno on failure.
+ */
+
+int drm_rename_connector_type(struct drm_connector *connector,
+		     int target_type)
+{
+	struct connector_type_id *type_id, *temp;
+	int connector_id, found = 0;
+	struct drm_device *dev = connector->dev;
+
+	if (connector->connector_type == target_type)
+		return 0;
+
+	list_for_each_entry_safe(type_id, temp,
+			&connector->connector_type_list, head) {
+		if (type_id->connector_type == target_type) {
+			connector_id = type_id->connector_id;
+			found = 1;
+			break;
+		}
+	}
+	if (found) {
+		connector->connector_type = target_type;
+		connector->connector_type_id = connector_id;
+		return 0;
+	}
+
+	type_id = kzalloc(sizeof(*type_id), GFP_KERNEL);
+
+	if (!type_id) {
+		DRM_DEBUG_KMS("Can't allocate the memory\n");
+		return -ENOMEM;
+	}
+
+	connector->connector_type = target_type;
+	connector->connector_type_id =
+		++drm_connector_enum_list[target_type].count;
+
+	type_id->connector_type = target_type;
+	type_id->connector_id = connector->connector_type_id;
+	list_add_tail(&type_id->head, &connector->connector_type_list);
+
+	return 0;
+}
+EXPORT_SYMBOL(drm_rename_connector_type);
+
+/**
  * drm_connector_cleanup - cleans up an initialised connector
  * @connector: connector to cleanup
  *
@@ -482,6 +556,7 @@  void drm_connector_cleanup(struct drm_connector *connector)
 {
 	struct drm_device *dev = connector->dev;
 	struct drm_display_mode *mode, *t;
+	struct connector_type_id *type_id, *temp;
 
 	list_for_each_entry_safe(mode, t, &connector->probed_modes, head)
 		drm_mode_remove(connector, mode);
@@ -492,6 +567,12 @@  void drm_connector_cleanup(struct drm_connector *connector)
 	list_for_each_entry_safe(mode, t, &connector->user_modes, head)
 		drm_mode_remove(connector, mode);
 
+	list_for_each_entry_safe(type_id, temp,
+			&connector->connector_type_list, head) {
+		list_del(&type_id->head);
+		kfree(type_id);
+	}
+
 	kfree(connector->fb_helper_private);
 	mutex_lock(&dev->mode_config.mutex);
 	drm_mode_object_put(dev, &connector->base);
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index fdf43ab..3862e32 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -521,6 +521,8 @@  struct drm_connector {
 	uint32_t encoder_ids[DRM_CONNECTOR_MAX_ENCODER];
 	uint32_t force_encoder_id;
 	struct drm_encoder *encoder; /* currently active encoder */
+	/* the list of possible connector type/id for this connector */
+	struct list_head connector_type_list;
 	void *fb_helper_private;
 };
 
@@ -647,6 +649,9 @@  extern void drm_connector_init(struct drm_device *dev,
 			    const struct drm_connector_funcs *funcs,
 			    int connector_type);
 
+extern int drm_rename_connector_type(struct drm_connector *connector,
+			    int target_type);
+
 extern void drm_connector_cleanup(struct drm_connector *connector);
 
 extern void drm_encoder_init(struct drm_device *dev,