All of lore.kernel.org
 help / color / mirror / Atom feed
From: yakui.zhao@intel.com
To: airlied@redhat.com
Cc: intel-gfx@lists.freedesktop.org, dri-devel@lists.sourceforge.net
Subject: [PATCH] drm: Add a generic function to change connector type/id of connector dynamically
Date: Wed, 27 Jan 2010 15:16:07 +0800	[thread overview]
Message-ID: <1264576567-11236-1-git-send-email-yakui.zhao@intel.com> (raw)

From: Zhao Yakui <yakui.zhao@intel.com>

Sometimes one connector can support more than one connector type. And it
will switch the connector type/id dynamically according to the external
connected device.

Add a generic function to change connector type/id of the connector
dynamically.

Signed-off-by: Zhao Yakui <yakui.zhao@intel.com>
---
One multi-function SDVO card device can support SDVO-VGA/SDVO-TV(S-Video/
Composite). We should give them the correct connector type according
to the external connected device. For example: VGA/TV. The connector id
should be re-initialized when connector type is changed. Otherwise we will
get one conflict connector id.
 
One list is added to save the connector type/id that is already used by the
connector. If the target type is already in the list, we can change the
connector type/ide directly by using the saved result. 
If the new connector type is not in the list, we will dynamically
allocate the connector id for it and then save the connector type/id to the
list.

 drivers/gpu/drm/drm_crtc.c |   81 ++++++++++++++++++++++++++++++++++++++++++++
 include/drm/drm_crtc.h     |    5 +++
 2 files changed, 86 insertions(+), 0 deletions(-)

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,
-- 
1.5.4.5


------------------------------------------------------------------------------
The Planet: dedicated and managed hosting, cloud storage, colocation
Stay online with enterprise data centers and the best network in the business
Choose flexible plans and management services without long-term contracts
Personal 24x7 support from experience hosting pros just a phone call away.
http://p.sf.net/sfu/theplanet-com
--

             reply	other threads:[~2010-01-27  7:16 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-01-27  7:16 yakui.zhao [this message]
2010-01-27  9:07 ` [PATCH] drm: Add a generic function to change connector type/id of connector dynamically Maarten Maathuis
2010-01-28  1:43   ` ykzhao
2010-01-28  2:00     ` Dave Airlie
2010-01-27  9:25 ` Dave Airlie
2010-01-27 17:24   ` Jesse Barnes
2010-01-28  8:41     ` ykzhao

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1264576567-11236-1-git-send-email-yakui.zhao@intel.com \
    --to=yakui.zhao@intel.com \
    --cc=airlied@redhat.com \
    --cc=dri-devel@lists.sourceforge.net \
    --cc=intel-gfx@lists.freedesktop.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.