Received: by 10.213.65.68 with SMTP id h4csp2866424imn; Mon, 2 Apr 2018 15:51:42 -0700 (PDT) X-Google-Smtp-Source: AIpwx49axSFMljGswnCi5kjUrOG4nm1ea235EY0SfTxPxLskvtt2lkN9DDZhI0Fi5iERUxw+5/vU X-Received: by 10.99.119.9 with SMTP id s9mr7349844pgc.276.1522709502095; Mon, 02 Apr 2018 15:51:42 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1522709501; cv=none; d=google.com; s=arc-20160816; b=bdo5dihKWMvd4rRv9RWrxZL0MwORILh3tbYkqElChVQz80GA36FUvlgPnnwKtHjh8E byyW0kh9WiFJTmsTL0Xows9k1SjFdhVu4/YogF0PY8qaUksnpCPnUAuRf4qBATgl4XsC haacPhRBuIB5xuzDjOTHGGHsE5tXq+gYoOAJHSTB9GZrLbl+MhQW1r2b22v3OKcpd7so JvZlUet9Lkv22AU1pyWubEg14urm5jcmbNzs35NdiAwYfYyvKnN+Pa7y6isGlJ6k6YPd qJnNEJnsXtWX+ENgeds0IoLLa5lGeSJmw3RtQ3AvxfaaFxd2z7896wz69DbR3e/OiKwZ zaRA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=H9YRjsqorcYQ3NqxrjtzppxYhbzHN/2GO1xFizHERa8=; b=flaBE/Nelf1NhOJ/ZdVTicWpGH4tzx2z3lcP1azpegO+WpMNblfAd2g0zO/etMOlCV ZNJRhJwqKLeTigTBG2D5/ofa4B6o97LBnXkunS76DiGTOFqEkPDHuaq5mfjNFvkMLQUK 5yS0afN6LGYEe6PTMf2DNoJ0+LcRzy3KfbnHd6QitsLX/8v38ExqA9Et6ZZR6guqxNex cu/rb2A8+PdqT5X0/0+szJfBPNDBS2YNI3kTnORV8IUlji9HHflNZ8rHq/5VLwGJ0bNF Vu/1Qo0RpCs4aopIUhH3T0MxfZ9WYlCfTkRTJjAidF+RzbXPsut/EPtEgEYpsiALnu/v megA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 75si994795pfx.61.2018.04.02.15.51.28; Mon, 02 Apr 2018 15:51:41 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754696AbeDBWsb (ORCPT + 99 others); Mon, 2 Apr 2018 18:48:31 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:58432 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1754516AbeDBWs2 (ORCPT ); Mon, 2 Apr 2018 18:48:28 -0400 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id ECD264057284; Mon, 2 Apr 2018 22:48:27 +0000 (UTC) Received: from malachite.bss.redhat.com (dhcp-10-20-1-55.bss.redhat.com [10.20.1.55]) by smtp.corp.redhat.com (Postfix) with ESMTP id 406CF11301CD; Mon, 2 Apr 2018 22:48:27 +0000 (UTC) From: Lyude Paul To: intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org Cc: Manasi Navare , =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= , Alex Deucher , =?UTF-8?q?Christian=20K=C3=B6nig?= , "David (ChunMing) Zhou" , David Airlie , Gustavo Padovan , Maarten Lankhorst , Sean Paul , Jani Nikula , Joonas Lahtinen , Rodrigo Vivi , Ben Skeggs , Harry Wentland , Andrey Grodzovsky , Tony Cheng , "Leo (Sunpeng) Li" , Shirish S , "Jerry (Fangzhi) Zuo" , Roman Li , amd-gfx@lists.freedesktop.org, linux-kernel@vger.kernel.org, nouveau@lists.freedesktop.org Subject: [PATCH v5 05/10] drm/dp_mst: Make drm_dp_mst_topology_state subclassable Date: Mon, 2 Apr 2018 18:47:41 -0400 Message-Id: <20180402224800.16080-6-lyude@redhat.com> In-Reply-To: <20180402224800.16080-1-lyude@redhat.com> References: <20180402224800.16080-1-lyude@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Scanned-By: MIMEDefang 2.78 on 10.11.54.3 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.6]); Mon, 02 Apr 2018 22:48:28 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.6]); Mon, 02 Apr 2018 22:48:28 +0000 (UTC) for IP:'10.11.54.3' DOMAIN:'int-mx03.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'lyude@redhat.com' RCPT:'' Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This is useful for drivers (which will probably be all of them soon) which need to track state that is exclusive to the topology, and not a specific connector on said topology. This includes things such as the link rate and lane count that are shared by all of the connectors on the topology. Signed-off-by: Lyude Paul Cc: Manasi Navare Cc: Ville Syrjälä --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 14 +++- .../amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 35 +++++++- .../amd/display/amdgpu_dm/amdgpu_dm_mst_types.h | 4 +- drivers/gpu/drm/drm_dp_mst_topology.c | 94 +++++++++++++++++----- drivers/gpu/drm/i915/intel_dp_mst.c | 13 ++- drivers/gpu/drm/nouveau/nv50_display.c | 15 +++- drivers/gpu/drm/radeon/radeon_dp_mst.c | 13 ++- include/drm/drm_dp_mst_helper.h | 8 ++ 8 files changed, 165 insertions(+), 31 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index e42a28e3adc5..2c3660c36732 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -3626,9 +3626,17 @@ static int amdgpu_dm_connector_init(struct amdgpu_display_manager *dm, drm_connector_register(&aconnector->base); - if (connector_type == DRM_MODE_CONNECTOR_DisplayPort - || connector_type == DRM_MODE_CONNECTOR_eDP) - amdgpu_dm_initialize_dp_connector(dm, aconnector); + if (connector_type == DRM_MODE_CONNECTOR_DisplayPort || + connector_type == DRM_MODE_CONNECTOR_eDP) { + res = amdgpu_dm_initialize_dp_connector(dm, aconnector); + if (res) { + drm_connector_unregister(&aconnector->base); + drm_connector_cleanup(&aconnector->base); + aconnector->connector_id = -1; + + goto out_free; + } + } #if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) ||\ defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE) 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 8291d74f26bc..a3a43b1b30df 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 @@ -475,22 +475,49 @@ static const struct drm_dp_mst_topology_cbs dm_mst_cbs = { .register_connector = dm_dp_mst_register_connector }; -void amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm, - struct amdgpu_dm_connector *aconnector) +static const struct drm_private_state_funcs dm_mst_state_funcs = { + .atomic_duplicate_state = drm_atomic_dp_mst_duplicate_topology_state, + .atomic_destroy_state = drm_atomic_dp_mst_destroy_topology_state, +}; + +int amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm, + struct amdgpu_dm_connector *aconnector) { + struct drm_dp_mst_topology_state *state = + kzalloc(sizeof(*state), GFP_KERNEL); + int ret = 0; + + if (!state) + return -ENOMEM; + aconnector->dm_dp_aux.aux.name = "dmdc"; aconnector->dm_dp_aux.aux.dev = dm->adev->dev; aconnector->dm_dp_aux.aux.transfer = dm_dp_aux_transfer; aconnector->dm_dp_aux.ddc_service = aconnector->dc_link->ddc; - drm_dp_aux_register(&aconnector->dm_dp_aux.aux); + ret = drm_dp_aux_register(&aconnector->dm_dp_aux.aux); + if (ret) + goto err_aux; + aconnector->mst_mgr.cbs = &dm_mst_cbs; - drm_dp_mst_topology_mgr_init( + aconnector->mst_mgr.funcs = &dm_mst_state_funcs; + ret = drm_dp_mst_topology_mgr_init( &aconnector->mst_mgr, + state, dm->adev->ddev, &aconnector->dm_dp_aux.aux, 16, 4, aconnector->connector_id); + if (ret) + goto err_mst; + + return 0; + +err_mst: + drm_dp_aux_unregister(&aconnector->dm_dp_aux.aux); +err_aux: + kfree(state); + return ret; } diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h index 8cf51da26657..d28fb456d2d5 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h @@ -29,8 +29,8 @@ struct amdgpu_display_manager; struct amdgpu_dm_connector; -void amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm, - struct amdgpu_dm_connector *aconnector); +int amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm, + struct amdgpu_dm_connector *aconnector); void dm_dp_mst_dc_sink_create(struct drm_connector *connector); #endif diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c index ba67f1782a04..8a72eed0ae05 100644 --- a/drivers/gpu/drm/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/drm_dp_mst_topology.c @@ -3100,33 +3100,89 @@ static void drm_dp_destroy_connector_work(struct work_struct *work) (*mgr->cbs->hotplug)(mgr); } -static struct drm_private_state * -drm_dp_mst_duplicate_state(struct drm_private_obj *obj) +/** + * drm_atomic_dp_mst_duplicate_topology_state - default + * drm_dp_mst_topology_state duplicate handler + * + * For drivers which don't yet subclass drm_dp_mst_topology_state + * + * RETURNS: the duplicated state on success, or an error code embedded into a + * pointer value otherwise. + */ +struct drm_private_state * +drm_atomic_dp_mst_duplicate_topology_state(struct drm_private_obj *obj) { + struct drm_dp_mst_topology_mgr *mgr = to_dp_mst_topology_mgr(obj); struct drm_dp_mst_topology_state *state; + int ret; state = kmemdup(obj->state, sizeof(*state), GFP_KERNEL); if (!state) return NULL; - __drm_atomic_helper_private_obj_duplicate_state(obj, &state->base); + ret = __drm_atomic_dp_mst_duplicate_topology_state(mgr, state); + if (ret) { + kfree(state); + return NULL; + } return &state->base; } +EXPORT_SYMBOL(drm_atomic_dp_mst_duplicate_topology_state); -static void drm_dp_mst_destroy_state(struct drm_private_obj *obj, - struct drm_private_state *state) +/** + * __drm_atomic_dp_mst_duplicate_topology_state - default + * drm_dp_mst_topology_state duplicate hook + * + * Copies atomic state from an MST topology's current state. This is useful + * for drivers that subclass the MST topology state. + * + * RETURNS: 0 on success, negative error code on failure. + */ +int +__drm_atomic_dp_mst_duplicate_topology_state(struct drm_dp_mst_topology_mgr *mgr, + struct drm_dp_mst_topology_state *state) +{ + struct drm_private_obj *obj = &mgr->base; + + memcpy(state, obj->state, sizeof(*state)); + + __drm_atomic_helper_private_obj_duplicate_state(&mgr->base, + &state->base); + return 0; +} +EXPORT_SYMBOL(__drm_atomic_dp_mst_duplicate_topology_state); + +/** + * drm_atomic_dp_mst_destroy_topology_state - default + * drm_dp_mst_topology_state destroy handler + * + * For drivers which don't yet subclass drm_dp_mst_topology_state. + */ +void +drm_atomic_dp_mst_destroy_topology_state(struct drm_private_obj *obj, + struct drm_private_state *state) { struct drm_dp_mst_topology_state *mst_state = to_dp_mst_topology_state(state); + __drm_atomic_dp_mst_destroy_topology_state(mst_state); + kfree(mst_state); } +EXPORT_SYMBOL(drm_atomic_dp_mst_destroy_topology_state); -static const struct drm_private_state_funcs mst_state_funcs = { - .atomic_duplicate_state = drm_dp_mst_duplicate_state, - .atomic_destroy_state = drm_dp_mst_destroy_state, -}; +/** + * __drm_atomic_dp_mst_destroy_topology_state - default + * drm_dp_mst_topology_state destroy hook + * + * Frees the resources associated with the given drm_dp_mst_topology_state. + * This is useful for drivers that subclass the MST topology state. + */ +void +__drm_atomic_dp_mst_destroy_topology_state(struct drm_dp_mst_topology_state *state) { +} +EXPORT_SYMBOL(__drm_atomic_dp_mst_destroy_topology_state); /** * drm_atomic_dp_mst_get_topology_state: get MST topology state @@ -3157,21 +3213,25 @@ EXPORT_SYMBOL(drm_atomic_dp_mst_get_topology_state); /** * drm_dp_mst_topology_mgr_init - initialise a topology manager * @mgr: manager struct to initialise + * @state: atomic topology state to init, allocated by the driver * @dev: device providing this structure - for i2c addition. * @aux: DP helper aux channel to talk to this device * @max_dpcd_transaction_bytes: hw specific DPCD transaction limit * @max_payloads: maximum number of payloads this GPU can source * @conn_base_id: the connector object ID the MST device is connected to. * + * Note that this function doesn't take care of allocating the atomic MST + * state, this must be handled by the caller before calling + * drm_dp_mst_topology_mgr_init(). + * * Return 0 for success, or negative error code on failure */ int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr, + struct drm_dp_mst_topology_state *state, struct drm_device *dev, struct drm_dp_aux *aux, int max_dpcd_transaction_bytes, int max_payloads, int conn_base_id) { - struct drm_dp_mst_topology_state *mst_state; - mutex_init(&mgr->lock); mutex_init(&mgr->qlock); mutex_init(&mgr->payload_lock); @@ -3200,18 +3260,14 @@ int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr, if (test_calc_pbn_mode() < 0) DRM_ERROR("MST PBN self-test failed\n"); - mst_state = kzalloc(sizeof(*mst_state), GFP_KERNEL); - if (mst_state == NULL) - return -ENOMEM; - - mst_state->mgr = mgr; + state->mgr = mgr; /* max. time slots - one slot for MTP header */ - mst_state->avail_slots = 63; + state->avail_slots = 63; drm_atomic_private_obj_init(&mgr->base, - &mst_state->base, - &mst_state_funcs); + &state->base, + mgr->funcs); return 0; } diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c index c3de0918ee13..e308962cde05 100644 --- a/drivers/gpu/drm/i915/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/intel_dp_mst.c @@ -581,19 +581,30 @@ intel_dp_create_fake_mst_encoders(struct intel_digital_port *intel_dig_port) return true; } +static const struct drm_private_state_funcs mst_state_funcs = { + .atomic_destroy_state = drm_atomic_dp_mst_destroy_topology_state, + .atomic_duplicate_state = drm_atomic_dp_mst_duplicate_topology_state, +}; + int intel_dp_mst_encoder_init(struct intel_digital_port *intel_dig_port, int conn_base_id) { struct intel_dp *intel_dp = &intel_dig_port->dp; + struct drm_dp_mst_topology_state *mst_state; struct drm_device *dev = intel_dig_port->base.base.dev; int ret; + mst_state = kzalloc(sizeof(*mst_state), GFP_KERNEL); + if (!mst_state) + return -ENOMEM; + intel_dp->can_mst = true; intel_dp->mst_mgr.cbs = &mst_cbs; + intel_dp->mst_mgr.funcs = &mst_state_funcs; /* create encoders */ intel_dp_create_fake_mst_encoders(intel_dig_port); - ret = drm_dp_mst_topology_mgr_init(&intel_dp->mst_mgr, dev, + ret = drm_dp_mst_topology_mgr_init(&intel_dp->mst_mgr, mst_state, dev, &intel_dp->aux, 16, 3, conn_base_id); if (ret) { intel_dp->can_mst = false; diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index 8bd739cfd00d..1cacd806eb8d 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -3310,6 +3310,12 @@ nv50_mstm = { .hotplug = nv50_mstm_hotplug, }; +static const struct drm_private_state_funcs +nv50_mst_state_funcs = { + .atomic_duplicate_state = drm_atomic_dp_mst_duplicate_topology_state, + .atomic_destroy_state = drm_atomic_dp_mst_destroy_topology_state, +}; + void nv50_mstm_service(struct nv50_mstm *mstm) { @@ -3438,6 +3444,7 @@ nv50_mstm_new(struct nouveau_encoder *outp, struct drm_dp_aux *aux, int aux_max, { const int max_payloads = hweight8(outp->dcb->heads); struct drm_device *dev = outp->base.base.dev; + struct drm_dp_mst_topology_state *state; struct nv50_mstm *mstm; int ret, i; u8 dpcd; @@ -3454,10 +3461,16 @@ nv50_mstm_new(struct nouveau_encoder *outp, struct drm_dp_aux *aux, int aux_max, if (!(mstm = *pmstm = kzalloc(sizeof(*mstm), GFP_KERNEL))) return -ENOMEM; + if (!(state = kzalloc(sizeof(*state), GFP_KERNEL))) { + kfree(mstm); + return -ENOMEM; + } mstm->outp = outp; mstm->mgr.cbs = &nv50_mstm; + mstm->mgr.funcs = &nv50_mst_state_funcs; - ret = drm_dp_mst_topology_mgr_init(&mstm->mgr, dev, aux, aux_max, + ret = drm_dp_mst_topology_mgr_init(&mstm->mgr, state, dev, + aux, aux_max, max_payloads, conn_base_id); if (ret) return ret; diff --git a/drivers/gpu/drm/radeon/radeon_dp_mst.c b/drivers/gpu/drm/radeon/radeon_dp_mst.c index cd8a3ee16649..6edf52404256 100644 --- a/drivers/gpu/drm/radeon/radeon_dp_mst.c +++ b/drivers/gpu/drm/radeon/radeon_dp_mst.c @@ -335,6 +335,11 @@ static const struct drm_dp_mst_topology_cbs mst_cbs = { .hotplug = radeon_dp_mst_hotplug, }; +static const struct drm_private_state_funcs mst_state_funcs = { + .atomic_duplicate_state = drm_atomic_dp_mst_duplicate_topology_state, + .atomic_destroy_state = drm_atomic_dp_mst_destroy_topology_state, +}; + static struct radeon_connector *radeon_mst_find_connector(struct drm_encoder *encoder) { @@ -657,12 +662,18 @@ int radeon_dp_mst_init(struct radeon_connector *radeon_connector) { struct drm_device *dev = radeon_connector->base.dev; + struct drm_dp_mst_topology_state *state = + kzalloc(sizeof(*state), GFP_KERNEL); + if (!state) + return -ENOMEM; if (!radeon_connector->ddc_bus->has_aux) return 0; radeon_connector->mst_mgr.cbs = &mst_cbs; - return drm_dp_mst_topology_mgr_init(&radeon_connector->mst_mgr, dev, + radeon_connector->mst_mgr.funcs = &mst_state_funcs; + return drm_dp_mst_topology_mgr_init(&radeon_connector->mst_mgr, + state, dev, &radeon_connector->ddc_bus->aux, 16, 6, radeon_connector->base.base.id); } diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h index 035963fbcd9d..b42922987470 100644 --- a/include/drm/drm_dp_mst_helper.h +++ b/include/drm/drm_dp_mst_helper.h @@ -565,6 +565,7 @@ struct drm_dp_mst_topology_mgr { }; int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr, + struct drm_dp_mst_topology_state *state, struct drm_device *dev, struct drm_dp_aux *aux, int max_dpcd_transaction_bytes, int max_payloads, int conn_base_id); @@ -620,6 +621,13 @@ int drm_dp_mst_topology_mgr_resume(struct drm_dp_mst_topology_mgr *mgr); struct drm_dp_mst_topology_state *drm_atomic_dp_mst_get_topology_state(struct drm_atomic_state *state, struct drm_dp_mst_topology_mgr *mgr); +struct drm_private_state *drm_atomic_dp_mst_duplicate_topology_state(struct drm_private_obj *obj); +int __drm_atomic_dp_mst_duplicate_topology_state(struct drm_dp_mst_topology_mgr *mgr, + struct drm_dp_mst_topology_state *state); +void drm_atomic_dp_mst_destroy_topology_state(struct drm_private_obj *obj, + struct drm_private_state *state); +void __drm_atomic_dp_mst_destroy_topology_state(struct drm_dp_mst_topology_state *state); + int drm_dp_atomic_find_vcpi_slots(struct drm_atomic_state *state, struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port, int pbn); -- 2.14.3