Message ID | 1558019883-12397-3-git-send-email-sunpeng.li@amd.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Add DP MST AUX devices | expand |
So a couple of things: On Thu, 2019-05-16 at 11:17 -0400, sunpeng.li@amd.com wrote: > From: Ville Syrjälä <ville.syrjala@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@redhat.com> > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> > Signed-off-by: Leo Li <sunpeng.li@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,
Hey, sorry for my late response! On 2019-05-16 5:40 p.m., Lyude Paul wrote: >> 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: **snip** > [ 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 ]--- **snip** > > 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). Hmm, I don't think that will quite work for the purpose of the series. If I register the aux device before the connector's, I wouldn't be able to set the connector's kdev as parent. The udev rules depend on this hierarchy to generate the symlinks we want - it reads the parent connector's attrs. How are you reproducing this? I can try debugging this on an intel system. It looks like there's an expected 'power' attribute group that's missing when unregistering the aux device - I wonder where that gets attached. Thanks, Leo > >> + >> + drm_dp_aux_register_devnode(&port->aux); >> }
On Thu, 2019-05-30 at 18:20 +0000, Li, Sun peng (Leo) wrote: > Hey, sorry for my late response! > > On 2019-05-16 5:40 p.m., Lyude Paul wrote: > > > > 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: > > **snip** > > > [ 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 ]--- > > **snip** > > > 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). > > Hmm, I don't think that will quite work for the purpose of the series. > > If I register the aux device before the connector's, I wouldn't be able > to set the connector's kdev as parent. The udev rules depend on this > hierarchy to generate the symlinks we want - it reads the parent > connector's attrs. eesh, you're right-somehow I didn't notice that. Guess we'll need some sort of other fix then > > How are you reproducing this? I can try debugging this on an intel > system. It looks like there's an expected 'power' attribute group that's > missing when unregistering the aux device - I wonder where that gets > attached. I'm reproducing this just by reloading i915 on a machine with some MST displays connected. I uploaded a copy of the script that I use to do this here: https://people.freedesktop.org/~lyudess/archive/06-03-2019/unloadgpumod.sh Given a module (in this case drm.ko), it will go through and unload all of the modules depending on it, then drm.ko, then reload. > > Thanks, > Leo > > > > + > > > + drm_dp_aux_register_devnode(&port->aux); > > > }
On Mon, 2019-06-03 at 15:25 -0400, Lyude Paul wrote: > On Thu, 2019-05-30 at 18:20 +0000, Li, Sun peng (Leo) wrote: > > Hey, sorry for my late response! > > > > On 2019-05-16 5:40 p.m., Lyude Paul wrote: > > > > > > 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: > > > > **snip** > > > > > [ 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 ]--- > > > > **snip** > > > > > 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). > > > > Hmm, I don't think that will quite work for the purpose of the series. > > > > If I register the aux device before the connector's, I wouldn't be able > > to set the connector's kdev as parent. The udev rules depend on this > > hierarchy to generate the symlinks we want - it reads the parent > > connector's attrs. > > eesh, you're right-somehow I didn't notice that. Guess we'll need some sort > of > other fix then > > > How are you reproducing this? I can try debugging this on an intel > > system. It looks like there's an expected 'power' attribute group that's > > missing when unregistering the aux device - I wonder where that gets > > attached. > > I'm reproducing this just by reloading i915 on a machine with some MST > displays connected. I uploaded a copy of the script that I use to do this > here: > > https://people.freedesktop.org/~lyudess/archive/06-03-2019/unloadgpumod.sh oops-almost forgot to mention. The argument you pass to make it reload instead of just unloading is --reload > > Given a module (in this case drm.ko), it will go through and unload all of > the > modules depending on it, then drm.ko, then reload. > > Thanks, > > Leo > > > > > > + > > > > + drm_dp_aux_register_devnode(&port->aux); > > > > }
On 2019-06-03 3:28 p.m., Lyude Paul wrote: >> I'm reproducing this just by reloading i915 on a machine with some MST >> displays connected. I uploaded a copy of the script that I use to do this >> here: >> >> https://people.freedesktop.org/~lyudess/archive/06-03-2019/unloadgpumod.sh > oops-almost forgot to mention. The argument you pass to make it reload instead > of just unloading is --reload > Thanks for the script! So, the warning has to do with: 1. Having the aux device as a child of connector device, and 2. During driver unload, drm_connector_unregister() is called before drm_dp_mst_topology_put_port() Which means that connector_unregister() will recursively remove the child aux device, before put_port() can properly unregister it. Any further attempts to remove after the first will throw a "not found" warning. Call-stacks for reference: *drm_connector_unregister*+0x37/0x60 [drm] drm_connector_unregister_all+0x30/0x60 [drm] drm_modeset_unregister_all+0xe/0x30 [drm] drm_dev_unregister+0x9c/0xb0 [drm] i915_driver_unload+0x73/0x120 [i915] drm_dp_aux_unregister_devnode+0xf5/0x180 [drm_kms_helper] *drm_dp_mst_topology_put_port*+0x4e/0xf0 [drm_kms_helper] drm_dp_mst_topology_put_mstb+0x91/0x160 [drm_kms_helper] drm_dp_mst_topology_mgr_set_mst+0x12b/0x2b0 [drm_kms_helper] ? __finish_swait+0x10/0x40 drm_dp_mst_topology_mgr_destroy+0x11/0xa0 [drm_kms_helper] intel_dp_encoder_flush_work+0x32/0xb0 [i915] intel_ddi_encoder_destroy+0x32/0x60 [i915] drm_mode_config_cleanup+0x51/0x2e0 [drm] intel_modeset_cleanup+0xc8/0x140 [i915] i915_driver_unload+0xa0/0x120 [i915] A solution is to unregister the aux device immediately before the connector device is unregistered - if we are to keep the aux device as a child. Following current scheme with SST, it looks like drm_connector_funcs->early_unregister() is the right place to do so. To keep the balance, aux registration will then happen in drm_connector_funcs->late_register(). This will leave the SDP transaction handling part in DRM still, but pass the responsibility of creating and removing remote (fake) aux devices to the driver. I have a WIP patch here for you to take a look. It should apply on top of the existing patchset: https://pastebin.com/1YJZhL4C I'd like to hear your thoughts, before I go and modify other drivers :) Thanks, Leo
On Thu, 2019-06-06 at 19:41 +0000, Li, Sun peng (Leo) wrote: > > On 2019-06-03 3:28 p.m., Lyude Paul wrote: > > > I'm reproducing this just by reloading i915 on a machine with some MST > > > displays connected. I uploaded a copy of the script that I use to do > > > this > > > here: > > > > > > https://people.freedesktop.org/~lyudess/archive/06-03-2019/unloadgpumod.sh > > oops-almost forgot to mention. The argument you pass to make it reload > > instead > > of just unloading is --reload > > > > Thanks for the script! > > So, the warning has to do with: > > 1. Having the aux device as a child of connector device, and > 2. During driver unload, drm_connector_unregister() is called before > drm_dp_mst_topology_put_port() > > Which means that connector_unregister() will recursively remove the > child aux device, before put_port() can properly unregister it. Any > further attempts to remove after the first will throw a "not found" warning. > > Call-stacks for reference: > > *drm_connector_unregister*+0x37/0x60 [drm] > drm_connector_unregister_all+0x30/0x60 [drm] > drm_modeset_unregister_all+0xe/0x30 [drm] > drm_dev_unregister+0x9c/0xb0 [drm] > i915_driver_unload+0x73/0x120 [i915] > > drm_dp_aux_unregister_devnode+0xf5/0x180 [drm_kms_helper] > *drm_dp_mst_topology_put_port*+0x4e/0xf0 [drm_kms_helper] > drm_dp_mst_topology_put_mstb+0x91/0x160 [drm_kms_helper] > drm_dp_mst_topology_mgr_set_mst+0x12b/0x2b0 [drm_kms_helper] > ? __finish_swait+0x10/0x40 > drm_dp_mst_topology_mgr_destroy+0x11/0xa0 [drm_kms_helper] > intel_dp_encoder_flush_work+0x32/0xb0 [i915] > intel_ddi_encoder_destroy+0x32/0x60 [i915] > drm_mode_config_cleanup+0x51/0x2e0 [drm] > intel_modeset_cleanup+0xc8/0x140 [i915] > i915_driver_unload+0xa0/0x120 [i915] > > A solution is to unregister the aux device immediately before the > connector device is unregistered - if we are to keep the aux device as a > child. Following current scheme with SST, it looks like > drm_connector_funcs->early_unregister() is the right place to do so. > To keep the balance, aux registration will then happen in > drm_connector_funcs->late_register(). This will leave the SDP > transaction handling part in DRM still, but pass the responsibility of > creating and removing remote (fake) aux devices to the driver. > > I have a WIP patch here for you to take a look. It should apply on top > of the existing patchset: > https://pastebin.com/1YJZhL4C > This approach seems fine to me! I was thinking we might end up doing something like this. My only thought is that we can probably write up a drm_dp_mst_connector_late_register() and drm_dp_mst_connector_early_unregister() that drivers can call from their →late_register()/→early_unregister() callbacks that handles printing the debug message, setting the parent and registering/unregistering the aux device. I'd imagine someday in the future we'll probably have more things to add to those callbacks for mst as well. > I'd like to hear your thoughts, before I go and modify other drivers :) > > Thanks, > Leo
Sorry for the late response! just jumping back on this now. On 2019-05-16 5:40 p.m., Lyude Paul wrote: > [CAUTION: External Email] > > So a couple of things: > > On Thu, 2019-05-16 at 11:17 -0400, sunpeng.li@amd.com wrote: >> From: Ville Syrjälä <ville.syrjala@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@redhat.com> >> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> >> Signed-off-by: Leo Li <sunpeng.li@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(). > I'm not sure if this would work well. The existing policy does retries around the ->transfer() call. Using the same hook will cause a nested retry - once when calling remote_aux->transfer, and another when calling real_aux->transfer. The difference is the scope of the retry. The former replays the entire aux transaction, while the latter replays just the failed sideband packet. I think having the retry at the packet level makes more sense. Either way, it shouldn't happen in a nested manner. In general, we need a way to determine whether a message needs to be sent via sideband. I'm not sure if there's a better way than setting a 'is_remote' flag? Leo >> 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 >
On Thu, 2019-06-27 at 22:21 +0000, Li, Sun peng (Leo) wrote: > Sorry for the late response! just jumping back on this now. > > On 2019-05-16 5:40 p.m., Lyude Paul wrote: > > [CAUTION: External Email] > > > > So a couple of things: > > > > On Thu, 2019-05-16 at 11:17 -0400, sunpeng.li@amd.com wrote: > > > From: Ville Syrjälä <ville.syrjala@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@redhat.com> > > > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> > > > Signed-off-by: Leo Li <sunpeng.li@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(). > > > > I'm not sure if this would work well. The existing policy does retries > around the ->transfer() call. Using the same hook will cause a nested > retry - once when calling remote_aux->transfer, and another when calling > real_aux->transfer. The difference is the scope of the retry. The former > replays the entire aux transaction, while the latter replays just the > failed sideband packet. I think having the retry at the packet level > makes more sense. Either way, it shouldn't happen in a nested manner. > > In general, we need a way to determine whether a message needs to be > sent via sideband. I'm not sure if there's a better way than setting a > 'is_remote' flag? oh-this is a very good point actually! I suppose we would certainly want to be able to retry on a packet level instead. Since that's the case, I think going with the current is_remote solution should be fine then. Might be worth noting the reasoning behind this with a comment > > Leo > > > > 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, > > > struc > > > t > > > drm_dp_mst_topology_mgr *mgr); > > > int drm_dp_atomic_find_vcpi_slots(struct drm_atomic_state *state, > > -- > > Cheers, > > Lyude Paul > >
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); + 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" + /** * 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); + + 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,