[PATCH 2/7] drm/dp_mst: Register AUX devices for MST ports
Lyude Paul
lyude at redhat.com
Thu May 16 21:40:05 UTC 2019
So a couple of things:
On Thu, 2019-05-16 at 11:17 -0400, sunpeng.li at amd.com wrote:
> From: Ville Syrjälä <ville.syrjala at linux.intel.com>
>
> All available downstream ports - physical and logical - are exposed for
> each MST device. They are listed in /dev/, following the same naming
> scheme as SST devices by appending an incremental ID.
>
> Although all downstream ports are exposed, only some will work as
> expected. Consider the following topology:
>
> +---------+
> | ASIC |
> +---------+
> Conn-0|
> |
> +----v----+
> +----| MST HUB |----+
> | +---------+ |
> | |
> |Port-1 Port-2|
> +-----v-----+ +-----v-----+
> | MST | | SST |
> | Display | | Display |
> +-----------+ +-----------+
> |Port-1
> x
>
> MST Path | MST Device
> ----------+----------------------------------
> sst:0 | MST Hub
> mst:0-1 | MST Display
> mst:0-1-1 | MST Display's disconnected DP out
> mst:0-1-8 | MST Display's internal sink
> mst:0-2 | SST Display
>
> On certain MST displays, the upstream physical port will ACK DPCD reads.
> However, reads on the local logical port to the internal sink will
> *NAK*. i.e. reading mst:0-1 ACKs, but mst:0-1-8 NAKs.
>
> There may also be duplicates. Some displays will return the same GUID
> when reading DPCD from both mst:0-1 and mst:0-1-8.
>
> There are some device-dependent behavior as well. The MST hub used
> during testing will actually *ACK* read requests on a disconnected
> physical port, whereas the MST displays will NAK.
>
> In light of these discrepancies, it's simpler to expose all downstream
> ports - both physical and logical - and let the user decide what to use.
>
> Cc: Lyude Paul <lyude at redhat.com>
> Signed-off-by: Ville Syrjälä <ville.syrjala at linux.intel.com>
> Signed-off-by: Leo Li <sunpeng.li at amd.com>
> ---
> drivers/gpu/drm/drm_dp_aux_dev.c | 14 ++++-
> drivers/gpu/drm/drm_dp_mst_topology.c | 103 +++++++++++++++++++++++++++++
> -----
> include/drm/drm_dp_helper.h | 4 ++
> include/drm/drm_dp_mst_helper.h | 6 ++
> 4 files changed, 112 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_dp_aux_dev.c
> b/drivers/gpu/drm/drm_dp_aux_dev.c
> index 6d84611..01c02b9 100644
> --- a/drivers/gpu/drm/drm_dp_aux_dev.c
> +++ b/drivers/gpu/drm/drm_dp_aux_dev.c
> @@ -34,6 +34,7 @@
> #include <linux/uaccess.h>
> #include <linux/uio.h>
> #include <drm/drm_dp_helper.h>
> +#include <drm/drm_dp_mst_helper.h>
> #include <drm/drm_crtc.h>
> #include <drm/drmP.h>
>
> @@ -114,6 +115,7 @@ static ssize_t name_show(struct device *dev,
>
> return res;
> }
> +
> static DEVICE_ATTR_RO(name);
>
> static struct attribute *drm_dp_aux_attrs[] = {
> @@ -160,7 +162,11 @@ static ssize_t auxdev_read_iter(struct kiocb *iocb,
> struct iov_iter *to)
> break;
> }
>
> - res = drm_dp_dpcd_read(aux_dev->aux, pos, buf, todo);
> + if (aux_dev->aux->is_remote)
> + res = drm_dp_mst_dpcd_read(aux_dev->aux, pos, buf,
> todo);
> + else
> + res = drm_dp_dpcd_read(aux_dev->aux, pos, buf, todo);
> +
It's still not at all clear to me why we're trying to avoid specifying actual
callbacks for the aux device. We should remove this part entirely, remove the
is_remote entry from struct drm_dp_aux, and then just specify our own hook in
struct drm_dp_aux->transfer().
> if (res <= 0)
> break;
>
> @@ -207,7 +213,11 @@ static ssize_t auxdev_write_iter(struct kiocb *iocb,
> struct iov_iter *from)
> break;
> }
>
> - res = drm_dp_dpcd_write(aux_dev->aux, pos, buf, todo);
> + if (aux_dev->aux->is_remote)
> + res = drm_dp_mst_dpcd_write(aux_dev->aux, pos, buf,
> todo);
> + else
> + res = drm_dp_dpcd_write(aux_dev->aux, pos, buf, todo);
> +
> if (res <= 0)
> break;
>
> diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c
> b/drivers/gpu/drm/drm_dp_mst_topology.c
> index 2ab16c9..54da68e 100644
> --- a/drivers/gpu/drm/drm_dp_mst_topology.c
> +++ b/drivers/gpu/drm/drm_dp_mst_topology.c
> @@ -35,6 +35,8 @@
> #include <drm/drm_atomic_helper.h>
> #include <drm/drm_crtc_helper.h>
>
> +#include "drm_crtc_helper_internal.h"
> +
Unless I'm mistaken, this looks like some sort of ditritus.
> /**
> * DOC: dp mst helper
> *
> @@ -52,6 +54,9 @@ static int drm_dp_dpcd_write_payload(struct
> drm_dp_mst_topology_mgr *mgr,
> int id,
> struct drm_dp_payload *payload);
>
> +static int drm_dp_send_dpcd_read(struct drm_dp_mst_topology_mgr *mgr,
> + struct drm_dp_mst_port *port,
> + int offset, int size, u8 *bytes);
> static int drm_dp_send_dpcd_write(struct drm_dp_mst_topology_mgr *mgr,
> struct drm_dp_mst_port *port,
> int offset, int size, u8 *bytes);
> @@ -941,6 +946,8 @@ static void drm_dp_destroy_port(struct kref *kref)
> struct drm_dp_mst_topology_mgr *mgr = port->mgr;
>
> if (!port->input) {
> + drm_dp_aux_unregister_devnode(&port->aux);
> +
> port->vcpi.num_slots = 0;
>
> kfree(port->cached_edid);
> @@ -1095,6 +1102,46 @@ static bool drm_dp_port_setup_pdt(struct
> drm_dp_mst_port *port)
> return send_link;
> }
>
> +/**
> + * drm_dp_mst_dpcd_read() - read a series of bytes from the DPCD via
> sideband
> + * @aux: Fake sideband AUX CH
> + * @offset: address of the (first) register to read
> + * @buffer: buffer to store the register values
> + * @size: number of bytes in @buffer
> + *
> + * Performs the same functionality for remote devices via
> + * sideband messaging as drm_dp_dpcd_read() does for local
> + * devices via actual AUX CH.
> + */
> +ssize_t drm_dp_mst_dpcd_read(struct drm_dp_aux *aux,
> + unsigned int offset, void *buffer, size_t size)
> +{
> + struct drm_dp_mst_port *port = container_of(aux, struct
> drm_dp_mst_port, aux);
> +
> + return drm_dp_send_dpcd_read(port->mgr, port,
> + offset, size, buffer);
> +}
> +
> +/**
> + * drm_dp_mst_dpcd_write() - write a series of bytes to the DPCD via
> sideband
> + * @aux: Fake sideband AUX CH
> + * @offset: address of the (first) register to write
> + * @buffer: buffer containing the values to write
> + * @size: number of bytes in @buffer
> + *
> + * Performs the same functionality for remote devices via
> + * sideband messaging as drm_dp_dpcd_write() does for local
> + * devices via actual AUX CH.
> + */
> +ssize_t drm_dp_mst_dpcd_write(struct drm_dp_aux *aux,
> + unsigned int offset, void *buffer, size_t size)
> +{
> + struct drm_dp_mst_port *port = container_of(aux, struct
> drm_dp_mst_port, aux);
> +
> + return drm_dp_send_dpcd_write(port->mgr, port,
> + offset, size, buffer);
> +}
> +
> static void drm_dp_check_mstb_guid(struct drm_dp_mst_branch *mstb, u8
> *guid)
> {
> int ret;
> @@ -1158,6 +1205,7 @@ static void drm_dp_add_port(struct drm_dp_mst_branch
> *mstb,
> port->mgr = mstb->mgr;
> port->aux.name = "DPMST";
> port->aux.dev = dev->dev;
> + port->aux.is_remote = true;
> created = true;
> } else {
> old_pdt = port->pdt;
> @@ -1188,7 +1236,7 @@ static void drm_dp_add_port(struct drm_dp_mst_branch
> *mstb,
> drm_dp_send_enum_path_resources(mstb->mgr,
> mstb, port);
> } else {
> port->available_pbn = 0;
> - }
> + }
> }
>
> if (old_pdt != port->pdt && !port->input) {
> @@ -1220,6 +1268,8 @@ static void drm_dp_add_port(struct drm_dp_mst_branch
> *mstb,
> drm_connector_set_tile_property(port->connector);
> }
> (*mstb->mgr->cbs->register_connector)(port->connector);
This is wrong: we always want to setup everything in the connector first
before trying to register it, not after. Otherwise, things explode like so:
[ 13.305329] [drm:drm_mode_object_get [drm]] OBJ ID: 113 (3)
[ 13.305361] [drm:drm_mode_object_get [drm]] OBJ ID: 123 (1)
[ 13.305384] [drm:drm_mode_object_get [drm]] OBJ ID: 113 (4)
[ 13.305405] [drm:drm_mode_object_get [drm]] OBJ ID: 124 (1)
[ 13.305429] [drm:drm_mode_object_get [drm]] OBJ ID: 113 (5)
[ 13.305449] [drm:drm_mode_object_put.part.3 [drm]] OBJ ID: 113 (6)
[ 13.305471] [drm:drm_mode_object_get [drm]] OBJ ID: 85 (5)
[ 13.305490] [drm:drm_mode_object_get [drm]] OBJ ID: 85 (6)
[ 13.305512] [drm:drm_mode_object_put.part.3 [drm]] OBJ ID: 85 (6)
[ 13.305532] [drm:drm_mode_object_get [drm]] OBJ ID: 85 (5)
[ 13.305552] [drm:drm_mode_object_get [drm]] OBJ ID: 113 (5)
[ 13.305571] [drm:drm_mode_object_put.part.3 [drm]] OBJ ID: 113 (6)
[ 13.305592] [drm:drm_mode_object_get [drm]] OBJ ID: 86 (5)
[ 13.305612] [drm:drm_mode_object_get [drm]] OBJ ID: 86 (6)
[ 13.305631] [drm:drm_mode_object_put.part.3 [drm]] OBJ ID: 86 (6)
[ 13.305651] [drm:drm_mode_object_get [drm]] OBJ ID: 86 (5)
[ 13.305725] [drm:drm_vblank_enable [drm]] enabling vblank on crtc 0, ret: 0
[ 13.305768] [drm:drm_vblank_enable [drm]] enabling vblank on crtc 1, ret: 0
[ 13.306088] [drm:drm_handle_vblank [drm]] vblank event on 325, current 325
[ 13.322514] [drm:drm_handle_vblank [drm]] vblank event on 313, current 313
[ 13.322612] [drm:drm_mode_object_put.part.3 [drm]] OBJ ID: 85 (6)
[ 13.322634] [drm:drm_mode_object_put.part.3 [drm]] OBJ ID: 85 (5)
[ 13.322656] [drm:drm_mode_object_put.part.3 [drm]] OBJ ID: 86 (6)
[ 13.322676] [drm:drm_mode_object_put.part.3 [drm]] OBJ ID: 86 (5)
[ 13.322697] [drm:drm_mode_object_put.part.3 [drm]] OBJ ID: 123 (2)
[ 13.322718] [drm:drm_mode_object_put.part.3 [drm]] OBJ ID: 124 (2)
[ 13.322740] [drm:drm_mode_object_put.part.3 [drm]] OBJ ID: 113 (5)
[ 13.322764] [drm:vblank_disable_fn [drm]] disabling vblank on crtc 0
[ 13.322784] [drm:drm_mode_object_put.part.3 [drm]] OBJ ID: 113 (4)
[ 13.339191] [drm:vblank_disable_fn [drm]] disabling vblank on crtc 1
[ 451.149789] Console: switching to colour dummy device 80x25
[ 451.194596] [drm:drm_dp_aux_unregister_devnode [drm_kms_helper]] drm_dp_aux_dev: aux [DPDDC-A] unregistering
[ 451.194666] [drm:drm_sysfs_connector_remove [drm]] removing "eDP-1" from sysfs
[ 451.194718] [drm:drm_dp_aux_unregister_devnode [drm_kms_helper]] drm_dp_aux_dev: aux [DPDDC-B] unregistering
[ 451.194766] [drm:drm_sysfs_connector_remove [drm]] removing "DP-1" from sysfs
[ 451.194791] [drm:drm_sysfs_connector_remove [drm]] removing "HDMI-A-1" from sysfs
[ 451.194835] [drm:drm_dp_aux_unregister_devnode [drm_kms_helper]] drm_dp_aux_dev: aux [DPDDC-C] unregistering
[ 451.194880] [drm:drm_sysfs_connector_remove [drm]] removing "DP-2" from sysfs
[ 451.194903] [drm:drm_sysfs_connector_remove [drm]] removing "HDMI-A-2" from sysfs
[ 451.194924] [drm:drm_sysfs_connector_remove [drm]] removing "DP-3" from sysfs
[ 451.194950] [drm:drm_sysfs_connector_remove [drm]] removing "DP-4" from sysfs
[ 451.194975] [drm:drm_sysfs_connector_remove [drm]] removing "DP-5" from sysfs
[ 451.204535] [drm:drm_mode_object_get [drm]] OBJ ID: 123 (1)
[ 451.204551] [drm:drm_mode_object_put.part.3 [drm]] OBJ ID: 123 (2)
[ 451.204566] [drm:drm_mode_object_get [drm]] OBJ ID: 113 (3)
[ 451.204582] [drm:drm_mode_object_get [drm]] OBJ ID: 85 (5)
[ 451.204596] [drm:drm_mode_object_get [drm]] OBJ ID: 85 (6)
[ 451.204611] [drm:drm_mode_object_get [drm]] OBJ ID: 124 (1)
[ 451.204621] [drm:drm_mode_object_put.part.3 [drm]] OBJ ID: 124 (2)
[ 451.204631] [drm:drm_mode_object_get [drm]] OBJ ID: 113 (4)
[ 451.204641] [drm:drm_mode_object_get [drm]] OBJ ID: 86 (5)
[ 451.204651] [drm:drm_mode_object_get [drm]] OBJ ID: 86 (6)
[ 451.204662] [drm:drm_mode_object_put.part.3 [drm]] OBJ ID: 85 (6)
[ 451.204671] [drm:drm_mode_object_put.part.3 [drm]] OBJ ID: 86 (6)
[ 451.204680] [drm:drm_mode_object_put.part.3 [drm]] OBJ ID: 113 (5)
[ 451.204689] [drm:drm_mode_object_put.part.3 [drm]] OBJ ID: 113 (4)
[ 451.204699] [drm:drm_dp_mst_duplicate_state [drm_kms_helper]] port 00000000dde1b00a (5)
[ 451.204703] [drm:drm_dp_mst_put_port_malloc [drm_kms_helper]] port 00000000dde1b00a (4)
[ 451.411817] [drm:intel_panel_actually_set_backlight [i915]] set backlight PWM = 0
[ 451.420911] [drm:drm_dp_dpcd_write [drm_kms_helper]] DPDDC-A: 0x00600 AUX <- (ret= 1) 02
[ 451.425358] [drm:gen8_de_irq_handler [i915]] hotplug event received, stat 0x01000000, dig 0x11101010, pins 0x00000010, long 0x00000000
[ 451.425422] [drm:intel_hpd_irq_handler [i915]] digital hpd port A - short
[ 451.471777] [drm:drm_dp_mst_topology_get_mstb_validated [drm_kms_helper]] mstb 00000000eec1a629 (2)
[ 451.473361] [drm:gen8_de_irq_handler [i915]] hotplug event received, stat 0x01000000, dig 0x12101010, pins 0x00000010, long 0x00000010
[ 451.473465] [drm:intel_hpd_irq_handler [i915]] digital hpd port A - long
[ 452.207301] [drm:gen8_de_irq_handler [i915]] hotplug event received, stat 0x01000000, dig 0x12101010, pins 0x00000010, long 0x00000010
[ 452.207395] [drm:intel_hpd_irq_handler [i915]] digital hpd port A - long
[ 452.340311] [drm:drm_dp_dpcd_read [drm_kms_helper]] DPDDC-A: 0x00000 AUX -> (ret= 15) 11 0a 02 41 00 00 01 00 02 00 00 00 00 0b 00
[ 452.341060] [drm:drm_dp_dpcd_read [drm_kms_helper]] DPDDC-A: 0x00201 AUX -> (ret= 1) 00
[ 452.341584] [drm:drm_dp_dpcd_write [drm_kms_helper]] DPDDC-B: 0x01000 AUX <- (ret= 10) 10 47 d3 11 11 01 00 00 00 f4
[ 452.343183] [drm:gen8_de_irq_handler [i915]] hotplug event received, stat 0x00200000, dig 0x10101011, pins 0x00000020, long 0x00000000
[ 452.343286] [drm:intel_hpd_irq_handler [i915]] digital hpd port B - short
[ 452.344765] [drm:drm_dp_dpcd_read [drm_kms_helper]] DPDDC-B: 0x02002 AUX -> (ret= 14) 01 10 00 00 00 00 00 00 00 00 77 77 01 00
[ 452.346263] [drm:drm_dp_dpcd_read [drm_kms_helper]] DPDDC-B: 0x01400 AUX -> (ret= 16) 10 46 d6 11 10 01 00 00 78 00 00 00 00 00 00 00
[ 452.346287] [drm:drm_dp_get_mst_branch_device [drm_kms_helper]] mstb 00000000eec1a629 (3)
[ 452.346305] [drm:drm_dp_mst_topology_put_mstb [drm_kms_helper]] mstb 00000000eec1a629 (2)
[ 452.346405] [drm:drm_dp_mst_topology_put_mstb [drm_kms_helper]] mstb 00000000eec1a629 (1)
[ 452.347529] [drm:drm_dp_dpcd_write [drm_kms_helper]] DPDDC-B: 0x02003 AUX <- (ret= 3) 10 00 00
[ 452.348672] [drm:drm_dp_dpcd_write [drm_kms_helper]] DPDDC-B: 0x002c0 AUX <- (ret= 1) 01
[ 452.350168] [drm:drm_dp_dpcd_read [drm_kms_helper]] DPDDC-B: 0x02002 AUX -> (ret= 14) 01 00 00 00 00 00 00 00 00 00 77 77 01 00
[ 452.351328] [drm:drm_dp_dpcd_write [drm_kms_helper]] DPDDC-B: 0x001c0 AUX <- (ret= 3) 01 01 00
[ 452.352665] [drm:drm_dp_dpcd_read [drm_kms_helper]] DPDDC-B: 0x002c0 AUX -> (ret= 1) 01
[ 452.358905] [drm:drm_dp_dpcd_read [drm_kms_helper]] DPDDC-B: 0x002c0 AUX -> (ret= 1) 01
[ 452.360327] [drm:drm_dp_dpcd_read [drm_kms_helper]] DPDDC-B: 0x002c0 AUX -> (ret= 1) 01
[ 452.361660] [drm:drm_dp_dpcd_read [drm_kms_helper]] DPDDC-B: 0x002c0 AUX -> (ret= 1) 03
[ 452.361681] [drm:drm_dp_mst_put_port_malloc [drm_kms_helper]] port 00000000dde1b00a (3)
[ 452.361700] [drm:drm_dp_mst_topology_get_port_validated [drm_kms_helper]] port 00000000dde1b00a (2)
[ 452.362894] [drm:drm_dp_dpcd_write [drm_kms_helper]] DPDDC-B: 0x01000 AUX <- (ret= 6) 10 43 c7 25 10 c0
[ 452.364318] [drm:gen8_de_irq_handler [i915]] hotplug event received, stat 0x00200000, dig 0x10101011, pins 0x00000020, long 0x00000000
[ 452.364421] [drm:intel_hpd_irq_handler [i915]] digital hpd port B - short
[ 452.365929] [drm:drm_dp_dpcd_read [drm_kms_helper]] DPDDC-B: 0x02002 AUX -> (ret= 14) 01 10 00 00 00 00 00 00 00 00 77 77 01 00
[ 452.367361] [drm:drm_dp_dpcd_read [drm_kms_helper]] DPDDC-B: 0x01400 AUX -> (ret= 16) 10 43 c7 25 10 c0 00 00 00 00 00 00 00 00 00 00
[ 452.367388] [drm:drm_dp_get_mst_branch_device [drm_kms_helper]] mstb 00000000eec1a629 (2)
[ 452.367407] [drm:drm_dp_mst_topology_put_mstb [drm_kms_helper]] mstb 00000000eec1a629 (1)
[ 452.367460] [drm:drm_dp_mst_topology_put_port [drm_kms_helper]] port 00000000dde1b00a (1)
[ 452.368548] [drm:drm_dp_dpcd_write [drm_kms_helper]] DPDDC-B: 0x02003 AUX <- (ret= 3) 10 00 00
[ 452.368803] [drm:drm_dp_dpcd_write [drm_kms_helper]] DPDDC-B: 0x00600 AUX <- (ret= 1) 02
[ 452.368970] [drm:intel_dump_cdclk_state [i915]] Changing CDCLK to 337500 kHz, VCO 8100000 kHz, ref 24000 kHz, bypass 24000 kHz, voltage level 0
[ 452.369269] [drm:drm_mode_object_put.part.3 [drm]] OBJ ID: 123 (1)
[ 452.369330] [drm:drm_mode_object_put.part.3 [drm]] OBJ ID: 124 (1)
[ 452.369422] [drm:drm_mode_object_put.part.3 [drm]] OBJ ID: 85 (5)
[ 452.369466] [drm:drm_mode_object_put.part.3 [drm]] OBJ ID: 85 (4)
[ 452.369515] [drm:drm_mode_object_put.part.3 [drm]] OBJ ID: 86 (5)
[ 452.369558] [drm:drm_mode_object_put.part.3 [drm]] OBJ ID: 86 (4)
[ 452.369608] [drm:drm_mode_object_put.part.3 [drm]] OBJ ID: 113 (3)
[ 452.369660] [drm:drm_mode_object_put.part.3 [drm]] OBJ ID: 113 (2)
[ 452.369690] [drm:drm_dp_mst_put_port_malloc [drm_kms_helper]] port 00000000dde1b00a (2)
[ 452.369750] [drm:drm_irq_uninstall [drm]] irq=177
[ 452.406452] [drm:drm_dp_dpcd_read [drm_kms_helper]] DPDDC-B: 0x02002 AUX -> (ret= 14) 01 00 00 00 00 00 00 00 00 00 00 00 80 00
[ 452.412626] [drm:drm_mode_object_put.part.3 [drm]] OBJ ID: 85 (3)
[ 452.412636] [drm:drm_mode_object_put.part.3 [drm]] OBJ ID: 91 (2)
[ 452.412644] [drm:drm_mode_object_put.part.3 [drm]] OBJ ID: 98 (2)
[ 452.412652] [drm:drm_mode_object_put.part.3 [drm]] OBJ ID: 104 (2)
[ 452.412660] [drm:drm_mode_object_put.part.3 [drm]] OBJ ID: 109 (2)
[ 452.412668] [drm:drm_mode_object_put.part.3 [drm]] OBJ ID: 86 (3)
[ 452.412676] [drm:drm_mode_object_put.part.3 [drm]] OBJ ID: 117 (2)
[ 452.412684] [drm:drm_mode_object_put.part.3 [drm]] OBJ ID: 120 (2)
[ 452.412692] [drm:drm_mode_object_put.part.3 [drm]] OBJ ID: 85 (2)
[ 452.412700] [drm:drm_mode_object_put.part.3 [drm]] OBJ ID: 86 (2)
[ 452.412708] [drm:drm_mode_object_put.part.3 [drm]] OBJ ID: 113 (1)
[ 452.424450] [drm:drm_dp_dpcd_write [drm_kms_helper]] DPDDC-B: 0x00111 AUX <- (ret= 1) 00
[ 452.424454] [drm:drm_dp_mst_topology_put_mstb [drm_kms_helper]] mstb 00000000eec1a629 (0)
[ 452.424457] [drm:drm_dp_mst_topology_put_port [drm_kms_helper]] port 00000000eeef3cfd (0)
[ 452.424461] ------------[ cut here ]------------
[ 452.424464] sysfs group 'power' not found for kobject 'drm_dp_aux5'
[ 452.424471] WARNING: CPU: 3 PID: 1887 at fs/sysfs/group.c:256 sysfs_remove_group+0x76/0x80
[ 452.424473] Modules linked in: vfat fat elan_i2c i915(O) intel_rapl x86_pkg_temp_thermal intel_powerclamp coretemp kvm_intel iTCO_wdt kvm mei_wdt irqbypass iTCO_vendor_support crct10dif_pclmul wmi_bmof intel_wmi_thunderbolt crc32_pclmul i2c_algo_bit ghash_clmulni_intel intel_cstate drm_kms_helper(O) intel_uncore intel_rapl_perf btusb btrtl btbcm syscopyarea btintel sysfillrect sysimgblt fb_sys_fops bluetooth drm(O) joydev mei_me idma64 ucsi_acpi thunderbolt ecdh_generic i2c_i801 intel_xhci_usb_role_switch processor_thermal_device typec_ucsi intel_lpss_pci intel_soc_dts_iosf mei roles intel_lpss typec intel_pch_thermal wmi thinkpad_acpi ledtrig_audio rfkill int3403_thermal int340x_thermal_zone int3400_thermal acpi_thermal_rel acpi_pad video pcc_cpufreq crc32c_intel nvme serio_raw uas e1000e nvme_core usb_storage i2c_dev
[ 452.424492] CPU: 3 PID: 1887 Comm: unloadgpumod Tainted: G O 5.1.0Lyude-Test+ #1
[ 452.424494] Hardware name: LENOVO 20L8S2N800/20L8S2N800, BIOS N22ET35W (1.12 ) 04/09/2018
[ 452.424496] RIP: 0010:sysfs_remove_group+0x76/0x80
[ 452.424498] Code: 48 89 df 5b 5d 41 5c e9 f8 bc ff ff 48 89 df e8 d0 bc ff ff eb cb 49 8b 14 24 48 8b 75 00 48 c7 c7 08 a5 0c aa e8 44 00 d6 ff <0f> 0b 5b 5d 41 5c c3 0f 1f 00 0f 1f 44 00 00 48 85 f6 74 31 41 54
[ 452.424500] RSP: 0018:ffffa8bb81b5fb28 EFLAGS: 00010282
[ 452.424501] RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000006
[ 452.424502] RDX: 0000000000000007 RSI: 0000000000000086 RDI: ffff981fde2d5a00
[ 452.424503] RBP: ffffffffa9ea12e0 R08: 0000000000000792 R09: 0000000000000046
[ 452.424504] R10: 0000000000000727 R11: ffffa8bb81b5f9d0 R12: ffff981fd5f77010
[ 452.424505] R13: ffff981fd6ebbedc R14: dead000000000200 R15: dead000000000100
[ 452.424507] FS: 00007f8cc1d8c740(0000) GS:ffff981fde2c0000(0000) knlGS:0000000000000000
[ 452.424508] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 452.424509] CR2: 000055b19d079a08 CR3: 000000043b2a0002 CR4: 00000000003606e0
[ 452.424510] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[ 452.424511] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
[ 452.424512] Call Trace:
[ 452.424516] device_del+0x75/0x360
[ 452.424518] ? class_find_device+0x96/0xf0
[ 452.424520] device_unregister+0x16/0x60
[ 452.424521] device_destroy+0x3a/0x40
[ 452.424525] drm_dp_aux_unregister_devnode+0xea/0x180 [drm_kms_helper]
[ 452.424534] ? drm_dbg+0x87/0x90 [drm]
[ 452.424538] drm_dp_mst_topology_put_port+0x5b/0x110 [drm_kms_helper]
[ 452.424543] drm_dp_mst_topology_put_mstb+0xb6/0x180 [drm_kms_helper]
[ 452.424547] drm_dp_mst_topology_mgr_set_mst+0x233/0x2b0 [drm_kms_helper]
[ 452.424551] drm_dp_mst_topology_mgr_destroy+0x18/0xa0 [drm_kms_helper]
[ 452.424571] intel_dp_encoder_flush_work+0x32/0xb0 [i915]
[ 452.424592] intel_ddi_encoder_destroy+0x32/0x70 [i915]
[ 452.424600] drm_mode_config_cleanup+0x51/0x2e0 [drm]
[ 452.424621] intel_modeset_cleanup+0xc8/0x140 [i915]
[ 452.424633] i915_driver_unload+0xa8/0x130 [i915]
[ 452.424645] i915_pci_remove+0x1e/0x40 [i915]
[ 452.424647] pci_device_remove+0x3b/0xc0
[ 452.424649] device_release_driver_internal+0xe4/0x1d0
[ 452.424651] pci_stop_bus_device+0x69/0x90
[ 452.424653] pci_stop_and_remove_bus_device_locked+0x16/0x30
[ 452.424655] remove_store+0x75/0x90
[ 452.424656] kernfs_fop_write+0x116/0x190
[ 452.424658] vfs_write+0xa5/0x1a0
[ 452.424660] ksys_write+0x57/0xd0
[ 452.424663] do_syscall_64+0x55/0x150
[ 452.424665] entry_SYSCALL_64_after_hwframe+0x44/0xa9
[ 452.424667] RIP: 0033:0x7f8cc1e7d038
[ 452.424668] Code: 89 02 48 c7 c0 ff ff ff ff eb b3 0f 1f 80 00 00 00 00 f3 0f 1e fa 48 8d 05 e5 76 0d 00 8b 00 85 c0 75 17 b8 01 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 58 c3 0f 1f 80 00 00 00 00 41 54 49 89 d4 55
[ 452.424670] RSP: 002b:00007ffce4321218 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
[ 452.424672] RAX: ffffffffffffffda RBX: 0000000000000002 RCX: 00007f8cc1e7d038
[ 452.424673] RDX: 0000000000000002 RSI: 000056515aefbf00 RDI: 0000000000000001
[ 452.424674] RBP: 000056515aefbf00 R08: 000000000000000a R09: 00007f8cc1f0ee80
[ 452.424675] R10: 000000000000000a R11: 0000000000000246 R12: 00007f8cc1f50780
[ 452.424676] R13: 0000000000000002 R14: 00007f8cc1f4b740 R15: 0000000000000002
[ 452.424678] WARNING: CPU: 3 PID: 1887 at fs/sysfs/group.c:256 sysfs_remove_group+0x76/0x80
[ 452.424680] ---[ end trace a1c11eaf054910a3 ]---
[ 452.424751] [drm:drm_dp_aux_unregister_devnode [drm_kms_helper]] drm_dp_aux_dev: aux [DPMST] unregistering
[ 452.424755] [drm:drm_dp_mst_topology_put_port [drm_kms_helper]] port 000000000f6aa5a3 (0)
[ 452.424765] [drm:drm_mode_object_put.part.3 [drm]] OBJ ID: 120 (1)
[ 452.424770] [drm:drm_dp_mst_put_port_malloc [drm_kms_helper]] port 00000000eeef3cfd (1)
[ 452.424773] [drm:drm_dp_mst_put_port_malloc [drm_kms_helper]] port 00000000eeef3cfd (0)
[ 452.424776] [drm:drm_dp_mst_put_mstb_malloc [drm_kms_helper]] mstb 00000000eec1a629 (4)
[ 452.424783] [drm:drm_sysfs_hotplug_event [drm]] generating hotplug event
[ 452.424790] ------------[ cut here ]------------
[ 452.424791] sysfs group 'power' not found for kobject 'drm_dp_aux4'
[ 452.424795] WARNING: CPU: 3 PID: 1887 at fs/sysfs/group.c:256 sysfs_remove_group+0x76/0x80
[ 452.424796] Modules linked in: vfat fat elan_i2c i915(O) intel_rapl x86_pkg_temp_thermal intel_powerclamp coretemp kvm_intel iTCO_wdt kvm mei_wdt irqbypass iTCO_vendor_support crct10dif_pclmul wmi_bmof intel_wmi_thunderbolt crc32_pclmul i2c_algo_bit ghash_clmulni_intel intel_cstate drm_kms_helper(O) intel_uncore intel_rapl_perf btusb btrtl btbcm syscopyarea btintel sysfillrect sysimgblt fb_sys_fops bluetooth drm(O) joydev mei_me idma64 ucsi_acpi thunderbolt ecdh_generic i2c_i801 intel_xhci_usb_role_switch processor_thermal_device typec_ucsi intel_lpss_pci intel_soc_dts_iosf mei roles intel_lpss typec intel_pch_thermal wmi thinkpad_acpi ledtrig_audio rfkill int3403_thermal int340x_thermal_zone int3400_thermal acpi_thermal_rel acpi_pad video pcc_cpufreq crc32c_intel nvme serio_raw uas e1000e nvme_core usb_storage i2c_dev
[ 452.424809] CPU: 3 PID: 1887 Comm: unloadgpumod Tainted: G W O 5.1.0Lyude-Test+ #1
[ 452.424811] Hardware name: LENOVO 20L8S2N800/20L8S2N800, BIOS N22ET35W (1.12 ) 04/09/2018
[ 452.424812] RIP: 0010:sysfs_remove_group+0x76/0x80
[ 452.424813] Code: 48 89 df 5b 5d 41 5c e9 f8 bc ff ff 48 89 df e8 d0 bc ff ff eb cb 49 8b 14 24 48 8b 75 00 48 c7 c7 08 a5 0c aa e8 44 00 d6 ff <0f> 0b 5b 5d 41 5c c3 0f 1f 00 0f 1f 44 00 00 48 85 f6 74 31 41 54
[ 452.424815] RSP: 0018:ffffa8bb81b5fb28 EFLAGS: 00010282
[ 452.424816] RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000006
[ 452.424817] RDX: 0000000000000007 RSI: 0000000000000086 RDI: ffff981fde2d5a00
[ 452.424818] RBP: ffffffffa9ea12e0 R08: 00000000000007d1 R09: 0000000000000046
[ 452.424820] R10: 0000000000000727 R11: ffffa8bb81b5f9d0 R12: ffff981fd50d0410
[ 452.424821] R13: ffff981fd6ebbebc R14: dead000000000200 R15: dead000000000100
[ 452.424822] FS: 00007f8cc1d8c740(0000) GS:ffff981fde2c0000(0000) knlGS:0000000000000000
[ 452.424823] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 452.424824] CR2: 000055b19d079a08 CR3: 000000043b2a0002 CR4: 00000000003606e0
[ 452.424825] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[ 452.424826] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
[ 452.424827] Call Trace:
[ 452.424829] device_del+0x75/0x360
[ 452.424830] ? class_find_device+0x96/0xf0
[ 452.424832] device_unregister+0x16/0x60
[ 452.424833] device_destroy+0x3a/0x40
[ 452.424837] drm_dp_aux_unregister_devnode+0xea/0x180 [drm_kms_helper]
[ 452.424841] drm_dp_mst_topology_put_port+0x5b/0x110 [drm_kms_helper]
[ 452.424845] drm_dp_mst_topology_put_mstb+0xb6/0x180 [drm_kms_helper]
[ 452.424849] drm_dp_mst_topology_mgr_set_mst+0x233/0x2b0 [drm_kms_helper]
[ 452.424854] drm_dp_mst_topology_mgr_destroy+0x18/0xa0 [drm_kms_helper]
[ 452.424873] intel_dp_encoder_flush_work+0x32/0xb0 [i915]
[ 452.424892] intel_ddi_encoder_destroy+0x32/0x70 [i915]
[ 452.424900] drm_mode_config_cleanup+0x51/0x2e0 [drm]
[ 452.424920] intel_modeset_cleanup+0xc8/0x140 [i915]
[ 452.424932] i915_driver_unload+0xa8/0x130 [i915]
[ 452.424943] i915_pci_remove+0x1e/0x40 [i915]
[ 452.424945] pci_device_remove+0x3b/0xc0
[ 452.424947] device_release_driver_internal+0xe4/0x1d0
[ 452.424948] pci_stop_bus_device+0x69/0x90
[ 452.424950] pci_stop_and_remove_bus_device_locked+0x16/0x30
[ 452.424951] remove_store+0x75/0x90
[ 452.424953] kernfs_fop_write+0x116/0x190
[ 452.424954] vfs_write+0xa5/0x1a0
[ 452.424956] ksys_write+0x57/0xd0
[ 452.424957] do_syscall_64+0x55/0x150
[ 452.424959] entry_SYSCALL_64_after_hwframe+0x44/0xa9
[ 452.424960] RIP: 0033:0x7f8cc1e7d038
[ 452.424961] Code: 89 02 48 c7 c0 ff ff ff ff eb b3 0f 1f 80 00 00 00 00 f3 0f 1e fa 48 8d 05 e5 76 0d 00 8b 00 85 c0 75 17 b8 01 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 58 c3 0f 1f 80 00 00 00 00 41 54 49 89 d4 55
[ 452.424963] RSP: 002b:00007ffce4321218 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
[ 452.424965] RAX: ffffffffffffffda RBX: 0000000000000002 RCX: 00007f8cc1e7d038
[ 452.424966] RDX: 0000000000000002 RSI: 000056515aefbf00 RDI: 0000000000000001
[ 452.424967] RBP: 000056515aefbf00 R08: 000000000000000a R09: 00007f8cc1f0ee80
[ 452.424968] R10: 000000000000000a R11: 0000000000000246 R12: 00007f8cc1f50780
[ 452.424969] R13: 0000000000000002 R14: 00007f8cc1f4b740 R15: 0000000000000002
[ 452.424971] WARNING: CPU: 3 PID: 1887 at fs/sysfs/group.c:256 sysfs_remove_group+0x76/0x80
[ 452.424972] ---[ end trace a1c11eaf054910a4 ]---
[ 452.424992] [drm:drm_dp_aux_unregister_devnode [drm_kms_helper]] drm_dp_aux_dev: aux [DPMST] unregistering
[ 452.424997] [drm:drm_dp_mst_topology_put_port [drm_kms_helper]] port 00000000dde1b00a (0)
[ 452.425006] [drm:drm_mode_object_put.part.3 [drm]] OBJ ID: 117 (1)
[ 452.425010] [drm:drm_dp_mst_put_port_malloc [drm_kms_helper]] port 000000000f6aa5a3 (1)
[ 452.425014] [drm:drm_dp_mst_put_port_malloc [drm_kms_helper]] port 000000000f6aa5a3 (0)
[ 452.425017] [drm:drm_dp_mst_put_mstb_malloc [drm_kms_helper]] mstb 00000000eec1a629 (3)
[ 452.425023] [drm:drm_sysfs_hotplug_event [drm]] generating hotplug event
[ 452.425028] ------------[ cut here ]------------
[ 452.425029] sysfs group 'power' not found for kobject 'drm_dp_aux3'
[ 452.425033] WARNING: CPU: 3 PID: 1887 at fs/sysfs/group.c:256 sysfs_remove_group+0x76/0x80
[ 452.425034] Modules linked in: vfat fat elan_i2c i915(O) intel_rapl x86_pkg_temp_thermal intel_powerclamp coretemp kvm_intel iTCO_wdt kvm mei_wdt irqbypass iTCO_vendor_support crct10dif_pclmul wmi_bmof intel_wmi_thunderbolt crc32_pclmul i2c_algo_bit ghash_clmulni_intel intel_cstate drm_kms_helper(O) intel_uncore intel_rapl_perf btusb btrtl btbcm syscopyarea btintel sysfillrect sysimgblt fb_sys_fops bluetooth drm(O) joydev mei_me idma64 ucsi_acpi thunderbolt ecdh_generic i2c_i801 intel_xhci_usb_role_switch processor_thermal_device typec_ucsi intel_lpss_pci intel_soc_dts_iosf mei roles intel_lpss typec intel_pch_thermal wmi thinkpad_acpi ledtrig_audio rfkill int3403_thermal int340x_thermal_zone int3400_thermal acpi_thermal_rel acpi_pad video pcc_cpufreq crc32c_intel nvme serio_raw uas e1000e nvme_core usb_storage i2c_dev
[ 452.425047] CPU: 3 PID: 1887 Comm: unloadgpumod Tainted: G W O 5.1.0Lyude-Test+ #1
[ 452.425048] Hardware name: LENOVO 20L8S2N800/20L8S2N800, BIOS N22ET35W (1.12 ) 04/09/2018
[ 452.425050] RIP: 0010:sysfs_remove_group+0x76/0x80
[ 452.425051] Code: 48 89 df 5b 5d 41 5c e9 f8 bc ff ff 48 89 df e8 d0 bc ff ff eb cb 49 8b 14 24 48 8b 75 00 48 c7 c7 08 a5 0c aa e8 44 00 d6 ff <0f> 0b 5b 5d 41 5c c3 0f 1f 00 0f 1f 44 00 00 48 85 f6 74 31 41 54
[ 452.425053] RSP: 0018:ffffa8bb81b5fb28 EFLAGS: 00010282
[ 452.425054] RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000006
[ 452.425055] RDX: 0000000000000007 RSI: 0000000000000086 RDI: ffff981fde2d5a00
[ 452.425056] RBP: ffffffffa9ea12e0 R08: 000000000000080f R09: 0000000000000046
[ 452.425057] R10: 0000000000000727 R11: ffffa8bb81b5f9d0 R12: ffff981fd50d1810
[ 452.425058] R13: ffff981fd6ebbe1c R14: dead000000000200 R15: dead000000000100
[ 452.425059] FS: 00007f8cc1d8c740(0000) GS:ffff981fde2c0000(0000) knlGS:0000000000000000
[ 452.425061] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 452.425062] CR2: 000055b19d079a08 CR3: 000000043b2a0002 CR4: 00000000003606e0
[ 452.425063] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[ 452.425064] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
[ 452.425065] Call Trace:
[ 452.425066] device_del+0x75/0x360
[ 452.425068] ? class_find_device+0x96/0xf0
[ 452.425069] device_unregister+0x16/0x60
[ 452.425070] device_destroy+0x3a/0x40
[ 452.425074] drm_dp_aux_unregister_devnode+0xea/0x180 [drm_kms_helper]
[ 452.425078] drm_dp_mst_topology_put_port+0x5b/0x110 [drm_kms_helper]
[ 452.425083] drm_dp_mst_topology_put_mstb+0xb6/0x180 [drm_kms_helper]
[ 452.425087] drm_dp_mst_topology_mgr_set_mst+0x233/0x2b0 [drm_kms_helper]
[ 452.425091] drm_dp_mst_topology_mgr_destroy+0x18/0xa0 [drm_kms_helper]
[ 452.425110] intel_dp_encoder_flush_work+0x32/0xb0 [i915]
[ 452.425128] intel_ddi_encoder_destroy+0x32/0x70 [i915]
[ 452.425137] drm_mode_config_cleanup+0x51/0x2e0 [drm]
[ 452.425157] intel_modeset_cleanup+0xc8/0x140 [i915]
[ 452.425168] i915_driver_unload+0xa8/0x130 [i915]
[ 452.425180] i915_pci_remove+0x1e/0x40 [i915]
[ 452.425182] pci_device_remove+0x3b/0xc0
[ 452.425183] device_release_driver_internal+0xe4/0x1d0
[ 452.425185] pci_stop_bus_device+0x69/0x90
[ 452.425186] pci_stop_and_remove_bus_device_locked+0x16/0x30
[ 452.425188] remove_store+0x75/0x90
[ 452.425189] kernfs_fop_write+0x116/0x190
[ 452.425191] vfs_write+0xa5/0x1a0
[ 452.425192] ksys_write+0x57/0xd0
[ 452.425194] do_syscall_64+0x55/0x150
[ 452.425195] entry_SYSCALL_64_after_hwframe+0x44/0xa9
[ 452.425197] RIP: 0033:0x7f8cc1e7d038
[ 452.425198] Code: 89 02 48 c7 c0 ff ff ff ff eb b3 0f 1f 80 00 00 00 00 f3 0f 1e fa 48 8d 05 e5 76 0d 00 8b 00 85 c0 75 17 b8 01 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 58 c3 0f 1f 80 00 00 00 00 41 54 49 89 d4 55
[ 452.425199] RSP: 002b:00007ffce4321218 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
[ 452.425201] RAX: ffffffffffffffda RBX: 0000000000000002 RCX: 00007f8cc1e7d038
[ 452.425202] RDX: 0000000000000002 RSI: 000056515aefbf00 RDI: 0000000000000001
[ 452.425203] RBP: 000056515aefbf00 R08: 000000000000000a R09: 00007f8cc1f0ee80
[ 452.425204] R10: 000000000000000a R11: 0000000000000246 R12: 00007f8cc1f50780
[ 452.425205] R13: 0000000000000002 R14: 00007f8cc1f4b740 R15: 0000000000000002
[ 452.425207] WARNING: CPU: 3 PID: 1887 at fs/sysfs/group.c:256 sysfs_remove_group+0x76/0x80
[ 452.425208] ---[ end trace a1c11eaf054910a5 ]---
[ 452.425282] [drm:drm_dp_aux_unregister_devnode [drm_kms_helper]] drm_dp_aux_dev: aux [DPMST] unregistering
[ 452.425288] [drm:drm_dp_mst_topology_put_port [drm_kms_helper]] port 000000002ba3174e (0)
[ 452.425292] [drm:drm_dp_mst_put_port_malloc [drm_kms_helper]] port 000000002ba3174e (0)
[ 452.425295] [drm:drm_dp_mst_put_mstb_malloc [drm_kms_helper]] mstb 00000000eec1a629 (2)
[ 452.425299] [drm:drm_dp_mst_put_mstb_malloc [drm_kms_helper]] mstb 00000000eec1a629 (1)
[ 452.425311] [drm:drm_mode_object_put.part.3 [drm]] OBJ ID: 86 (1)
[ 452.425318] [drm:drm_dp_mst_put_port_malloc [drm_kms_helper]] port 00000000dde1b00a (1)
[ 452.425365] [drm:drm_dp_mst_put_port_malloc [drm_kms_helper]] port 00000000dde1b00a (0)
[ 452.425368] [drm:drm_dp_mst_put_mstb_malloc [drm_kms_helper]] mstb 00000000eec1a629 (0)
So, we need to move the drm_dp_aux_register_devnode() call above the connector
registration callback. Same goes for the port->aux.dev = port->connector-
>kdev; assignment that you do in patch 3/7 (and of course, you can remove the
connector registration status check there now).
> +
> + drm_dp_aux_register_devnode(&port->aux);
> }
>
> out:
> @@ -1404,7 +1454,6 @@ static bool drm_dp_validate_guid(struct
> drm_dp_mst_topology_mgr *mgr,
> return false;
> }
>
> -#if 0
> static int build_dpcd_read(struct drm_dp_sideband_msg_tx *msg, u8 port_num,
> u32 offset, u8 num_bytes)
> {
> struct drm_dp_sideband_msg_req_body req;
> @@ -1417,7 +1466,6 @@ static int build_dpcd_read(struct
> drm_dp_sideband_msg_tx *msg, u8 port_num, u32
>
> return 0;
> }
> -#endif
>
> static int drm_dp_send_sideband_msg(struct drm_dp_mst_topology_mgr *mgr,
> bool up, u8 *msg, int len)
> @@ -1994,26 +2042,55 @@ int drm_dp_update_payload_part2(struct
> drm_dp_mst_topology_mgr *mgr)
> }
> EXPORT_SYMBOL(drm_dp_update_payload_part2);
>
> -#if 0 /* unused as of yet */
> static int drm_dp_send_dpcd_read(struct drm_dp_mst_topology_mgr *mgr,
> struct drm_dp_mst_port *port,
> - int offset, int size)
> + int offset, int size, u8 *bytes)
> {
> int len;
> + int ret = 0;
> struct drm_dp_sideband_msg_tx *txmsg;
> + struct drm_dp_mst_branch *mstb;
> +
> + mstb = drm_dp_get_validated_mstb_ref(mgr, port->parent);
> + if (!mstb)
> + return -EINVAL;
>
> txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);
> - if (!txmsg)
> - return -ENOMEM;
> + if (!txmsg) {
> + ret = -ENOMEM;
> + goto fail_put;
> + }
>
> - len = build_dpcd_read(txmsg, port->port_num, 0, 8);
> + len = build_dpcd_read(txmsg, port->port_num, offset, size);
> txmsg->dst = port->parent;
>
> drm_dp_queue_down_tx(mgr, txmsg);
>
> - return 0;
> + ret = drm_dp_mst_wait_tx_reply(mstb, txmsg);
> + if (ret < 0)
> + goto fail_free;
> +
> + /* DPCD read should never be NACKed */
> + if (WARN_ON_ONCE(txmsg->reply.reply_type == 1)) {
> + ret = -EIO;
> + goto fail_free;
> + }
> +
> + if (txmsg->reply.u.remote_dpcd_read_ack.num_bytes != size) {
> + ret = -EPROTO;
> + goto fail_free;
> + }
> +
> + ret = min_t(size_t, txmsg->reply.u.remote_dpcd_read_ack.num_bytes,
> size);
> + memcpy(bytes, txmsg->reply.u.remote_dpcd_read_ack.bytes, ret);
> +
> +fail_free:
> + kfree(txmsg);
> +fail_put:
> + drm_dp_put_mst_branch_device(mstb);
> +
> + return ret;
> }
> -#endif
>
> static int drm_dp_send_dpcd_write(struct drm_dp_mst_topology_mgr *mgr,
> struct drm_dp_mst_port *port,
> @@ -2041,9 +2118,9 @@ static int drm_dp_send_dpcd_write(struct
> drm_dp_mst_topology_mgr *mgr,
>
> ret = drm_dp_mst_wait_tx_reply(mstb, txmsg);
> if (ret > 0) {
> - if (txmsg->reply.reply_type == 1) {
> - ret = -EINVAL;
> - } else
> + if (txmsg->reply.reply_type == 1)
> + ret = -EIO;
> + else
> ret = 0;
> }
> kfree(txmsg);
> diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
> index 509667e..6dea76a 100644
> --- a/include/drm/drm_dp_helper.h
> +++ b/include/drm/drm_dp_helper.h
> @@ -1265,6 +1265,10 @@ struct drm_dp_aux {
> * @cec: struct containing fields used for CEC-Tunneling-over-AUX.
> */
> struct drm_dp_aux_cec cec;
> + /**
> + * @is_remote: Is this "AUX CH" actually using sideband messaging.
> + */
> + bool is_remote;
> };
>
> ssize_t drm_dp_dpcd_read(struct drm_dp_aux *aux, unsigned int offset,
> diff --git a/include/drm/drm_dp_mst_helper.h
> b/include/drm/drm_dp_mst_helper.h
> index 371cc28..30f8c11 100644
> --- a/include/drm/drm_dp_mst_helper.h
> +++ b/include/drm/drm_dp_mst_helper.h
> @@ -615,6 +615,12 @@ void drm_dp_mst_dump_topology(struct seq_file *m,
>
> void drm_dp_mst_topology_mgr_suspend(struct drm_dp_mst_topology_mgr *mgr);
> int drm_dp_mst_topology_mgr_resume(struct drm_dp_mst_topology_mgr *mgr);
> +
> +ssize_t drm_dp_mst_dpcd_read(struct drm_dp_aux *aux,
> + unsigned int offset, void *buffer, size_t size);
> +ssize_t drm_dp_mst_dpcd_write(struct drm_dp_aux *aux,
> + unsigned int offset, void *buffer, size_t size);
> +
> struct drm_dp_mst_topology_state *drm_atomic_get_mst_topology_state(struct
> drm_atomic_state *state,
> struct
> drm_dp_mst_topology_mgr *mgr);
> int drm_dp_atomic_find_vcpi_slots(struct drm_atomic_state *state,
--
Cheers,
Lyude Paul
More information about the amd-gfx
mailing list