From nobody Mon Feb 9 19:26:32 2026 Received: from mail-wr1-f51.google.com (mail-wr1-f51.google.com [209.85.221.51]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A3E4E1B6CE8 for ; Wed, 29 Jan 2025 11:01:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738148483; cv=none; b=CpOdrA0E+qDp/uyFvclQrR9MRVOIqnZZ3EUsydB0pWlGh52j7TsRZIsAsc5NELvcGXX4M/bgpXUahPd8Z3VevySDCehL34wdwNBaWW5CS++eHBbGQYxs5Xs9MYhHFt1hHw6IMvo+r0PfapTwljgnChkXjNHOsmn7eMWFwHThoXQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738148483; c=relaxed/simple; bh=bwkOgbSp2DlzaYVVLPsg1YWMggL4kTAYXaaduWdo1to=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=UKyMF4ss9B9kH6gYh7L1Tm2IfK88PtH6cCrQI+5DvmKnDLXq7Z/S7jIB2dLQTEsrJzp1muYNKYgHHINDsXzryjwDfC4eFryHaGYL4xbql7GzexAFX2dpCQh1A8M1jEou1UR3mNQS55h/uYmJNkPcVUZg4tpwf0j5xOtHd65uLmw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=mmmXFfFS; arc=none smtp.client-ip=209.85.221.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="mmmXFfFS" Received: by mail-wr1-f51.google.com with SMTP id ffacd0b85a97d-385e27c75f4so5825425f8f.2 for ; Wed, 29 Jan 2025 03:01:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1738148479; x=1738753279; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=XUpkYP/tGsoAbjn0vsUGNcgy0Vg9vALDj5dfocC1jjo=; b=mmmXFfFSIW1heV/gXGnhfS/v2Lee4QCne1usNk2fNPn5WwX3wEKlyoyCzNMzcveEnd YcVHLyCf3RmJ9N7s2PiOi+R5Et+ONGOe8aQxwL+90cdwHDpugRPNFmOUE105wHSm94Rk L4UHZSaiW9caDng2U8LuhVGonsqBM4Q0WAbnV3fAdQ4RSw7B6iMpuYMGNC4O4SRDxHhT ChQd8dqVa0+X4aHuWS26hV/zW8V3C/VybsTw+l5p+GFgZxqVJ7hbYjj605xhwxLK6Xej XgVfL0DTmSk66xv8A+0TMx7k9G4PVswKNThYhEkHB9K0JeZUR4H/lQSqsexsBybFC2Yj u1SQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1738148479; x=1738753279; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=XUpkYP/tGsoAbjn0vsUGNcgy0Vg9vALDj5dfocC1jjo=; b=AgpdgA8jc9hbBb0M14J4i4isNlPqHlHY8yfYqy+40ikoUtz3/Y/JexsKVEP2Fp0Gk/ c/uXeuYtcCn8Vg6aWfmSM6x208QY8tihd+z/f+ZkSDi5XCVIEAcnKp1NTVSzhivLy+Lq 80/LBwDyVCXcv4z/wCRs6ojCus9xp/Pb7cbByIYes3DkikLU4bvMLwPsSpl4CNd6NIGd bXc6Y0n9ZRGWkI2J387HWVfvcthitrowEJgVNy+Bhvw65lXHtwIhiZL99Q4TjzRNF4co n4hEehzmWPi8A/NqR3AShpRvXSORgR0OPsOhJ/2CGPG89/GeRjUop6EUUb3crAQBfofx eiVA== X-Forwarded-Encrypted: i=1; AJvYcCXHG68wJwozyKGdqSxAEENKCun/RUXGRmkjIgqQxLfIImY5Uz2wC9DS+9BkA8WXiCwNqmJc17TYN7ay3Is=@vger.kernel.org X-Gm-Message-State: AOJu0YwSbPiUTsQB3uUt/NTx+ZdRVm0WEJhBPJtG8wZDR0shLVJOelTW Oo2wdkdEk9MSjsudNz2lxhMBa3c2U4NQIk96NdJVYHPnrFO20VY+ X-Gm-Gg: ASbGncsDtdwr0y7/PubdWx2N3EOUiGIANAoQDZ+9eceT7CyU3SZllebiD62S+lmkN0R 02wDiPhO207UAJKu7/Ldk7tts/QMStdcWox531gkIsKQdAtppjQr39tuLjcG982p9R30jfzbigQ bG24Br3tfbXCRQwUyvNfVEVslNOX+Mx+EWAW45MlccoakwAZpweXx9iTBHrhCzxb6OCY/KGQ5Nq vFOVVUjWEXmvU0w5hqK1TBJlOgA/A69j2xVtkTbxJcPVToQ4pbi14FSIZXB7GXyTBy90T90Tb0h PmLWGwpoSUB1WXAu40JMCjlgeTM= X-Google-Smtp-Source: AGHT+IEt/RU5BgHN4IuQXOAUZYIJmz+x4OCgxOMAFdg/eovjklOwz0AsxWcDE4GbtSVBFa+HrggMRA== X-Received: by 2002:a5d:5988:0:b0:385:fd07:8616 with SMTP id ffacd0b85a97d-38c5167d80bmr2164396f8f.0.1738148478451; Wed, 29 Jan 2025 03:01:18 -0800 (PST) Received: from fedora.. ([94.73.37.161]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38c2a176434sm16947113f8f.13.2025.01.29.03.01.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 29 Jan 2025 03:01:17 -0800 (PST) From: =?UTF-8?q?Jos=C3=A9=20Exp=C3=B3sito?= To: louis.chauvet@bootlin.com Cc: hamohammed.sa@gmail.com, simona@ffwll.ch, melissa.srw@gmail.com, maarten.lankhorst@linux.intel.com, mripard@kernel.org, tzimmermann@suse.de, airlied@gmail.com, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, =?UTF-8?q?Jos=C3=A9=20Exp=C3=B3sito?= Subject: [PATCH 12/13] drm/vkms: Allow to configure multiple connectors Date: Wed, 29 Jan 2025 12:00:58 +0100 Message-ID: <20250129110059.12199-13-jose.exposito89@gmail.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250129110059.12199-1-jose.exposito89@gmail.com> References: <20250129110059.12199-1-jose.exposito89@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Add a list of connectors to vkms_config and helper functions to add and remove as many connectors as wanted. Unlike planes, CRTCs and encoders, connectors can be added and removed once the device is created. To reflect it, add an "enabled" flag in the configuration and filter disabled connectors in the vkms_config_get_connectors() function. For the moment, changing the enabled status of the connector has no effect after the device is created, but a future patch will add this capability. For backwards compatibility, add one enabled connector to the default configuration. A future patch will allow to attach connectors and encoders, but for the moment there are no changes in the way the output is configured. Signed-off-by: Louis Chauvet Signed-off-by: Jos=C3=A9 Exp=C3=B3sito --- drivers/gpu/drm/vkms/tests/vkms_config_test.c | 84 +++++++++++++++++ drivers/gpu/drm/vkms/vkms_config.c | 93 +++++++++++++++++++ drivers/gpu/drm/vkms/vkms_config.h | 76 +++++++++++++++ drivers/gpu/drm/vkms/vkms_connector.c | 11 +++ 4 files changed, 264 insertions(+) diff --git a/drivers/gpu/drm/vkms/tests/vkms_config_test.c b/drivers/gpu/dr= m/vkms/tests/vkms_config_test.c index 27d44315c2de..40c385eedc1d 100644 --- a/drivers/gpu/drm/vkms/tests/vkms_config_test.c +++ b/drivers/gpu/drm/vkms/tests/vkms_config_test.c @@ -27,6 +27,7 @@ static void vkms_config_test_empty_config(struct kunit *t= est) KUNIT_EXPECT_TRUE(test, list_empty(&config->planes)); KUNIT_EXPECT_TRUE(test, list_empty(&config->crtcs)); KUNIT_EXPECT_TRUE(test, list_empty(&config->encoders)); + KUNIT_EXPECT_TRUE(test, list_empty(&config->connectors)); =20 KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); =20 @@ -52,6 +53,7 @@ static void vkms_config_test_default_config(struct kunit = *test) struct vkms_config *config; struct vkms_config_plane *plane_cfg; struct vkms_config_crtc *crtc_cfg; + struct vkms_config_connector *connector_cfg; int n_primaries =3D 0; int n_cursors =3D 0; int n_overlays =3D 0; @@ -103,6 +105,12 @@ static void vkms_config_test_default_config(struct kun= it *test) /* Encoders */ KUNIT_EXPECT_EQ(test, list_count_nodes(&config->encoders), 1); =20 + /* Connectors */ + KUNIT_EXPECT_EQ(test, list_count_nodes(&config->connectors), 1); + connector_cfg =3D list_first_entry(&config->connectors, + typeof(*connector_cfg), link); + KUNIT_EXPECT_TRUE(test, vkms_config_connector_is_enabled(connector_cfg)); + KUNIT_EXPECT_TRUE(test, vkms_config_is_valid(config)); =20 vkms_config_destroy(config); @@ -216,6 +224,47 @@ static void vkms_config_test_get_encoders(struct kunit= *test) vkms_config_destroy(config); } =20 +static void vkms_config_test_get_connectors(struct kunit *test) +{ + struct vkms_config *config; + struct vkms_config_connector *connector_cfg1, *connector_cfg2; + struct vkms_config_connector **array; + size_t length; + + config =3D vkms_config_create("test"); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); + + array =3D vkms_config_get_connectors(config, &length); + KUNIT_ASSERT_EQ(test, length, 0); + KUNIT_ASSERT_NULL(test, array); + + connector_cfg1 =3D vkms_config_add_connector(config); + array =3D vkms_config_get_connectors(config, &length); + KUNIT_ASSERT_EQ(test, length, 0); + KUNIT_ASSERT_NULL(test, array); + + vkms_config_connector_set_enabled(connector_cfg1, true); + array =3D vkms_config_get_connectors(config, &length); + KUNIT_ASSERT_EQ(test, length, 1); + KUNIT_ASSERT_PTR_EQ(test, array[0], connector_cfg1); + kfree(array); + + connector_cfg2 =3D vkms_config_add_connector(config); + vkms_config_connector_set_enabled(connector_cfg2, true); + array =3D vkms_config_get_connectors(config, &length); + KUNIT_ASSERT_EQ(test, length, 2); + KUNIT_ASSERT_PTR_EQ(test, array[0], connector_cfg1); + KUNIT_ASSERT_PTR_EQ(test, array[1], connector_cfg2); + kfree(array); + + vkms_config_connector_set_enabled(connector_cfg1, false); + vkms_config_destroy_connector(connector_cfg2); + array =3D vkms_config_get_connectors(config, &length); + KUNIT_ASSERT_NULL(test, array); + + vkms_config_destroy(config); +} + static void vkms_config_test_valid_plane_number(struct kunit *test) { struct vkms_config *config; @@ -423,6 +472,39 @@ static void vkms_config_test_valid_encoder_possible_cr= tcs(struct kunit *test) vkms_config_destroy(config); } =20 +static void vkms_config_test_valid_connector_number(struct kunit *test) +{ + struct vkms_config *config; + struct vkms_config_connector *connector_cfg; + int n; + + config =3D vkms_config_default_create(false, false, false); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); + + /* Valid: No connectors */ + connector_cfg =3D list_first_entry(&config->connectors, typeof(*connector= _cfg), link); + vkms_config_destroy_connector(connector_cfg); + KUNIT_EXPECT_TRUE(test, vkms_config_is_valid(config)); + + /* Valid: Only a disabled connector */ + connector_cfg =3D vkms_config_add_connector(config); + KUNIT_EXPECT_TRUE(test, vkms_config_is_valid(config)); + + /* Valid: The connector is enabled */ + vkms_config_connector_set_enabled(connector_cfg, true); + KUNIT_EXPECT_TRUE(test, vkms_config_is_valid(config)); + + /* Invalid: Too many connectors */ + for (n =3D 0; n <=3D 32; n++) { + connector_cfg =3D vkms_config_add_connector(config); + vkms_config_connector_set_enabled(connector_cfg, true); + } + + KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); + + vkms_config_destroy(config); +} + static void vkms_config_test_plane_attach_crtc(struct kunit *test) { struct vkms_config *config; @@ -613,12 +695,14 @@ static struct kunit_case vkms_config_test_cases[] =3D= { KUNIT_CASE(vkms_config_test_get_planes), KUNIT_CASE(vkms_config_test_get_crtcs), KUNIT_CASE(vkms_config_test_get_encoders), + KUNIT_CASE(vkms_config_test_get_connectors), KUNIT_CASE(vkms_config_test_valid_plane_number), KUNIT_CASE(vkms_config_test_valid_plane_type), KUNIT_CASE(vkms_config_test_valid_plane_possible_crtcs), KUNIT_CASE(vkms_config_test_valid_crtc_number), KUNIT_CASE(vkms_config_test_valid_encoder_number), KUNIT_CASE(vkms_config_test_valid_encoder_possible_crtcs), + KUNIT_CASE(vkms_config_test_valid_connector_number), KUNIT_CASE(vkms_config_test_plane_attach_crtc), KUNIT_CASE(vkms_config_test_plane_get_possible_crtcs), KUNIT_CASE(vkms_config_test_encoder_get_possible_crtcs), diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms= _config.c index 437a9980e9a8..e94e48fe3ad9 100644 --- a/drivers/gpu/drm/vkms/vkms_config.c +++ b/drivers/gpu/drm/vkms/vkms_config.c @@ -24,6 +24,7 @@ struct vkms_config *vkms_config_create(const char *dev_na= me) INIT_LIST_HEAD(&config->planes); INIT_LIST_HEAD(&config->crtcs); INIT_LIST_HEAD(&config->encoders); + INIT_LIST_HEAD(&config->connectors); =20 return config; } @@ -36,6 +37,7 @@ struct vkms_config *vkms_config_default_create(bool enabl= e_cursor, struct vkms_config_plane *plane_cfg; struct vkms_config_crtc *crtc_cfg; struct vkms_config_encoder *encoder_cfg; + struct vkms_config_connector *connector_cfg; int n; =20 config =3D vkms_config_create(DEFAULT_DEVICE_NAME); @@ -87,6 +89,11 @@ struct vkms_config *vkms_config_default_create(bool enab= le_cursor, if (vkms_config_encoder_attach_crtc(encoder_cfg, crtc_cfg)) goto err_alloc; =20 + connector_cfg =3D vkms_config_add_connector(config); + if (IS_ERR(connector_cfg)) + goto err_alloc; + vkms_config_connector_set_enabled(connector_cfg, true); + return config; =20 err_alloc: @@ -99,6 +106,7 @@ void vkms_config_destroy(struct vkms_config *config) struct vkms_config_plane *plane_cfg, *plane_tmp; struct vkms_config_crtc *crtc_cfg, *crtc_tmp; struct vkms_config_encoder *encoder_cfg, *encoder_tmp; + struct vkms_config_connector *connector_cfg, *connector_tmp; =20 list_for_each_entry_safe(plane_cfg, plane_tmp, &config->planes, link) vkms_config_destroy_plane(plane_cfg); @@ -109,6 +117,9 @@ void vkms_config_destroy(struct vkms_config *config) list_for_each_entry_safe(encoder_cfg, encoder_tmp, &config->encoders, lin= k) vkms_config_destroy_encoder(config, encoder_cfg); =20 + list_for_each_entry_safe(connector_cfg, connector_tmp, &config->connector= s, link) + vkms_config_destroy_connector(connector_cfg); + kfree_const(config->dev_name); kfree(config); } @@ -194,6 +205,39 @@ struct vkms_config_encoder **vkms_config_get_encoders(= const struct vkms_config * return array; } =20 +struct vkms_config_connector **vkms_config_get_connectors(const struct vkm= s_config *config, + size_t *out_length) +{ + struct vkms_config_connector **array; + struct vkms_config_connector *connector_cfg; + size_t length =3D 0; + int n =3D 0; + + list_for_each_entry(connector_cfg, &config->connectors, link) { + if (vkms_config_connector_is_enabled(connector_cfg)) + length++; + } + + if (length =3D=3D 0) { + *out_length =3D length; + return NULL; + } + + array =3D kmalloc_array(length, sizeof(*array), GFP_KERNEL); + if (!array) + return ERR_PTR(-ENOMEM); + + list_for_each_entry(connector_cfg, &config->connectors, link) { + if (vkms_config_connector_is_enabled(connector_cfg)) { + array[n] =3D connector_cfg; + n++; + } + } + + *out_length =3D length; + return array; +} + static bool valid_plane_number(struct vkms_config *config) { size_t n_planes; @@ -325,6 +369,24 @@ static bool valid_encoder_possible_crtcs(struct vkms_c= onfig *config) return true; } =20 +static bool valid_connector_number(struct vkms_config *config) +{ + struct vkms_config_connector *connector_cfg; + size_t n_connectors =3D 0; + + list_for_each_entry(connector_cfg, &config->connectors, link) { + if (vkms_config_connector_is_enabled(connector_cfg)) + n_connectors++; + } + + if (n_connectors >=3D 32) { + pr_err("The number of connectors must be between 0 and 31\n"); + return false; + } + + return true; +} + bool vkms_config_is_valid(struct vkms_config *config) { struct vkms_config_crtc *crtc_cfg; @@ -338,6 +400,9 @@ bool vkms_config_is_valid(struct vkms_config *config) if (!valid_encoder_number(config)) return false; =20 + if (!valid_connector_number(config)) + return false; + if (!valid_plane_possible_crtcs(config)) return false; =20 @@ -361,6 +426,7 @@ static int vkms_config_show(struct seq_file *m, void *d= ata) struct vkms_config_plane *plane_cfg; struct vkms_config_crtc *crtc_cfg; struct vkms_config_encoder *encoder_cfg; + struct vkms_config_connector *connector_cfg; =20 dev_name =3D vkms_config_get_device_name((struct vkms_config *)vkmsdev->c= onfig); seq_printf(m, "dev_name=3D%s\n", dev_name); @@ -381,6 +447,12 @@ static int vkms_config_show(struct seq_file *m, void *= data) seq_puts(m, "encoder\n"); } =20 + list_for_each_entry(connector_cfg, &vkmsdev->config->connectors, link) { + seq_puts(m, "connector:\n"); + seq_printf(m, "\tenabled=3D%d\n", + vkms_config_connector_is_enabled(connector_cfg)); + } + return 0; } =20 @@ -620,3 +692,24 @@ vkms_config_encoder_get_possible_crtcs(struct vkms_con= fig_encoder *encoder_cfg, *out_length =3D length; return array; } + +struct vkms_config_connector *vkms_config_add_connector(struct vkms_config= *config) +{ + struct vkms_config_connector *connector_cfg; + + connector_cfg =3D kzalloc(sizeof(*connector_cfg), GFP_KERNEL); + if (!connector_cfg) + return ERR_PTR(-ENOMEM); + + vkms_config_connector_set_enabled(connector_cfg, false); + + list_add_tail(&connector_cfg->link, &config->connectors); + + return connector_cfg; +} + +void vkms_config_destroy_connector(struct vkms_config_connector *connector= _cfg) +{ + list_del(&connector_cfg->link); + kfree(connector_cfg); +} diff --git a/drivers/gpu/drm/vkms/vkms_config.h b/drivers/gpu/drm/vkms/vkms= _config.h index 5f4a33e113bf..cc32aadfda8d 100644 --- a/drivers/gpu/drm/vkms/vkms_config.h +++ b/drivers/gpu/drm/vkms/vkms_config.h @@ -15,6 +15,7 @@ * @planes: List of planes configured for the device * @crtcs: List of CRTCs configured for the device * @encoders: List of encoders configured for the device + * @connectors: List of connectors configured for the device * @dev: Used to store the current VKMS device. Only set when the device i= s instantiated. */ struct vkms_config { @@ -22,6 +23,7 @@ struct vkms_config { struct list_head planes; struct list_head crtcs; struct list_head encoders; + struct list_head connectors; struct vkms_device *dev; }; =20 @@ -85,6 +87,27 @@ struct vkms_config_encoder { struct drm_encoder *encoder; }; =20 +/** + * struct vkms_config_connector + * + * @link: Link to the others connector in vkms_config + * @enabled: Connector are a different from planes, CRTCs and encoders bec= ause + * they can be added and removed once the device is created. + * This flag represents if they are part of the device or not. + * @connector: Internal usage. This pointer should never be considered as = valid. + * It can be used to store a temporary reference to a VKMS con= nector + * during device creation. This pointer is not managed by the + * configuration and must be managed by other means. + */ +struct vkms_config_connector { + struct list_head link; + + bool enabled; + + /* Internal usage */ + struct vkms_connector *connector; +}; + /** * vkms_config_create() - Create a new VKMS configuration * @dev_name: Name of the device @@ -173,6 +196,21 @@ struct vkms_config_crtc **vkms_config_get_crtcs(const = struct vkms_config *config struct vkms_config_encoder **vkms_config_get_encoders(const struct vkms_co= nfig *config, size_t *out_length); =20 +/** + * vkms_config_get_connectors() - Return the array of connectors of the de= vice + * @config: Configuration to get the connectors from + * @out_length: Length of the returned array + * + * Note that only enabled connectors are returned. + * + * Returns: + * A list of pointers to the configurations. On success, the caller is + * responsible to free the returned array, but not its contents. On error, + * it returns an error and @out_length is invalid. + */ +struct vkms_config_connector **vkms_config_get_connectors(const struct vkm= s_config *config, + size_t *out_length); + /** * vkms_config_is_valid() - Validate a configuration * @config: Configuration to validate @@ -367,4 +405,42 @@ struct vkms_config_crtc ** vkms_config_encoder_get_possible_crtcs(struct vkms_config_encoder *encoder= _cfg, size_t *out_length); =20 +/** + * vkms_config_add_connector() - Add a new connector configuration + * @config: Configuration to add the connector to + * + * Returns: + * The new connector configuration or an error. Call + * vkms_config_destroy_connector() to free the returned connector configur= ation. + */ +struct vkms_config_connector *vkms_config_add_connector(struct vkms_config= *config); + +/** + * vkms_config_destroy_connector() - Remove and free a connector configura= tion + * @connector_cfg: Connector configuration to destroy + */ +void vkms_config_destroy_connector(struct vkms_config_connector *connector= _cfg); + +/** + * vkms_config_connector_is_enabled() - If the connector is part of the de= vice + * @connector_cfg: The connector + */ +static inline bool +vkms_config_connector_is_enabled(struct vkms_config_connector *connector_c= fg) +{ + return connector_cfg->enabled; +} + +/** + * vkms_config_connector_set_enabled() - If the connector is part of the d= evice + * @crtc_cfg: Target connector + * @enabled: Add or remove the connector + */ +static inline void +vkms_config_connector_set_enabled(struct vkms_config_connector *connector_= cfg, + bool enabled) +{ + connector_cfg->enabled =3D enabled; +} + #endif /* _VKMS_CONFIG_H_ */ diff --git a/drivers/gpu/drm/vkms/vkms_connector.c b/drivers/gpu/drm/vkms/v= kms_connector.c index ab8b52a84151..48b10cba322a 100644 --- a/drivers/gpu/drm/vkms/vkms_connector.c +++ b/drivers/gpu/drm/vkms/vkms_connector.c @@ -25,8 +25,19 @@ static int vkms_conn_get_modes(struct drm_connector *con= nector) return count; } =20 +static struct drm_encoder *vkms_conn_best_encoder(struct drm_connector *co= nnector) +{ + struct drm_encoder *encoder; + + drm_connector_for_each_possible_encoder(connector, encoder) + return encoder; + + return NULL; +} + static const struct drm_connector_helper_funcs vkms_conn_helper_funcs =3D { .get_modes =3D vkms_conn_get_modes, + .best_encoder =3D vkms_conn_best_encoder, }; =20 struct vkms_connector *vkms_connector_init(struct vkms_device *vkmsdev) --=20 2.48.1