From patchwork Wed Jan 27 07:16:07 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Zhao, Yakui" X-Patchwork-Id: 75399 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by demeter.kernel.org (8.14.3/8.14.2) with ESMTP id o0R7GXCs019072 for ; Wed, 27 Jan 2010 07:16:33 GMT Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 708AA9E8A5; Tue, 26 Jan 2010 23:16:32 -0800 (PST) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by gabe.freedesktop.org (Postfix) with ESMTP id A66C29E86C for ; Tue, 26 Jan 2010 23:16:30 -0800 (PST) Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga101.fm.intel.com with ESMTP; 26 Jan 2010 23:15:25 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.49,351,1262592000"; d="scan'208";a="767659465" Received: from yakui_zhao.sh.intel.com (HELO localhost.localdomain) ([10.239.13.83]) by fmsmga001.fm.intel.com with ESMTP; 26 Jan 2010 23:16:26 -0800 From: yakui.zhao@intel.com To: airlied@redhat.com Date: Wed, 27 Jan 2010 15:16:07 +0800 Message-Id: <1264576567-11236-1-git-send-email-yakui.zhao@intel.com> X-Mailer: git-send-email 1.5.4.5 Cc: intel-gfx@lists.freedesktop.org, dri-devel@lists.sourceforge.net Subject: [Intel-gfx] [PATCH] drm: Add a generic function to change connector type/id of connector dynamically X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.9 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: intel-gfx-bounces@lists.freedesktop.org Errors-To: intel-gfx-bounces@lists.freedesktop.org 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,