@@ -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);
@@ -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,