From patchwork Wed Dec 11 23:03:18 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Imre Deak X-Patchwork-Id: 13904320 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id D7B86E7717D for ; Wed, 11 Dec 2024 23:02:56 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id E064810EC4A; Wed, 11 Dec 2024 23:02:53 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.b="a/2u2hc3"; dkim-atps=neutral Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.17]) by gabe.freedesktop.org (Postfix) with ESMTPS id 88BF110EC48; Wed, 11 Dec 2024 23:02:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1733958173; x=1765494173; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=5AMCYrr3tmfkJeGILEYoPC9m08zwnWcuet8VqnZ36SQ=; b=a/2u2hc3aD/l1mn9XbBr5qeVR32JVvy7xrssnGiV05Q0JEA3W4awgqHU a0FY0iJfoZ84vbri9uW6ozYhWrmxJy94L7+uGos55dHGG/0udcqazTbd8 12mZSKbGRhWc+3SEdl38lT/zMpX+xHeug1bbhSIchCPws7Q1F55qrCI6h Lr5sfr674CYhS/wyAXtgWTDtt+0CIGNQ+R+hrQLM2FcieI52W1o3FY+cH J2ByvzjjBoThccEBpL4hDFRTy9MPZG/BBjm5AEPtfSZ+iYQenw+md+xVB IiyrRzOBcHBo0/742oWkbtZTdopl/f9RuLSGBFKIKZ8bETGlrkguwZP/B g==; X-CSE-ConnectionGUID: Tn3GAuv7TI6dVuMAEA4pPQ== X-CSE-MsgGUID: JOW2xDV5TrW4cffBGoKvyA== X-IronPort-AV: E=McAfee;i="6700,10204,11283"; a="34401466" X-IronPort-AV: E=Sophos;i="6.12,226,1728975600"; d="scan'208";a="34401466" Received: from fmviesa001.fm.intel.com ([10.60.135.141]) by orvoesa109.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 Dec 2024 15:02:53 -0800 X-CSE-ConnectionGUID: 8SPDvEITS3G0x5huELUbbA== X-CSE-MsgGUID: gHHJxNa2SlyxAdhKGfdRVg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.12,224,1728975600"; d="scan'208";a="126962338" Received: from ideak-desk.fi.intel.com ([10.237.72.78]) by smtpauth.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 Dec 2024 15:02:50 -0800 From: Imre Deak To: intel-gfx@lists.freedesktop.org Cc: dri-devel@lists.freedesktop.org, Jani Nikula , Simona Vetter , Maxime Ripard , Rodrigo Vivi Subject: [PATCH v3 01/11] drm/connector: Add a way to init/add a connector in separate steps Date: Thu, 12 Dec 2024 01:03:18 +0200 Message-ID: <20241211230328.4012496-2-imre.deak@intel.com> X-Mailer: git-send-email 2.44.2 In-Reply-To: <20241211230328.4012496-1-imre.deak@intel.com> References: <20241211230328.4012496-1-imre.deak@intel.com> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Atm when the connector is added to the drm_mode_config::connector_list, the connector may not be fully initialized yet. This is not a problem for static connectors initialized/added during driver loading, for which the driver ensures that look-ups via the above list are not possible until all the connector and other required state is fully initialized already. It's also not a problem for user space looking up either a static or dynamic (see what this is below) connector, since this will be only possible once the connector is registered. A dynamic - atm only a DP MST - connector can be initialized and added after the load time initialization is done. Such a connector may be looked up by in-kernel users once it's added to the connector list. In particular a hotplug handler could perform a detection on all the connectors on the list and hence find a connector there which isn't yet initialized. For instance the connector's helper hooks may be unset, leading to a NULL dereference while the detect helper calls the connector's drm_connector_helper_funcs::detect() or detect_ctx() handler. To resolve the above issue, add a way for dynamic connectors to separately initialize the DRM core specific parts of the connector without adding it to the connector list - by calling the new drm_connector_dynamic_init() - and to add the connector to the list later once all the initialization is complete and the connector is registered - by calling the new drm_connector_dynamic_register(). Adding the above 2 functions was also motivated to make the distinction of the interface between static and dynamic connectors clearer: Drivers should manually initialize and register only dynamic connectors (with the above 2 functions). A driver should only initialize a static connector (with one of the drm_connector_init*, drmm_connector_init* functions) while the registration of the connector will be done automatically by DRM core. v2: (Jani) - Let initing DDC as well via drm_connector_init_core(). - Rename __drm_connector_init to drm_connector_init_core_and_add(). v3: - Rename drm_connector_init_core() to drm_connector_dynamic_init(). (Sima) - Instead of exporting drm_connector_add(), move adding the connector to the registration step via a new drm_connector_dynamic_register(). (Sima) - Update drm_connector_dynamic_init()'s function documentation and the commit log according to the above changes. - Update the commit log describing the problematic scenario during connector detection. (Maxime) Cc: Jani Nikula Cc: Simona Vetter Cc: Maxime Ripard Reviewed-by: Rodrigo Vivi (v1) Signed-off-by: Imre Deak Reviewed-by: Lyude Paul Reviewed-by: Jani Nikula Reviewed-by: Maxime Ripard --- drivers/gpu/drm/drm_connector.c | 150 +++++++++++++++++++++++++++----- include/drm/drm_connector.h | 6 ++ 2 files changed, 136 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index fc35f47e2849e..a53e5629ba6c1 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -218,11 +218,11 @@ void drm_connector_free_work_fn(struct work_struct *work) } } -static int __drm_connector_init(struct drm_device *dev, - struct drm_connector *connector, - const struct drm_connector_funcs *funcs, - int connector_type, - struct i2c_adapter *ddc) +static int drm_connector_init_only(struct drm_device *dev, + struct drm_connector *connector, + const struct drm_connector_funcs *funcs, + int connector_type, + struct i2c_adapter *ddc) { struct drm_mode_config *config = &dev->mode_config; int ret; @@ -273,6 +273,7 @@ static int __drm_connector_init(struct drm_device *dev, /* provide ddc symlink in sysfs */ connector->ddc = ddc; + INIT_LIST_HEAD(&connector->head); INIT_LIST_HEAD(&connector->global_connector_list_entry); INIT_LIST_HEAD(&connector->probed_modes); INIT_LIST_HEAD(&connector->modes); @@ -288,14 +289,6 @@ static int __drm_connector_init(struct drm_device *dev, drm_connector_get_cmdline_mode(connector); - /* We should add connectors at the end to avoid upsetting the connector - * index too much. - */ - spin_lock_irq(&config->connector_list_lock); - list_add_tail(&connector->head, &config->connector_list); - config->num_connector++; - spin_unlock_irq(&config->connector_list_lock); - if (connector_type != DRM_MODE_CONNECTOR_VIRTUAL && connector_type != DRM_MODE_CONNECTOR_WRITEBACK) drm_connector_attach_edid_property(connector); @@ -332,6 +325,58 @@ static int __drm_connector_init(struct drm_device *dev, return ret; } +static void drm_connector_add(struct drm_connector *connector) +{ + struct drm_device *dev = connector->dev; + struct drm_mode_config *config = &dev->mode_config; + + /* + * TODO: Change this to a WARN, once all drivers are converted to + * call drm_connector_dynamic_init() for MST connectors. + */ + if (!list_empty(&connector->head)) + return; + + spin_lock_irq(&config->connector_list_lock); + list_add_tail(&connector->head, &config->connector_list); + config->num_connector++; + spin_unlock_irq(&config->connector_list_lock); +} + +static void drm_connector_remove(struct drm_connector *connector) +{ + struct drm_device *dev = connector->dev; + + /* + * For dynamic connectors drm_connector_cleanup() can call this function + * before the connector is registered and added to the list. + */ + if (list_empty(&connector->head)) + return; + + spin_lock_irq(&dev->mode_config.connector_list_lock); + list_del_init(&connector->head); + dev->mode_config.num_connector--; + spin_unlock_irq(&dev->mode_config.connector_list_lock); +} + +static int drm_connector_init_and_add(struct drm_device *dev, + struct drm_connector *connector, + const struct drm_connector_funcs *funcs, + int connector_type, + struct i2c_adapter *ddc) +{ + int ret; + + ret = drm_connector_init_only(dev, connector, funcs, connector_type, ddc); + if (ret) + return ret; + + drm_connector_add(connector); + + return 0; +} + /** * drm_connector_init - Init a preallocated connector * @dev: DRM device @@ -361,10 +406,51 @@ int drm_connector_init(struct drm_device *dev, if (drm_WARN_ON(dev, !(funcs && funcs->destroy))) return -EINVAL; - return __drm_connector_init(dev, connector, funcs, connector_type, NULL); + return drm_connector_init_and_add(dev, connector, funcs, connector_type, NULL); } EXPORT_SYMBOL(drm_connector_init); +/** + * drm_connector_dynamic_init - Init a preallocated dynamic connector + * @dev: DRM device + * @connector: the connector to init + * @funcs: callbacks for this connector + * @connector_type: user visible type of the connector + * @ddc: pointer to the associated ddc adapter + * + * Initialises a preallocated dynamic connector. Connectors should be + * subclassed as part of driver connector objects. The connector + * structure should not be allocated with devm_kzalloc(). + * + * Drivers should call this for dynamic connectors which can be hotplugged + * after drm_dev_register() has been called already, e.g. DP MST connectors. + * For all other - static - connectors, drivers should call one of the + * drm_connector_init*()/drmm_connector_init*() functions. + * + * After calling this function the drivers must call + * drm_connector_dynamic_register(). + * + * To remove the connector the driver must call drm_connector_unregister() + * followed by drm_connector_put(). Putting the last reference will call the + * driver's &drm_connector_funcs.destroy hook, which in turn must call + * drm_connector_cleanup() and free the connector structure. + * + * Returns: + * Zero on success, error code on failure. + */ +int drm_connector_dynamic_init(struct drm_device *dev, + struct drm_connector *connector, + const struct drm_connector_funcs *funcs, + int connector_type, + struct i2c_adapter *ddc) +{ + if (drm_WARN_ON(dev, !(funcs && funcs->destroy))) + return -EINVAL; + + return drm_connector_init_only(dev, connector, funcs, connector_type, ddc); +} +EXPORT_SYMBOL(drm_connector_dynamic_init); + /** * drm_connector_init_with_ddc - Init a preallocated connector * @dev: DRM device @@ -398,7 +484,7 @@ int drm_connector_init_with_ddc(struct drm_device *dev, if (drm_WARN_ON(dev, !(funcs && funcs->destroy))) return -EINVAL; - return __drm_connector_init(dev, connector, funcs, connector_type, ddc); + return drm_connector_init_and_add(dev, connector, funcs, connector_type, ddc); } EXPORT_SYMBOL(drm_connector_init_with_ddc); @@ -442,7 +528,7 @@ int drmm_connector_init(struct drm_device *dev, if (drm_WARN_ON(dev, funcs && funcs->destroy)) return -EINVAL; - ret = __drm_connector_init(dev, connector, funcs, connector_type, ddc); + ret = drm_connector_init_and_add(dev, connector, funcs, connector_type, ddc); if (ret) return ret; @@ -659,10 +745,8 @@ void drm_connector_cleanup(struct drm_connector *connector) connector->name = NULL; fwnode_handle_put(connector->fwnode); connector->fwnode = NULL; - spin_lock_irq(&dev->mode_config.connector_list_lock); - list_del(&connector->head); - dev->mode_config.num_connector--; - spin_unlock_irq(&dev->mode_config.connector_list_lock); + + drm_connector_remove(connector); WARN_ON(connector->state && !connector->funcs->atomic_destroy_state); if (connector->state && connector->funcs->atomic_destroy_state) @@ -749,6 +833,32 @@ int drm_connector_register(struct drm_connector *connector) } EXPORT_SYMBOL(drm_connector_register); +/** + * drm_connector_dynamic_register - register a dynamic connector + * @connector: the connector to register + * + * Register userspace interfaces for a connector. Only call this for connectors + * initialized by calling drm_connector_dynamic_init(). All other connectors + * will be registered automatically when calling drm_dev_register(). + * + * When the connector is no longer available the driver must call + * drm_connector_unregister(). + * + * Returns: + * Zero on success, error code on failure. + */ +int drm_connector_dynamic_register(struct drm_connector *connector) +{ + /* Was the connector inited already? */ + if (WARN_ON(!(connector->funcs && connector->funcs->destroy))) + return -EINVAL; + + drm_connector_add(connector); + + return drm_connector_register(connector); +} +EXPORT_SYMBOL(drm_connector_dynamic_register); + /** * drm_connector_unregister - unregister a connector * @connector: the connector to unregister diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index e3fa43291f449..f766d194221d1 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -2126,6 +2126,11 @@ int drm_connector_init(struct drm_device *dev, struct drm_connector *connector, const struct drm_connector_funcs *funcs, int connector_type); +int drm_connector_dynamic_init(struct drm_device *dev, + struct drm_connector *connector, + const struct drm_connector_funcs *funcs, + int connector_type, + struct i2c_adapter *ddc); int drm_connector_init_with_ddc(struct drm_device *dev, struct drm_connector *connector, const struct drm_connector_funcs *funcs, @@ -2147,6 +2152,7 @@ int drmm_connector_hdmi_init(struct drm_device *dev, unsigned int max_bpc); void drm_connector_attach_edid_property(struct drm_connector *connector); int drm_connector_register(struct drm_connector *connector); +int drm_connector_dynamic_register(struct drm_connector *connector); void drm_connector_unregister(struct drm_connector *connector); int drm_connector_attach_encoder(struct drm_connector *connector, struct drm_encoder *encoder); From patchwork Wed Dec 11 23:03:19 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Imre Deak X-Patchwork-Id: 13904321 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 3AAA9E77182 for ; Wed, 11 Dec 2024 23:02:58 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 6136510EC4B; Wed, 11 Dec 2024 23:02:54 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.b="MyzeSJKC"; dkim-atps=neutral Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.17]) by gabe.freedesktop.org (Postfix) with ESMTPS id CAD0D10EC48; Wed, 11 Dec 2024 23:02:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1733958174; x=1765494174; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=sps+KDb4UQ16DhP3fbAtZbfumgJPH20/L0ttyJUy/DQ=; b=MyzeSJKCYXAZlcxnCx5UJuJcRdiUg/+Ufqu7+bSkLnIpQyCbvVXwVehr r189JfYS/M/6ke1xskyhBt8lliy9PMl6sCfPxV+VQRXn+1A9U1OTelTQk VueamnhoGRJyoAJHHz0kabJWTcgkIvr90PdWHL5chCmefI8oydN2ChWM5 73YKaCugoscYMfNo/yrEGoKr6ayPf8+srzBFSVElvyaJfkXAQ7MCpG6qH ImVqCRGCPOsOkMkGczwsXHjWhwhwQ5br+/ye07YGEFYrz9ShlBmLWCkJB ayy4gFVKIjLsP+vwbv6N1JiAmjaJBJigJsxZsgacp2BdB4OUnMQhb3kXA A==; X-CSE-ConnectionGUID: cTArqJ9qT/y/4dsGuHeGlg== X-CSE-MsgGUID: fNsxSc1YTZqLI20hxdgkvw== X-IronPort-AV: E=McAfee;i="6700,10204,11283"; a="34401470" X-IronPort-AV: E=Sophos;i="6.12,226,1728975600"; d="scan'208";a="34401470" Received: from fmviesa001.fm.intel.com ([10.60.135.141]) by orvoesa109.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 Dec 2024 15:02:54 -0800 X-CSE-ConnectionGUID: JtABZAq9Q3yeIt3jPd4B2g== X-CSE-MsgGUID: KS3ymazJT4asewfMbg8Ekw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.12,224,1728975600"; d="scan'208";a="126962339" Received: from ideak-desk.fi.intel.com ([10.237.72.78]) by smtpauth.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 Dec 2024 15:02:52 -0800 From: Imre Deak To: intel-gfx@lists.freedesktop.org Cc: dri-devel@lists.freedesktop.org, Simona Vetter Subject: [PATCH v3 02/11] drm/connector: Add FIXME for GETRESOURCES ioctl wrt. uninited connectors Date: Thu, 12 Dec 2024 01:03:19 +0200 Message-ID: <20241211230328.4012496-3-imre.deak@intel.com> X-Mailer: git-send-email 2.44.2 In-Reply-To: <20241211230328.4012496-1-imre.deak@intel.com> References: <20241211230328.4012496-1-imre.deak@intel.com> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" The connectors enumerated by the GETRESOURCES ioctl may not be fully initialized yet wrt. to the state set up during connector registration (for instance the connector's debugfs/sysfs interfaces may not exist yet). This can happen in two ways: 1. Connectors initialized and added to the drm_mode_config::connector_list during driver loading will be visible to the GETRESOURCES ioctl caller once the driver is registered via drm_dev_register()->drm_minor_register(DRM_MINOR_PRIMARY) and before the connectors are registered via drm_dev_register()-> drm_modeset_register_all(). 2. Dynamic connectors (MST) - after being initialized - may be added to the connector_list after the driver is loaded and registered and before the connector's userspace interfaces (debugfs, sysfs etc.) are added in drm_connector_dynamic_register(). A solution for 1. would be to register the driver only after the connectors are registered, for 2. to add the connector to connector_list only after the userspace interfaces are registered. The fix would require a bigger change, not the topic of this patchset, so adding only a FIXME comment here. Suggested-by: Simona Vetter Signed-off-by: Imre Deak Reviewed-by: Jani Nikula --- drivers/gpu/drm/drm_mode_config.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c index 37d2e0a4ef4be..8642a2fb25a90 100644 --- a/drivers/gpu/drm/drm_mode_config.c +++ b/drivers/gpu/drm/drm_mode_config.c @@ -150,6 +150,15 @@ int drm_mode_getresources(struct drm_device *dev, void *data, drm_connector_list_iter_begin(dev, &conn_iter); count = 0; connector_id = u64_to_user_ptr(card_res->connector_id_ptr); + /* + * FIXME: the connectors on the list may not be fully initialized yet, + * if the ioctl is called before the connectors are registered. (See + * drm_dev_register()->drm_modeset_register_all() for static and + * drm_connector_dynamic_register() for dynamic connectors.) + * The driver should only get registered after static connectors are + * fully initialized and dynamic connectors should be added to the + * connector list only after fully initializing them. + */ drm_for_each_connector_iter(connector, &conn_iter) { /* only expose writeback connectors if userspace understands them */ if (!file_priv->writeback_connectors && From patchwork Wed Dec 11 23:03:20 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Imre Deak X-Patchwork-Id: 13904322 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 6E668E77183 for ; Wed, 11 Dec 2024 23:03:00 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 593CB10EC50; Wed, 11 Dec 2024 23:02:56 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.b="luBo8kR8"; dkim-atps=neutral Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.17]) by gabe.freedesktop.org (Postfix) with ESMTPS id DFB4010EC4C; Wed, 11 Dec 2024 23:02:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1733958175; x=1765494175; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=6vj+6m0y6CENXxyub1QD6Q84DwS6vI2KU/FS8bllgt8=; b=luBo8kR8FjzI5nC00bjGAp1PCKO8pLKMn4LaLBcuxLGWd6qJDZLtbtTK cSUSZQApBRA0RqCtdVVorSvFJrN74UMAzKYXliDVCtgFbaDzAKkdpJuHv GkDUIOtGUGoxws1dkJ1FjKO0PL+zNxP5HRglWOzpaI5+0zai/hQzslZW7 bPn1VxmGZxmmaXh3oR/OHjbhkyXcLa6zBKO1Na1xII8BtZuAXGdX4+suj Fc2dNsJRtlYhRMBVxOlzAED6c6WHyfFqlsJSljmoCD++Nil3xJ7lpcsnt mMCohpNZNM06rYe2PjKcLV9VB0gpip72spPTZxkxJyPb1OM7P1atMcQxj A==; X-CSE-ConnectionGUID: VGnTFwIETc2mbslWuOGUtQ== X-CSE-MsgGUID: wz9ANd/ZTt2j34UywKl1sg== X-IronPort-AV: E=McAfee;i="6700,10204,11283"; a="34401474" X-IronPort-AV: E=Sophos;i="6.12,226,1728975600"; d="scan'208";a="34401474" Received: from fmviesa001.fm.intel.com ([10.60.135.141]) by orvoesa109.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 Dec 2024 15:02:55 -0800 X-CSE-ConnectionGUID: SnW0xtP/Sx+ByTtx4/4aqw== X-CSE-MsgGUID: N2TSx91KRjKPeL/YH/xZTw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.12,224,1728975600"; d="scan'208";a="126962374" Received: from ideak-desk.fi.intel.com ([10.237.72.78]) by smtpauth.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 Dec 2024 15:02:53 -0800 From: Imre Deak To: intel-gfx@lists.freedesktop.org Cc: dri-devel@lists.freedesktop.org Subject: [PATCH v3 03/11] drm/connector: Add deprication notes for drm_connector_register/unregister Date: Thu, 12 Dec 2024 01:03:20 +0200 Message-ID: <20241211230328.4012496-4-imre.deak@intel.com> X-Mailer: git-send-email 2.44.2 In-Reply-To: <20241211230328.4012496-1-imre.deak@intel.com> References: <20241211230328.4012496-1-imre.deak@intel.com> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Drivers should register/unregister only dynamic (MST) connectors manually using drm_connector_dynamic_register()/unregister(). Static connectors are registered/unregistered by the DRM core automatically. Some drivers still call drm_connector_register()/ unregister() for static connectors, both of which should be a nop for them and hence are scheduled to be removed. Update the function documentation for these functions accordingly. Signed-off-by: Imre Deak Reviewed-by: Jani Nikula --- drivers/gpu/drm/drm_connector.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index a53e5629ba6c1..c322dbf6e3161 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -767,14 +767,17 @@ EXPORT_SYMBOL(drm_connector_cleanup); * drm_connector_register - register a connector * @connector: the connector to register * - * Register userspace interfaces for a connector. Only call this for connectors - * which can be hotplugged after drm_dev_register() has been called already, - * e.g. DP MST connectors. All other connectors will be registered automatically - * when calling drm_dev_register(). + * Register userspace interfaces for a connector. Drivers shouldn't call this + * function. Static connectors will be registered automatically by DRM core + * from drm_dev_register(), dynamic connectors (MST) should be registered by + * drivers calling drm_connector_dynamic_register(). * * When the connector is no longer available, callers must call * drm_connector_unregister(). * + * Note: Existing uses of this function in drivers should be a nop already and + * are scheduled to be removed. + * * Returns: * Zero on success, error code on failure. */ @@ -863,9 +866,14 @@ EXPORT_SYMBOL(drm_connector_dynamic_register); * drm_connector_unregister - unregister a connector * @connector: the connector to unregister * - * Unregister userspace interfaces for a connector. Only call this for - * connectors which have been registered explicitly by calling - * drm_connector_register(). + * Unregister userspace interfaces for a connector. Drivers should call this + * for dynamic connectors (MST) only, which were registered explicitly by + * calling drm_connector_dynamic_register(). All other - static - connectors + * will be unregistered automatically by DRM core and drivers shouldn't call + * this function for those. + * + * Note: Existing uses of this function in drivers for static connectors + * should be a nop already and are scheduled to be removed. */ void drm_connector_unregister(struct drm_connector *connector) { From patchwork Wed Dec 11 23:03:21 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Imre Deak X-Patchwork-Id: 13904324 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id C627FE7717D for ; Wed, 11 Dec 2024 23:03:02 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 8131110EC59; Wed, 11 Dec 2024 23:03:01 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.b="SrOCrmZ9"; dkim-atps=neutral Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.17]) by gabe.freedesktop.org (Postfix) with ESMTPS id 98CC910EC53; Wed, 11 Dec 2024 23:02:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1733958178; x=1765494178; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=7/nOdPtf+5lAMIbv9oQ0HbQU5bIXHkU0aUSQmj+8K7M=; b=SrOCrmZ9ljgTfUL3/qJoPNXhTjvn29zIOCHZhddrJs5VvwOKHaZcvN8+ /yuugUmyuXugaoBiPb9OiTwlI0GKyQXJNAnPxNbxBXGEzy7WwVvuloLon CA03XNLH64uarndGLZOHN904wRV/hxM3xa7x7CrYtdIRYleKooSewAJ1I uJim8/7xec2vUlFy3LYFP0+Zc3jgVzNsE4WKgwYb9PwNgcik/JiMD7blE WmP4q8BtlJCpNqiJGnB7Z4I2QnAa179/uyPSClu597bhWyfs63izUdpCV 0wa0FNLwiTEKnmDmikYFL4e9GGs7/Et2A5nAR7ZrGRd01KTkQckYMhBAc A==; X-CSE-ConnectionGUID: aILRzOfLSlqMHdllJIYL/A== X-CSE-MsgGUID: T8CNNra7SLerzemIfsen+g== X-IronPort-AV: E=McAfee;i="6700,10204,11283"; a="34401479" X-IronPort-AV: E=Sophos;i="6.12,226,1728975600"; d="scan'208";a="34401479" Received: from fmviesa001.fm.intel.com ([10.60.135.141]) by orvoesa109.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 Dec 2024 15:02:58 -0800 X-CSE-ConnectionGUID: lrk1rqh9RSaI+8uFsPshgA== X-CSE-MsgGUID: UJkpOf6tR6OLST4KE41aNA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.12,224,1728975600"; d="scan'208";a="126962423" Received: from ideak-desk.fi.intel.com ([10.237.72.78]) by smtpauth.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 Dec 2024 15:02:54 -0800 From: Imre Deak To: intel-gfx@lists.freedesktop.org Cc: dri-devel@lists.freedesktop.org, Lyude Paul , Harry Wentland , Leo Li , Wayne Lin , Alex Deucher , Karol Herbst , Danilo Krummrich Subject: [PATCH v3 04/11] drm/dp_mst: Register connectors via drm_connector_dynamic_register() Date: Thu, 12 Dec 2024 01:03:21 +0200 Message-ID: <20241211230328.4012496-5-imre.deak@intel.com> X-Mailer: git-send-email 2.44.2 In-Reply-To: <20241211230328.4012496-1-imre.deak@intel.com> References: <20241211230328.4012496-1-imre.deak@intel.com> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" MST connectors should be initialized/registered by calling drm_connector_dynamic_init()/drm_connector_dynamic_register(). The previous patch adding these functions explains the issue with the current drm_connector_init*()/drm_connector_register() interface for MST connectors. Based on the above adjust here the registration part and change the initialization part in follow-up patches for each driver. For now, drivers are allowed to keep using the drm_connector_init*() functions, by drm_connector_dynamic_register() checking for this (see drm_connector_add()). A patch later will change this to WARN in such cases. Cc: Lyude Paul Cc: Harry Wentland Cc: Leo Li Cc: Wayne Lin Cc: Alex Deucher Cc: Karol Herbst Cc: Danilo Krummrich Signed-off-by: Imre Deak Reviewed-by: Jani Nikula Acked-by: Wayne Lin --- drivers/gpu/drm/display/drm_dp_mst_topology.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c index 687c70308d82b..f8cd094efa3c0 100644 --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c @@ -2281,7 +2281,7 @@ drm_dp_mst_port_add_connector(struct drm_dp_mst_branch *mstb, port->cached_edid = drm_edid_read_ddc(port->connector, &port->aux.ddc); - drm_connector_register(port->connector); + drm_connector_dynamic_register(port->connector); return; error: From patchwork Wed Dec 11 23:03:22 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Imre Deak X-Patchwork-Id: 13904323 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 025CAE77182 for ; Wed, 11 Dec 2024 23:03:01 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id F281110EC57; Wed, 11 Dec 2024 23:03:00 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.b="LkzAxyRg"; dkim-atps=neutral Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.17]) by gabe.freedesktop.org (Postfix) with ESMTPS id 6458010EC57; Wed, 11 Dec 2024 23:02:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1733958180; x=1765494180; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=GD3urlubJOUD/5fS+x121FKLyWU25hRdvB3HWimlS+E=; b=LkzAxyRg/5yGrAz5h25F8QRHgiBLmb5+WQiHSt4AZkKGNnVPILOs+FBK TKscWblUqMsNwTgqYnKI/H2RYCJqmCRAW8cTXQ2gflE0IiR/+e1w130wu vyOntxiAZNY82ICcNsx3LVNaL0eRyBGUq/S1UqkMMDx2rtWsMW1ob+Ivb b5dM52I6dgAVuOERmtiN95fjjTim68f4ZliUl83/0BhGdVV3ZLsReerUt 2FLTrTzAve72qKCX0iWs1RfNS5JJj2xgS2c8lbZ+c+F7v3b/jEQwWs+lj EMtHhk70GCQTuo9GNt++xs9fqgWm5qT05qXu00Cn2zzVX0RSHXVGE747R Q==; X-CSE-ConnectionGUID: hPhDg58NQg+QXb4x3JAT4w== X-CSE-MsgGUID: 9g8Buq6LQ2ufpNu4gV91AQ== X-IronPort-AV: E=McAfee;i="6700,10204,11283"; a="34401486" X-IronPort-AV: E=Sophos;i="6.12,226,1728975600"; d="scan'208";a="34401486" Received: from fmviesa001.fm.intel.com ([10.60.135.141]) by orvoesa109.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 Dec 2024 15:02:59 -0800 X-CSE-ConnectionGUID: j+tH4RGoQY+QhBoAIFvneQ== X-CSE-MsgGUID: R+K0wUnpSd6Xz30rCIz5iw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.12,224,1728975600"; d="scan'208";a="126962510" Received: from ideak-desk.fi.intel.com ([10.237.72.78]) by smtpauth.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 Dec 2024 15:02:57 -0800 From: Imre Deak To: intel-gfx@lists.freedesktop.org Cc: dri-devel@lists.freedesktop.org, Lyude Paul , Rodrigo Vivi Subject: [PATCH v3 05/11] drm/i915/dp_mst: Expose a connector to kernel users after it's properly initialized Date: Thu, 12 Dec 2024 01:03:22 +0200 Message-ID: <20241211230328.4012496-6-imre.deak@intel.com> X-Mailer: git-send-email 2.44.2 In-Reply-To: <20241211230328.4012496-1-imre.deak@intel.com> References: <20241211230328.4012496-1-imre.deak@intel.com> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" After a connector is added to the drm_mode_config::connector_list, it's visible to any in-kernel users looking up connectors via the above list. Make sure that the connector is properly initialized before such look-ups, by initializing the connector with drm_connector_dynamic_register() - which doesn't add the connector to the list - and registering it with drm_connector_dynamic_register() - which adds the connector to the list - after the initialization is complete. v2: Rebase on the change which moves adding the connector to the connector list only later when calling drm_connector_dynamic_register(). Cc: Lyude Paul Reviewed-by: Rodrigo Vivi (v1) Signed-off-by: Imre Deak Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 27 +++++++-------------- 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 123c4ece62688..debe4d0eee11f 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -1731,6 +1731,8 @@ mst_topology_add_connector(struct drm_dp_mst_topology_mgr *mgr, if (!intel_connector) return NULL; + connector = &intel_connector->base; + intel_connector->get_hw_state = mst_connector_get_hw_state; intel_connector->sync_state = intel_dp_connector_sync_state; intel_connector->mst_port = intel_dp; @@ -1739,30 +1741,19 @@ mst_topology_add_connector(struct drm_dp_mst_topology_mgr *mgr, intel_dp_init_modeset_retry_work(intel_connector); - /* - * TODO: The following drm_connector specific initialization belongs - * to DRM core, however it happens atm too late in - * drm_connector_init(). That function will also expose the connector - * to in-kernel users, so it can't be called until the connector is - * sufficiently initialized; init the device pointer used by the - * following DSC setup, until a fix moving this to DRM core. - */ - intel_connector->base.dev = mgr->dev; - - intel_connector->dp.dsc_decompression_aux = drm_dp_mst_dsc_aux_for_port(port); - intel_dp_mst_read_decompression_port_dsc_caps(intel_dp, intel_connector); - intel_connector->dp.dsc_hblank_expansion_quirk = - detect_dsc_hblank_expansion_quirk(intel_connector); - - connector = &intel_connector->base; - ret = drm_connector_init(display->drm, connector, &mst_connector_funcs, - DRM_MODE_CONNECTOR_DisplayPort); + ret = drm_connector_dynamic_init(display->drm, connector, &mst_connector_funcs, + DRM_MODE_CONNECTOR_DisplayPort, NULL); if (ret) { drm_dp_mst_put_port_malloc(port); intel_connector_free(intel_connector); return NULL; } + intel_connector->dp.dsc_decompression_aux = drm_dp_mst_dsc_aux_for_port(port); + intel_dp_mst_read_decompression_port_dsc_caps(intel_dp, intel_connector); + intel_connector->dp.dsc_hblank_expansion_quirk = + detect_dsc_hblank_expansion_quirk(intel_connector); + drm_connector_helper_add(connector, &mst_connector_helper_funcs); for_each_pipe(display, pipe) { From patchwork Wed Dec 11 23:03:23 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Imre Deak X-Patchwork-Id: 13904325 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 5A22FE77184 for ; Wed, 11 Dec 2024 23:03:04 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id A31DA10EC5B; Wed, 11 Dec 2024 23:03:03 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.b="F291Z76u"; dkim-atps=neutral Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.17]) by gabe.freedesktop.org (Postfix) with ESMTPS id 057FF10EC58; Wed, 11 Dec 2024 23:03:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1733958182; x=1765494182; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=xWx7D6gil7lDx+/G2SLm0hD2VCU/iLv8P+tC+OVl/ko=; b=F291Z76udXJsp7d5El/MxIOIIqq0JJ8gSt9ThSB/wnBVJ+rSgRR++Bp/ q4iikQ4D+LLN5kjCi6YIDPbpCpf5dVR5Sd16Ea1SSMH3NJM7gR8DDr+KL Hf+C7U8Qo3DECCAY95nBTM2Fu4VHjPxhAZHvCcIjhHLbRMeV5UZEmlgN4 Xz6AYj5GtzOLBvO0R1Xi7dAsbGEVFiyflEUy1ZljTdI9PDzFCXI0b0yAs RoWTA0ZCs2DEcZoM31a9RQtqUs06MCqUuRGkM3Q3IZfC0+ETmwDYqNvUL not+rkxnYZln7z7LM1v2nVWkvEeqvUG+1dDIS9hz0nrifhc3QB43U60XB A==; X-CSE-ConnectionGUID: EEIwU1f4QBGpdop2JtJvVg== X-CSE-MsgGUID: X848dY8zTTimftXLVLPs2g== X-IronPort-AV: E=McAfee;i="6700,10204,11283"; a="34401492" X-IronPort-AV: E=Sophos;i="6.12,226,1728975600"; d="scan'208";a="34401492" Received: from fmviesa001.fm.intel.com ([10.60.135.141]) by orvoesa109.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 Dec 2024 15:03:01 -0800 X-CSE-ConnectionGUID: joAzLjU/SJuSKrzxd+/RQA== X-CSE-MsgGUID: Vrm6wAwIR46MeXOzjoQetQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.12,224,1728975600"; d="scan'208";a="126962511" Received: from ideak-desk.fi.intel.com ([10.237.72.78]) by smtpauth.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 Dec 2024 15:02:58 -0800 From: Imre Deak To: intel-gfx@lists.freedesktop.org Cc: dri-devel@lists.freedesktop.org, Harry Wentland , Leo Li , Wayne Lin , Alex Deucher , Lyude Paul Subject: [PATCH v3 06/11] drm/amd/dp_mst: Expose a connector to kernel users after it's properly initialized Date: Thu, 12 Dec 2024 01:03:23 +0200 Message-ID: <20241211230328.4012496-7-imre.deak@intel.com> X-Mailer: git-send-email 2.44.2 In-Reply-To: <20241211230328.4012496-1-imre.deak@intel.com> References: <20241211230328.4012496-1-imre.deak@intel.com> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" After a connector is added to the drm_mode_config::connector_list, it's visible to any in-kernel users looking up connectors via the above list. Make sure that the connector is properly initialized before such look-ups, by initializing the connector with drm_connector_dynamic_register() - which doesn't add the connector to the list - and registering it with drm_connector_dynamic_register() - which adds the connector to the list - after the initialization is complete. Cc: Harry Wentland Cc: Leo Li Cc: Wayne Lin Cc: Alex Deucher Cc: Lyude Paul Signed-off-by: Imre Deak Reviewed-by: Jani Nikula Acked-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c index 6e43594906130..d398bc74e6677 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c @@ -590,11 +590,12 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr, amdgpu_dm_set_mst_status(&aconnector->mst_status, MST_PROBE, true); - if (drm_connector_init( + if (drm_connector_dynamic_init( dev, connector, &dm_dp_mst_connector_funcs, - DRM_MODE_CONNECTOR_DisplayPort)) { + DRM_MODE_CONNECTOR_DisplayPort, + NULL)) { kfree(aconnector); return NULL; } From patchwork Wed Dec 11 23:03:24 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Imre Deak X-Patchwork-Id: 13904327 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id AF28CE77180 for ; Wed, 11 Dec 2024 23:03:07 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 1C6DA10EC61; Wed, 11 Dec 2024 23:03:07 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.b="XQciWQ7n"; dkim-atps=neutral Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.17]) by gabe.freedesktop.org (Postfix) with ESMTPS id CBE0B10EC4D; Wed, 11 Dec 2024 23:03:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1733958183; x=1765494183; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=mzF0myakAockPX22Kdl2I/kjMADTSmWhi7MTXNkVNnc=; b=XQciWQ7nCFfMPQqCzbJwE2MMUn23THPrMEFSPretR8M8rtufQnOjVpFc wHNTPDsKPV6GCWizuMsWLhhFmsHLfch+Z71UcMwuPZctjJE0+a1TRs9P4 apFcSdZk0SME1ggjOHr46qSe5pr2ZZ6m/NXOZUJ6IIimwz5/vvpaDyrvi cs8uf/7VpezEncQOcjxG7gGNdEJg+vKDNswYpodYK5Tlc+JDtRxc4vGi2 Ms6NpbruxSSRXe86pnZ6szGTHJCt0EZ63ftmfKxkA7GkaeAV3BJr+MVte taS4d7aBrSqCPOqKXlxxTRjqreoYc3Fg3NNSc1pbBx7dwnbwcxzzDPAj9 g==; X-CSE-ConnectionGUID: HFbgCcFfRiyRXNCWzOFoog== X-CSE-MsgGUID: jeUrFkTaShihYhnUWYFrbA== X-IronPort-AV: E=McAfee;i="6700,10204,11283"; a="34401498" X-IronPort-AV: E=Sophos;i="6.12,226,1728975600"; d="scan'208";a="34401498" Received: from fmviesa001.fm.intel.com ([10.60.135.141]) by orvoesa109.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 Dec 2024 15:03:03 -0800 X-CSE-ConnectionGUID: LTEyMNeRRWyb8wt1Z30aiA== X-CSE-MsgGUID: 8jD81YrLSyKz8Ij6p+wQhg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.12,224,1728975600"; d="scan'208";a="126962521" Received: from ideak-desk.fi.intel.com ([10.237.72.78]) by smtpauth.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 Dec 2024 15:03:01 -0800 From: Imre Deak To: intel-gfx@lists.freedesktop.org Cc: dri-devel@lists.freedesktop.org, Karol Herbst , Lyude Paul , Danilo Krummrich Subject: [PATCH v3 07/11] drm/nouveau/dp_mst: Expose a connector to kernel users after it's properly initialized Date: Thu, 12 Dec 2024 01:03:24 +0200 Message-ID: <20241211230328.4012496-8-imre.deak@intel.com> X-Mailer: git-send-email 2.44.2 In-Reply-To: <20241211230328.4012496-1-imre.deak@intel.com> References: <20241211230328.4012496-1-imre.deak@intel.com> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" After a connector is added to the drm_mode_config::connector_list, it's visible to any in-kernel users looking up connectors via the above list. Make sure that the connector is properly initialized before such look-ups, by initializing the connector with drm_connector_dynamic_register() - which doesn't add the connector to the list - and registering it with drm_connector_dynamic_register() - which adds the connector to the list - after the initialization is complete. Cc: Karol Herbst Cc: Lyude Paul Cc: Danilo Krummrich Signed-off-by: Imre Deak Reviewed-by: Jani Nikula --- drivers/gpu/drm/nouveau/dispnv50/disp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c index eed579a6c858b..8097249612bc7 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c @@ -1265,8 +1265,8 @@ nv50_mstc_new(struct nv50_mstm *mstm, struct drm_dp_mst_port *port, mstc->mstm = mstm; mstc->port = port; - ret = drm_connector_init(dev, &mstc->connector, &nv50_mstc, - DRM_MODE_CONNECTOR_DisplayPort); + ret = drm_connector_dynamic_init(dev, &mstc->connector, &nv50_mstc, + DRM_MODE_CONNECTOR_DisplayPort, NULL); if (ret) { kfree(*pmstc); *pmstc = NULL; From patchwork Wed Dec 11 23:03:25 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Imre Deak X-Patchwork-Id: 13904326 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 4A3E1E7717D for ; Wed, 11 Dec 2024 23:03:06 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id AAFDD10EC4D; Wed, 11 Dec 2024 23:03:05 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.b="dRqtzQtU"; dkim-atps=neutral Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.17]) by gabe.freedesktop.org (Postfix) with ESMTPS id E050B10EC65; Wed, 11 Dec 2024 23:03:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1733958184; x=1765494184; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=fGSlh/zhJdIfVsmOJovFGnD3Nxl3WOJ0zFbOGizbQhE=; b=dRqtzQtUKhoePzg/WAaLJaXi8UXeXzRxTh2IapIHjTPsNHpY0Smc2I1C xYu3LKFBYO+t5iIcrJsezd9FF5nhEKUlgRY2BRudg12fn0EivvCjhoX7W cPejdC+q69Zk/aO9+/uvJ+ilcCjKRzKfIrdf5yVrrbcB6e9xGBBQRxYqI pMmjMIyRqIiw7JQTQUHJLCcY1bjnb8rsojl/Fl8wnai3s1YxCQmDA6nZP nOoMeGT3FZr7x82alBLyn77OGQYc7IMypI2n3eekyoqyMDBmYUMyreb1d yWmPFIccyaUOVM6PQ9TIC458GZJv7kjZFrqvZsgvxZie1e5VyUGaf1F4l A==; X-CSE-ConnectionGUID: W7ZPsRxKTIiLNsrfoLv1Sg== X-CSE-MsgGUID: Hh+zrYgDRCWyUFNyXQRniw== X-IronPort-AV: E=McAfee;i="6700,10204,11283"; a="34401507" X-IronPort-AV: E=Sophos;i="6.12,226,1728975600"; d="scan'208";a="34401507" Received: from fmviesa001.fm.intel.com ([10.60.135.141]) by orvoesa109.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 Dec 2024 15:03:04 -0800 X-CSE-ConnectionGUID: fmryekkWQS+SDaddj58hAw== X-CSE-MsgGUID: lvd6plF6SYCYBgXS4v8EEQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.12,224,1728975600"; d="scan'208";a="126962575" Received: from ideak-desk.fi.intel.com ([10.237.72.78]) by smtpauth.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 Dec 2024 15:03:02 -0800 From: Imre Deak To: intel-gfx@lists.freedesktop.org Cc: dri-devel@lists.freedesktop.org Subject: [PATCH v3 08/11] drm/connector: Warn if a connector is registered/added incorrectly Date: Thu, 12 Dec 2024 01:03:25 +0200 Message-ID: <20241211230328.4012496-9-imre.deak@intel.com> X-Mailer: git-send-email 2.44.2 In-Reply-To: <20241211230328.4012496-1-imre.deak@intel.com> References: <20241211230328.4012496-1-imre.deak@intel.com> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" All the drivers should be converted now to use drm_connector_dynamic_init() for MST connectors, hence drm_connector_dynamic_register()->drm_connector_add() can WARN now if this was not the case (for instance if a driver inited an MST connector with one of the drm_connector_init*() functions incorrectly). Signed-off-by: Imre Deak Reviewed-by: Jani Nikula --- drivers/gpu/drm/drm_connector.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index c322dbf6e3161..1bd7407223fbb 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -330,11 +330,7 @@ static void drm_connector_add(struct drm_connector *connector) struct drm_device *dev = connector->dev; struct drm_mode_config *config = &dev->mode_config; - /* - * TODO: Change this to a WARN, once all drivers are converted to - * call drm_connector_dynamic_init() for MST connectors. - */ - if (!list_empty(&connector->head)) + if (drm_WARN_ON(dev, !list_empty(&connector->head))) return; spin_lock_irq(&config->connector_list_lock); From patchwork Wed Dec 11 23:03:26 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Imre Deak X-Patchwork-Id: 13904328 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 53718E77183 for ; Wed, 11 Dec 2024 23:03:08 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 90DB410EC64; Wed, 11 Dec 2024 23:03:07 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.b="HRb+L2A9"; dkim-atps=neutral Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.17]) by gabe.freedesktop.org (Postfix) with ESMTPS id BA69810EC5D; Wed, 11 Dec 2024 23:03:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1733958186; x=1765494186; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=X32OBeey+SA/a0oyjH31od+vkcQaihdZgJxmS+91FtU=; b=HRb+L2A9GwNsWBnoyH9GEhSEnPSRBSXkRAcYo0RhA8rXYVk7gPxG3Swl 2gYBR6vqXeIQ/pLdrchhXvFBL1VB/C40p1w1tqR3nepv5F4kGz63GSpCo KC2hLCke0JrZ5ly9V6K7bsZVsj65sNpN+3fckJ7uCWnWlv9RX+9vqpTwK S5eR7s6fjYB6BsClPsGiwx9v0hcqtjVNp9yAFNxRGE+RoMqwyqQ8Fv0zZ 8xWHs1OoWmKc30fQpZjDsS6nom7eiwXviDtRk6FkM84b92TDSPMzSOHSY gCWfLS1iBAh0so8P2dEGSSyjzU+Ni4/LGbGh2W3MLQTDHm20zeVJ7y2K3 Q==; X-CSE-ConnectionGUID: dncT+SORSb6M5SBYh8mpog== X-CSE-MsgGUID: Yh1rC+XiQd6YUIZyu/ykPw== X-IronPort-AV: E=McAfee;i="6700,10204,11283"; a="34401510" X-IronPort-AV: E=Sophos;i="6.12,226,1728975600"; d="scan'208";a="34401510" Received: from fmviesa001.fm.intel.com ([10.60.135.141]) by orvoesa109.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 Dec 2024 15:03:06 -0800 X-CSE-ConnectionGUID: ghoygG1jQPKdXyJ+vhJ5xg== X-CSE-MsgGUID: DIvNxjVCREyxxFMCAxWv1A== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.12,224,1728975600"; d="scan'208";a="126962606" Received: from ideak-desk.fi.intel.com ([10.237.72.78]) by smtpauth.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 Dec 2024 15:03:03 -0800 From: Imre Deak To: intel-gfx@lists.freedesktop.org Cc: dri-devel@lists.freedesktop.org, Maxime Ripard Subject: [PATCH v3 09/11] drm/tests: Add tests for drm_connector_dynamic_init()/register() Date: Thu, 12 Dec 2024 01:03:26 +0200 Message-ID: <20241211230328.4012496-10-imre.deak@intel.com> X-Mailer: git-send-email 2.44.2 In-Reply-To: <20241211230328.4012496-1-imre.deak@intel.com> References: <20241211230328.4012496-1-imre.deak@intel.com> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Add kunit tests for drm_connector_dynamic_init()/drm_connector_dynamic_register() added in this patchset. Suggested-by: Maxime Ripard Signed-off-by: Imre Deak Reviewed-by: Maxime Ripard --- drivers/gpu/drm/tests/drm_connector_test.c | 463 +++++++++++++++++++++ 1 file changed, 463 insertions(+) diff --git a/drivers/gpu/drm/tests/drm_connector_test.c b/drivers/gpu/drm/tests/drm_connector_test.c index 6bba97d0be88e..129e813cfd1b0 100644 --- a/drivers/gpu/drm/tests/drm_connector_test.c +++ b/drivers/gpu/drm/tests/drm_connector_test.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -181,6 +182,465 @@ static struct kunit_suite drmm_connector_init_test_suite = { .test_cases = drmm_connector_init_tests, }; +static const struct drm_connector_funcs dummy_dynamic_init_funcs = { + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, + .reset = drm_atomic_helper_connector_reset, + .destroy = drm_connector_cleanup, +}; + +/* + * Test that the initialization of a bog standard dynamic connector works + * as expected and doesn't report any error. + */ +static void drm_test_drm_connector_dynamic_init(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + struct drm_connector *connector = &priv->connector; + int ret; + + ret = drm_connector_dynamic_init(&priv->drm, connector, + &dummy_dynamic_init_funcs, + DRM_MODE_CONNECTOR_DisplayPort, + &priv->ddc); + KUNIT_ASSERT_EQ(test, ret, 0); +} + +static void drm_test_connector_dynamic_init_cleanup(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + struct drm_connector *connector = &priv->connector; + + drm_connector_cleanup(connector); +} + +/* + * Test that the initialization of a dynamic connector without a DDC adapter + * doesn't report any error. + */ +static void drm_test_drm_connector_dynamic_init_null_ddc(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + struct drm_connector *connector = &priv->connector; + int ret; + + ret = drm_connector_dynamic_init(&priv->drm, connector, + &dummy_dynamic_init_funcs, + DRM_MODE_CONNECTOR_DisplayPort, + NULL); + KUNIT_ASSERT_EQ(test, ret, 0); +} + +/* + * Test that the initialization of a dynamic connector doesn't add the + * connector to the connector list. + */ +static void drm_test_drm_connector_dynamic_init_not_added(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + struct drm_connector *connector = &priv->connector; + int ret; + + ret = drm_connector_dynamic_init(&priv->drm, connector, + &dummy_dynamic_init_funcs, + DRM_MODE_CONNECTOR_DisplayPort, + &priv->ddc); + KUNIT_ASSERT_EQ(test, ret, 0); + KUNIT_ASSERT_PTR_EQ(test, connector->head.next, &connector->head); +} + +static void test_connector_property(struct kunit *test, + struct drm_connector *connector, + const struct drm_property *expected_prop) +{ + struct drm_property *prop; + uint64_t val; + int ret; + + KUNIT_ASSERT_NOT_NULL(test, expected_prop); + prop = drm_mode_obj_find_prop_id(&connector->base, expected_prop->base.id); + KUNIT_ASSERT_PTR_EQ_MSG(test, prop, expected_prop, + "Can't find property %s", expected_prop->name); + + ret = drm_object_property_get_default_value(&connector->base, prop, &val); + KUNIT_EXPECT_EQ(test, ret, 0); + KUNIT_EXPECT_EQ(test, val, 0); + + /* TODO: Check property value in the connector state. */ +} + +/* + * Test that the initialization of a dynamic connector adds all the expected + * properties to it. + */ +static void drm_test_drm_connector_dynamic_init_properties(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + struct drm_connector *connector = &priv->connector; + struct drm_mode_config *config = &priv->drm.mode_config; + const struct drm_property *props[] = { + config->edid_property, + config->dpms_property, + config->link_status_property, + config->non_desktop_property, + config->tile_property, + config->prop_crtc_id, + }; + int ret; + int i; + + ret = drm_connector_dynamic_init(&priv->drm, connector, + &dummy_dynamic_init_funcs, + DRM_MODE_CONNECTOR_DisplayPort, + &priv->ddc); + KUNIT_ASSERT_EQ(test, ret, 0); + + for (i = 0; i < ARRAY_SIZE(props); i++) + test_connector_property(test, connector, props[i]); +} + +/* + * Test that the initialization of a dynamic connector succeeds for all + * possible connector types. + */ +static void drm_test_drm_connector_dynamic_init_type_valid(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + struct drm_connector *connector = &priv->connector; + unsigned int connector_type = *(unsigned int *)test->param_value; + int ret; + + ret = drm_connector_dynamic_init(&priv->drm, connector, + &dummy_dynamic_init_funcs, + connector_type, + &priv->ddc); + KUNIT_ASSERT_EQ(test, ret, 0); +} + +/* + * Test that the initialization of a dynamic connector sets the expected name + * for it for all possible connector types. + */ +static void drm_test_drm_connector_dynamic_init_name(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + struct drm_connector *connector = &priv->connector; + unsigned int connector_type = *(unsigned int *)test->param_value; + char expected_name[128]; + int ret; + + ret = drm_connector_dynamic_init(&priv->drm, connector, + &dummy_dynamic_init_funcs, + connector_type, + &priv->ddc); + KUNIT_ASSERT_EQ(test, ret, 0); + + snprintf(expected_name, sizeof(expected_name), "%s-%d", + drm_get_connector_type_name(connector_type), connector->connector_type_id); + KUNIT_ASSERT_STREQ(test, connector->name, expected_name); +} + +static struct kunit_case drm_connector_dynamic_init_tests[] = { + KUNIT_CASE(drm_test_drm_connector_dynamic_init), + KUNIT_CASE(drm_test_drm_connector_dynamic_init_null_ddc), + KUNIT_CASE(drm_test_drm_connector_dynamic_init_not_added), + KUNIT_CASE(drm_test_drm_connector_dynamic_init_properties), + KUNIT_CASE_PARAM(drm_test_drm_connector_dynamic_init_type_valid, + drm_connector_init_type_valid_gen_params), + KUNIT_CASE_PARAM(drm_test_drm_connector_dynamic_init_name, + drm_connector_init_type_valid_gen_params), + {} +}; + +static struct kunit_suite drm_connector_dynamic_init_test_suite = { + .name = "drm_connector_dynamic_init", + .init = drm_test_connector_init, + .exit = drm_test_connector_dynamic_init_cleanup, + .test_cases = drm_connector_dynamic_init_tests, +}; + +static int drm_test_connector_dynamic_register_early_init(struct kunit *test) +{ + struct drm_connector_init_priv *priv; + int ret; + + ret = drm_test_connector_init(test); + KUNIT_ASSERT_EQ(test, ret, 0); + + priv = test->priv; + + ret = drm_connector_dynamic_init(&priv->drm, &priv->connector, + &dummy_dynamic_init_funcs, + DRM_MODE_CONNECTOR_DisplayPort, + &priv->ddc); + KUNIT_ASSERT_EQ(test, ret, 0); + + return 0; +} + +static void drm_test_connector_dynamic_register_early_cleanup(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + struct drm_connector *connector = &priv->connector; + + drm_connector_unregister(connector); + drm_connector_put(connector); +} + +/* + * Test that registration of a dynamic connector adds it to the connector list. + */ +static void drm_test_drm_connector_dynamic_register_early_on_list(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + struct drm_connector *connector = &priv->connector; + int ret; + + KUNIT_ASSERT_TRUE(test, list_empty(&connector->head)); + + ret = drm_connector_dynamic_register(connector); + KUNIT_ASSERT_EQ(test, ret, 0); + + KUNIT_ASSERT_PTR_EQ(test, connector->head.next, &priv->drm.mode_config.connector_list); +} + +/* + * Test that the registration of a dynamic connector before the drm device is + * registered results in deferring the connector's user interface registration. + */ +static void drm_test_drm_connector_dynamic_register_early_defer(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + struct drm_connector *connector = &priv->connector; + int ret; + + ret = drm_connector_dynamic_register(connector); + KUNIT_ASSERT_EQ(test, ret, 0); + + KUNIT_ASSERT_EQ(test, connector->registration_state, DRM_CONNECTOR_INITIALIZING); +} + +/* + * Test that the registration of a dynamic connector fails, if this is done before + * the connector is initialized. + */ +static void drm_test_drm_connector_dynamic_register_early_no_init(struct kunit *test) +{ + struct drm_connector *connector; + int ret; + + connector = kunit_kzalloc(test, sizeof(*connector), GFP_KERNEL); /* auto freed */ + KUNIT_ASSERT_NOT_NULL(test, connector); + + ret = drm_connector_dynamic_register(connector); + KUNIT_ASSERT_EQ(test, ret, -EINVAL); +} + +/* + * Test that the registration of a dynamic connector before the drm device is + * registered results in deferring adding a mode object for the connector. + */ +static void drm_test_drm_connector_dynamic_register_early_no_mode_object(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + struct drm_connector *connector = &priv->connector; + struct drm_connector *tmp_connector; + int ret; + + ret = drm_connector_dynamic_register(&priv->connector); + KUNIT_ASSERT_EQ(test, ret, 0); + + tmp_connector = drm_connector_lookup(connector->dev, NULL, connector->base.id); + KUNIT_ASSERT_NULL(test, tmp_connector); +} + +static struct kunit_case drm_connector_dynamic_register_early_tests[] = { + KUNIT_CASE(drm_test_drm_connector_dynamic_register_early_on_list), + KUNIT_CASE(drm_test_drm_connector_dynamic_register_early_defer), + KUNIT_CASE(drm_test_drm_connector_dynamic_register_early_no_init), + KUNIT_CASE(drm_test_drm_connector_dynamic_register_early_no_mode_object), + { } +}; + +static struct kunit_suite drm_connector_dynamic_register_early_test_suite = { + .name = "drm_connector_dynamic_register_early", + .init = drm_test_connector_dynamic_register_early_init, + .exit = drm_test_connector_dynamic_register_early_cleanup, + .test_cases = drm_connector_dynamic_register_early_tests, +}; + +static int drm_test_connector_dynamic_register_init(struct kunit *test) +{ + struct drm_connector_init_priv *priv; + int ret; + + ret = drm_test_connector_dynamic_register_early_init(test); + KUNIT_ASSERT_EQ(test, ret, 0); + + priv = test->priv; + + ret = drm_dev_register(priv->connector.dev, 0); + KUNIT_ASSERT_EQ(test, ret, 0); + + return 0; +} + +static void drm_test_connector_dynamic_register_cleanup(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + struct drm_device *dev = priv->connector.dev; + + drm_connector_unregister(&priv->connector); + drm_connector_put(&priv->connector); + + drm_dev_unregister(dev); + + drm_test_connector_dynamic_register_early_cleanup(test); +} + +static void drm_test_drm_connector_dynamic_register_on_list(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + int ret; + + KUNIT_ASSERT_TRUE(test, list_empty(&priv->connector.head)); + + ret = drm_connector_dynamic_register(&priv->connector); + KUNIT_ASSERT_EQ(test, ret, 0); + + KUNIT_ASSERT_PTR_EQ(test, priv->connector.head.next, &priv->drm.mode_config.connector_list); +} + +/* + * Test that the registration of a dynamic connector doesn't get deferred if + * this is done after the drm device is registered. + */ +static void drm_test_drm_connector_dynamic_register_no_defer(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + int ret; + + KUNIT_ASSERT_EQ(test, priv->connector.registration_state, DRM_CONNECTOR_INITIALIZING); + + ret = drm_connector_dynamic_register(&priv->connector); + KUNIT_ASSERT_EQ(test, ret, 0); + + KUNIT_ASSERT_EQ(test, priv->connector.registration_state, DRM_CONNECTOR_REGISTERED); +} + +/* + * Test that the registration of a dynamic connector fails if this is done after the + * drm device is registered, but before the connector is initialized. + */ +static void drm_test_drm_connector_dynamic_register_no_init(struct kunit *test) +{ + struct drm_connector *connector; + int ret; + + connector = kunit_kzalloc(test, sizeof(*connector), GFP_KERNEL); /* auto freed */ + KUNIT_ASSERT_NOT_NULL(test, connector); + + ret = drm_connector_dynamic_register(connector); + KUNIT_ASSERT_EQ(test, ret, -EINVAL); +} + +/* + * Test that the registration of a dynamic connector after the drm device is + * registered adds the mode object for the connector. + */ +static void drm_test_drm_connector_dynamic_register_mode_object(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + struct drm_connector *connector = &priv->connector; + struct drm_connector *tmp_connector; + int ret; + + tmp_connector = drm_connector_lookup(connector->dev, NULL, connector->base.id); + KUNIT_ASSERT_NULL(test, tmp_connector); + + ret = drm_connector_dynamic_register(&priv->connector); + KUNIT_ASSERT_EQ(test, ret, 0); + + tmp_connector = drm_connector_lookup(connector->dev, NULL, connector->base.id); + KUNIT_ASSERT_PTR_EQ(test, tmp_connector, connector); +} + +/* + * Test that the registration of a dynamic connector after the drm device is + * registered adds the connector to sysfs. + */ +static void drm_test_drm_connector_dynamic_register_sysfs(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + struct drm_connector *connector = &priv->connector; + int ret; + + KUNIT_ASSERT_NULL(test, connector->kdev); + + ret = drm_connector_dynamic_register(connector); + KUNIT_ASSERT_EQ(test, ret, 0); + + KUNIT_ASSERT_NOT_NULL(test, connector->kdev); +} + +/* + * Test that the registration of a dynamic connector after the drm device is + * registered sets the connector's sysfs name as expected. + */ +static void drm_test_drm_connector_dynamic_register_sysfs_name(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + struct drm_connector *connector = &priv->connector; + char expected_name[128]; + int ret; + + ret = drm_connector_dynamic_register(connector); + KUNIT_ASSERT_EQ(test, ret, 0); + + snprintf(expected_name, sizeof(expected_name), "card%d-%s", + connector->dev->primary->index, connector->name); + + KUNIT_ASSERT_STREQ(test, dev_name(connector->kdev), expected_name); +} + +/* + * Test that the registration of a dynamic connector after the drm device is + * registered adds the connector to debugfs. + */ +static void drm_test_drm_connector_dynamic_register_debugfs(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + int ret; + + KUNIT_ASSERT_NULL(test, priv->connector.debugfs_entry); + + ret = drm_connector_dynamic_register(&priv->connector); + KUNIT_ASSERT_EQ(test, ret, 0); + + if (IS_ENABLED(CONFIG_DEBUG_FS)) + KUNIT_ASSERT_NOT_NULL(test, priv->connector.debugfs_entry); + else + KUNIT_ASSERT_NULL(test, priv->connector.debugfs_entry); +} + +static struct kunit_case drm_connector_dynamic_register_tests[] = { + KUNIT_CASE(drm_test_drm_connector_dynamic_register_on_list), + KUNIT_CASE(drm_test_drm_connector_dynamic_register_no_defer), + KUNIT_CASE(drm_test_drm_connector_dynamic_register_no_init), + KUNIT_CASE(drm_test_drm_connector_dynamic_register_mode_object), + KUNIT_CASE(drm_test_drm_connector_dynamic_register_sysfs), + KUNIT_CASE(drm_test_drm_connector_dynamic_register_sysfs_name), + KUNIT_CASE(drm_test_drm_connector_dynamic_register_debugfs), + { } +}; + +static struct kunit_suite drm_connector_dynamic_register_test_suite = { + .name = "drm_connector_dynamic_register", + .init = drm_test_connector_dynamic_register_init, + .exit = drm_test_connector_dynamic_register_cleanup, + .test_cases = drm_connector_dynamic_register_tests, +}; + /* * Test that the registration of a bog standard connector works as * expected and doesn't report any error. @@ -1283,6 +1743,9 @@ static struct kunit_suite drm_hdmi_compute_mode_clock_test_suite = { kunit_test_suites( &drmm_connector_hdmi_init_test_suite, &drmm_connector_init_test_suite, + &drm_connector_dynamic_init_test_suite, + &drm_connector_dynamic_register_early_test_suite, + &drm_connector_dynamic_register_test_suite, &drm_connector_attach_broadcast_rgb_property_test_suite, &drm_get_tv_mode_from_name_test_suite, &drm_hdmi_compute_mode_clock_test_suite, From patchwork Wed Dec 11 23:03:27 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Imre Deak X-Patchwork-Id: 13904329 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id D2CDCE7717D for ; Wed, 11 Dec 2024 23:03:13 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 5704010EC67; Wed, 11 Dec 2024 23:03:13 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.b="j0Nmo74G"; dkim-atps=neutral Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.17]) by gabe.freedesktop.org (Postfix) with ESMTPS id 7170610EC58; Wed, 11 Dec 2024 23:03:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1733958188; x=1765494188; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=9hpvom8gqM7VbLowtit27JJWQ8Psc7stb5VXmDwJz/0=; b=j0Nmo74GkKUl13diUfQdW3NVdy5UDxNyobhY6nGzatE5sd9K+mqKZf+z OD1mZ032HPkMFL8unc4phSPfWMmhBeCOKrCOiMxx2CwpHU5gEVxSxo3Ic AMYrK2mEmq4DaOCQx+zFP4dsg+vI1o7fPDb0rkYYVR6IPNdjU+wJeIa9l g1Lf/6Ua6RZxgHhSyat1b8tCf0TLoXdQpwc3+/semVo8oouRZVwU2adxo /d6u4W6CCMzR3pOie9rxaVElUhv2ebGi7K3VtalKKfjeRbNrhhnyzh8dt maRVpKTZOjvVddMNojAVEjqZWgJw1I7GJjxnpZ9P3XQzvEFWBKgrf6ax2 A==; X-CSE-ConnectionGUID: nAJNv0HETlqmDS4XbQQ+nw== X-CSE-MsgGUID: YTIbN3FkTQSqIlGs2n8XyQ== X-IronPort-AV: E=McAfee;i="6700,10204,11283"; a="34401517" X-IronPort-AV: E=Sophos;i="6.12,226,1728975600"; d="scan'208";a="34401517" Received: from fmviesa001.fm.intel.com ([10.60.135.141]) by orvoesa109.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 Dec 2024 15:03:08 -0800 X-CSE-ConnectionGUID: DFqF02aYSyqhsq47oQrGdQ== X-CSE-MsgGUID: +cHKP3haQ3aERcOaY/Pqtw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.12,224,1728975600"; d="scan'208";a="126962728" Received: from ideak-desk.fi.intel.com ([10.237.72.78]) by smtpauth.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 Dec 2024 15:03:05 -0800 From: Imre Deak To: intel-gfx@lists.freedesktop.org Cc: dri-devel@lists.freedesktop.org, Rodrigo Vivi Subject: [PATCH v3 10/11] drm/i915/dp_mst: Fix error handling while adding a connector Date: Thu, 12 Dec 2024 01:03:27 +0200 Message-ID: <20241211230328.4012496-11-imre.deak@intel.com> X-Mailer: git-send-email 2.44.2 In-Reply-To: <20241211230328.4012496-1-imre.deak@intel.com> References: <20241211230328.4012496-1-imre.deak@intel.com> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" After an error during adding an MST connector the MST port and the intel_connector object could be leaked, fix this up. Reviewed-by: Rodrigo Vivi Signed-off-by: Imre Deak Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index debe4d0eee11f..99f08e31fd6e0 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -1743,11 +1743,8 @@ mst_topology_add_connector(struct drm_dp_mst_topology_mgr *mgr, ret = drm_connector_dynamic_init(display->drm, connector, &mst_connector_funcs, DRM_MODE_CONNECTOR_DisplayPort, NULL); - if (ret) { - drm_dp_mst_put_port_malloc(port); - intel_connector_free(intel_connector); - return NULL; - } + if (ret) + goto err_put_port; intel_connector->dp.dsc_decompression_aux = drm_dp_mst_dsc_aux_for_port(port); intel_dp_mst_read_decompression_port_dsc_caps(intel_dp, intel_connector); @@ -1762,12 +1759,12 @@ mst_topology_add_connector(struct drm_dp_mst_topology_mgr *mgr, ret = drm_connector_attach_encoder(&intel_connector->base, enc); if (ret) - goto err; + goto err_cleanup_connector; } ret = mst_topology_add_connector_properties(intel_dp, connector, pathprop); if (ret) - goto err; + goto err_cleanup_connector; ret = intel_dp_hdcp_init(dig_port, intel_connector); if (ret) @@ -1776,8 +1773,12 @@ mst_topology_add_connector(struct drm_dp_mst_topology_mgr *mgr, return connector; -err: +err_cleanup_connector: drm_connector_cleanup(connector); +err_put_port: + drm_dp_mst_put_port_malloc(port); + intel_connector_free(intel_connector); + return NULL; } From patchwork Wed Dec 11 23:03:28 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Imre Deak X-Patchwork-Id: 13904330 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 852DFE77182 for ; Wed, 11 Dec 2024 23:03:14 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id B029110EC68; Wed, 11 Dec 2024 23:03:13 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.b="THLcBzcm"; dkim-atps=neutral Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.17]) by gabe.freedesktop.org (Postfix) with ESMTPS id BE9EC10EC63; Wed, 11 Dec 2024 23:03:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1733958190; x=1765494190; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=55JTnV9Cdst5xCwsFFgXYafPTCuQTDceK7wRLpkppfw=; b=THLcBzcmEEGfkYBbZGkX4/yPW8KvpDK/pTC9ajRiwcqVf0K6hlU2q+dF hAzLJCSKXNQCZuEXh3v4dNP1vMjld8AWKAPPX/fS+GqGJ23Vd8bbzC7NZ UE0COm8VsVozhLlqfMaQJeA/95sPa0/vPJdGJyaH25N2FsqGBlVWCpJ4g T459wrUAc8YZVURo8tRVkp+w2COlRE8SvisIA8CQp444GgcXm4SNeeNdg 36F28S/axRB7moVQGVmwGpF2bkM1b1Aml+hd2PUczmP3Im3dyn4xNiC4c oD0kyLmZS/82/5NFHnsIkh6d7Bd36GVQA6PWKRD0ZHQBRAMFg4l1LhdHY w==; X-CSE-ConnectionGUID: JxG9pNYkQsWhMvMxtEogBw== X-CSE-MsgGUID: 7JjOHMPmT0KY0LzagKQRJg== X-IronPort-AV: E=McAfee;i="6700,10204,11283"; a="34401518" X-IronPort-AV: E=Sophos;i="6.12,226,1728975600"; d="scan'208";a="34401518" Received: from fmviesa001.fm.intel.com ([10.60.135.141]) by orvoesa109.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 Dec 2024 15:03:10 -0800 X-CSE-ConnectionGUID: 4joVMooPRmWcRMh3qQosiQ== X-CSE-MsgGUID: rJ9voqCVTL+Oje3j5W6O5A== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.12,224,1728975600"; d="scan'208";a="126962840" Received: from ideak-desk.fi.intel.com ([10.237.72.78]) by smtpauth.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 Dec 2024 15:03:06 -0800 From: Imre Deak To: intel-gfx@lists.freedesktop.org Cc: dri-devel@lists.freedesktop.org, Jani Nikula Subject: [PATCH v3 11/11] drm/i915/dp_mst: Use intel_connector vs. drm_connector pointer in intel_dp_mst.c Date: Thu, 12 Dec 2024 01:03:28 +0200 Message-ID: <20241211230328.4012496-12-imre.deak@intel.com> X-Mailer: git-send-email 2.44.2 In-Reply-To: <20241211230328.4012496-1-imre.deak@intel.com> References: <20241211230328.4012496-1-imre.deak@intel.com> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Follow the canonical way in intel_dp_mst.c, referencing a connector only via a struct intel_connector pointer and naming this pointer 'connector' instead of 'intel_connector', the only exception being the casting of a drm_connector function parameter pointer to intel_connector, calling the drm_connector pointer _connector. Suggested-by: Jani Nikula Signed-off-by: Imre Deak Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 180 ++++++++++---------- 1 file changed, 88 insertions(+), 92 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 99f08e31fd6e0..44cc54a87067a 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -969,33 +969,32 @@ mst_connector_atomic_topology_check(struct intel_connector *connector, } static int -mst_connector_atomic_check(struct drm_connector *connector, +mst_connector_atomic_check(struct drm_connector *_connector, struct drm_atomic_state *_state) { struct intel_atomic_state *state = to_intel_atomic_state(_state); - struct intel_connector *intel_connector = - to_intel_connector(connector); + struct intel_connector *connector = to_intel_connector(_connector); int ret; - ret = intel_digital_connector_atomic_check(connector, &state->base); + ret = intel_digital_connector_atomic_check(&connector->base, &state->base); if (ret) return ret; - ret = mst_connector_atomic_topology_check(intel_connector, state); + ret = mst_connector_atomic_topology_check(connector, state); if (ret) return ret; - if (intel_connector_needs_modeset(state, connector)) { + if (intel_connector_needs_modeset(state, &connector->base)) { ret = intel_dp_tunnel_atomic_check_state(state, - intel_connector->mst_port, - intel_connector); + connector->mst_port, + connector); if (ret) return ret; } return drm_dp_atomic_release_time_slots(&state->base, - &intel_connector->mst_port->mst_mgr, - intel_connector->port); + &connector->mst_port->mst_mgr, + connector->port); } static void mst_stream_disable(struct intel_atomic_state *state, @@ -1375,23 +1374,23 @@ static bool mst_stream_initial_fastset_check(struct intel_encoder *encoder, return intel_dp_initial_fastset_check(primary_encoder, crtc_state); } -static int mst_connector_get_ddc_modes(struct drm_connector *connector) +static int mst_connector_get_ddc_modes(struct drm_connector *_connector) { - struct intel_display *display = to_intel_display(connector->dev); - struct intel_connector *intel_connector = to_intel_connector(connector); - struct intel_dp *intel_dp = intel_connector->mst_port; + struct intel_connector *connector = to_intel_connector(_connector); + struct intel_display *display = to_intel_display(connector->base.dev); + struct intel_dp *intel_dp = connector->mst_port; const struct drm_edid *drm_edid; int ret; - if (drm_connector_is_unregistered(connector)) - return intel_connector_update_modes(connector, NULL); + if (drm_connector_is_unregistered(&connector->base)) + return intel_connector_update_modes(&connector->base, NULL); if (!intel_display_driver_check_access(display)) - return drm_edid_connector_add_modes(connector); + return drm_edid_connector_add_modes(&connector->base); - drm_edid = drm_dp_mst_edid_read(connector, &intel_dp->mst_mgr, intel_connector->port); + drm_edid = drm_dp_mst_edid_read(&connector->base, &intel_dp->mst_mgr, connector->port); - ret = intel_connector_update_modes(connector, drm_edid); + ret = intel_connector_update_modes(&connector->base, drm_edid); drm_edid_free(drm_edid); @@ -1399,32 +1398,29 @@ static int mst_connector_get_ddc_modes(struct drm_connector *connector) } static int -mst_connector_late_register(struct drm_connector *connector) +mst_connector_late_register(struct drm_connector *_connector) { - struct intel_connector *intel_connector = to_intel_connector(connector); + struct intel_connector *connector = to_intel_connector(_connector); int ret; - ret = drm_dp_mst_connector_late_register(connector, - intel_connector->port); + ret = drm_dp_mst_connector_late_register(&connector->base, connector->port); if (ret < 0) return ret; - ret = intel_connector_register(connector); + ret = intel_connector_register(&connector->base); if (ret < 0) - drm_dp_mst_connector_early_unregister(connector, - intel_connector->port); + drm_dp_mst_connector_early_unregister(&connector->base, connector->port); return ret; } static void -mst_connector_early_unregister(struct drm_connector *connector) +mst_connector_early_unregister(struct drm_connector *_connector) { - struct intel_connector *intel_connector = to_intel_connector(connector); + struct intel_connector *connector = to_intel_connector(_connector); - intel_connector_unregister(connector); - drm_dp_mst_connector_early_unregister(connector, - intel_connector->port); + intel_connector_unregister(&connector->base); + drm_dp_mst_connector_early_unregister(&connector->base, connector->port); } static const struct drm_connector_funcs mst_connector_funcs = { @@ -1438,23 +1434,25 @@ static const struct drm_connector_funcs mst_connector_funcs = { .atomic_duplicate_state = intel_digital_connector_duplicate_state, }; -static int mst_connector_get_modes(struct drm_connector *connector) +static int mst_connector_get_modes(struct drm_connector *_connector) { - return mst_connector_get_ddc_modes(connector); + struct intel_connector *connector = to_intel_connector(_connector); + + return mst_connector_get_ddc_modes(&connector->base); } static int -mst_connector_mode_valid_ctx(struct drm_connector *connector, +mst_connector_mode_valid_ctx(struct drm_connector *_connector, struct drm_display_mode *mode, struct drm_modeset_acquire_ctx *ctx, enum drm_mode_status *status) { - struct intel_display *display = to_intel_display(connector->dev); - struct drm_i915_private *dev_priv = to_i915(connector->dev); - struct intel_connector *intel_connector = to_intel_connector(connector); - struct intel_dp *intel_dp = intel_connector->mst_port; + struct intel_connector *connector = to_intel_connector(_connector); + struct intel_display *display = to_intel_display(connector->base.dev); + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct intel_dp *intel_dp = connector->mst_port; struct drm_dp_mst_topology_mgr *mgr = &intel_dp->mst_mgr; - struct drm_dp_mst_port *port = intel_connector->port; + struct drm_dp_mst_port *port = connector->port; const int min_bpp = 18; int max_dotclk = display->cdclk.max_dotclk_freq; int max_rate, mode_rate, max_lanes, max_link_clock; @@ -1465,7 +1463,7 @@ mst_connector_mode_valid_ctx(struct drm_connector *connector, int target_clock = mode->clock; int num_joined_pipes; - if (drm_connector_is_unregistered(connector)) { + if (drm_connector_is_unregistered(&connector->base)) { *status = MODE_ERROR; return 0; } @@ -1503,7 +1501,7 @@ mst_connector_mode_valid_ctx(struct drm_connector *connector, * corresponding link capabilities of the sink) in case the * stream is uncompressed for it by the last branch device. */ - num_joined_pipes = intel_dp_num_joined_pipes(intel_dp, intel_connector, + num_joined_pipes = intel_dp_num_joined_pipes(intel_dp, connector, mode->hdisplay, target_clock); max_dotclk *= num_joined_pipes; @@ -1517,14 +1515,14 @@ mst_connector_mode_valid_ctx(struct drm_connector *connector, return 0; } - if (intel_dp_has_dsc(intel_connector)) { + if (intel_dp_has_dsc(connector)) { /* * TBD pass the connector BPC, * for now U8_MAX so that max BPC on that platform would be picked */ - int pipe_bpp = intel_dp_dsc_compute_max_bpp(intel_connector, U8_MAX); + int pipe_bpp = intel_dp_dsc_compute_max_bpp(connector, U8_MAX); - if (drm_dp_sink_supports_fec(intel_connector->dp.fec_capability)) { + if (drm_dp_sink_supports_fec(connector->dp.fec_capability)) { dsc_max_compressed_bpp = intel_dp_dsc_get_max_compressed_bpp(dev_priv, max_link_clock, @@ -1535,7 +1533,7 @@ mst_connector_mode_valid_ctx(struct drm_connector *connector, INTEL_OUTPUT_FORMAT_RGB, pipe_bpp, 64); dsc_slice_count = - intel_dp_dsc_get_slice_count(intel_connector, + intel_dp_dsc_get_slice_count(connector, target_clock, mode->hdisplay, num_joined_pipes); @@ -1559,39 +1557,39 @@ mst_connector_mode_valid_ctx(struct drm_connector *connector, } static struct drm_encoder * -mst_connector_atomic_best_encoder(struct drm_connector *connector, +mst_connector_atomic_best_encoder(struct drm_connector *_connector, struct drm_atomic_state *state) { - struct drm_connector_state *connector_state = drm_atomic_get_new_connector_state(state, - connector); - struct intel_connector *intel_connector = to_intel_connector(connector); - struct intel_dp *intel_dp = intel_connector->mst_port; + struct intel_connector *connector = to_intel_connector(_connector); + struct drm_connector_state *connector_state = + drm_atomic_get_new_connector_state(state, &connector->base); + struct intel_dp *intel_dp = connector->mst_port; struct intel_crtc *crtc = to_intel_crtc(connector_state->crtc); return &intel_dp->mst_encoders[crtc->pipe]->base.base; } static int -mst_connector_detect_ctx(struct drm_connector *connector, +mst_connector_detect_ctx(struct drm_connector *_connector, struct drm_modeset_acquire_ctx *ctx, bool force) { - struct intel_display *display = to_intel_display(connector->dev); - struct intel_connector *intel_connector = to_intel_connector(connector); - struct intel_dp *intel_dp = intel_connector->mst_port; + struct intel_connector *connector = to_intel_connector(_connector); + struct intel_display *display = to_intel_display(connector->base.dev); + struct intel_dp *intel_dp = connector->mst_port; if (!intel_display_device_enabled(display)) return connector_status_disconnected; - if (drm_connector_is_unregistered(connector)) + if (drm_connector_is_unregistered(&connector->base)) return connector_status_disconnected; if (!intel_display_driver_check_access(display)) - return connector->status; + return connector->base.status; - intel_dp_flush_connector_commits(intel_connector); + intel_dp_flush_connector_commits(connector); - return drm_dp_mst_detect_port(connector, ctx, &intel_dp->mst_mgr, - intel_connector->port); + return drm_dp_mst_detect_port(&connector->base, ctx, &intel_dp->mst_mgr, + connector->port); } static const struct drm_connector_helper_funcs mst_connector_helper_funcs = { @@ -1627,29 +1625,30 @@ static bool mst_connector_get_hw_state(struct intel_connector *connector) } static int mst_topology_add_connector_properties(struct intel_dp *intel_dp, - struct drm_connector *connector, + struct drm_connector *_connector, const char *pathprop) { struct intel_display *display = to_intel_display(intel_dp); + struct intel_connector *connector = to_intel_connector(_connector); - drm_object_attach_property(&connector->base, + drm_object_attach_property(&connector->base.base, display->drm->mode_config.path_property, 0); - drm_object_attach_property(&connector->base, + drm_object_attach_property(&connector->base.base, display->drm->mode_config.tile_property, 0); - intel_attach_force_audio_property(connector); - intel_attach_broadcast_rgb_property(connector); + intel_attach_force_audio_property(&connector->base); + intel_attach_broadcast_rgb_property(&connector->base); /* * Reuse the prop from the SST connector because we're * not allowed to create new props after device registration. */ - connector->max_bpc_property = + connector->base.max_bpc_property = intel_dp->attached_connector->base.max_bpc_property; - if (connector->max_bpc_property) - drm_connector_attach_max_bpc_property(connector, 6, 12); + if (connector->base.max_bpc_property) + drm_connector_attach_max_bpc_property(&connector->base, 6, 12); - return drm_connector_set_path_property(connector, pathprop); + return drm_connector_set_path_property(&connector->base, pathprop); } static void @@ -1722,62 +1721,59 @@ mst_topology_add_connector(struct drm_dp_mst_topology_mgr *mgr, struct intel_dp *intel_dp = container_of(mgr, struct intel_dp, mst_mgr); struct intel_display *display = to_intel_display(intel_dp); struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); - struct intel_connector *intel_connector; - struct drm_connector *connector; + struct intel_connector *connector; enum pipe pipe; int ret; - intel_connector = intel_connector_alloc(); - if (!intel_connector) + connector = intel_connector_alloc(); + if (!connector) return NULL; - connector = &intel_connector->base; - - intel_connector->get_hw_state = mst_connector_get_hw_state; - intel_connector->sync_state = intel_dp_connector_sync_state; - intel_connector->mst_port = intel_dp; - intel_connector->port = port; + connector->get_hw_state = mst_connector_get_hw_state; + connector->sync_state = intel_dp_connector_sync_state; + connector->mst_port = intel_dp; + connector->port = port; drm_dp_mst_get_port_malloc(port); - intel_dp_init_modeset_retry_work(intel_connector); + intel_dp_init_modeset_retry_work(connector); - ret = drm_connector_dynamic_init(display->drm, connector, &mst_connector_funcs, + ret = drm_connector_dynamic_init(display->drm, &connector->base, &mst_connector_funcs, DRM_MODE_CONNECTOR_DisplayPort, NULL); if (ret) goto err_put_port; - intel_connector->dp.dsc_decompression_aux = drm_dp_mst_dsc_aux_for_port(port); - intel_dp_mst_read_decompression_port_dsc_caps(intel_dp, intel_connector); - intel_connector->dp.dsc_hblank_expansion_quirk = - detect_dsc_hblank_expansion_quirk(intel_connector); + connector->dp.dsc_decompression_aux = drm_dp_mst_dsc_aux_for_port(port); + intel_dp_mst_read_decompression_port_dsc_caps(intel_dp, connector); + connector->dp.dsc_hblank_expansion_quirk = + detect_dsc_hblank_expansion_quirk(connector); - drm_connector_helper_add(connector, &mst_connector_helper_funcs); + drm_connector_helper_add(&connector->base, &mst_connector_helper_funcs); for_each_pipe(display, pipe) { struct drm_encoder *enc = &intel_dp->mst_encoders[pipe]->base.base; - ret = drm_connector_attach_encoder(&intel_connector->base, enc); + ret = drm_connector_attach_encoder(&connector->base, enc); if (ret) goto err_cleanup_connector; } - ret = mst_topology_add_connector_properties(intel_dp, connector, pathprop); + ret = mst_topology_add_connector_properties(intel_dp, &connector->base, pathprop); if (ret) goto err_cleanup_connector; - ret = intel_dp_hdcp_init(dig_port, intel_connector); + ret = intel_dp_hdcp_init(dig_port, connector); if (ret) drm_dbg_kms(display->drm, "[%s:%d] HDCP MST init failed, skipping.\n", - connector->name, connector->base.id); + connector->base.name, connector->base.base.id); - return connector; + return &connector->base; err_cleanup_connector: - drm_connector_cleanup(connector); + drm_connector_cleanup(&connector->base); err_put_port: drm_dp_mst_put_port_malloc(port); - intel_connector_free(intel_connector); + intel_connector_free(connector); return NULL; }