Skip to content

Commit

Permalink
drm/dp_mst: Fix the DDC I2C device registration of an MST port
Browse files Browse the repository at this point in the history
commit d8bd15b upstream.

During the initial MST probing an MST port's I2C device will be
registered using the kdev of the DRM device as a parent. Later after MST
Connection Status Notifications this I2C device will be re-registered
with the kdev of the port's connector. This will also move
inconsistently the I2C device's sysfs entry from the DRM device's sysfs
dir to the connector's dir.

Fix the above by keeping the DRM kdev as the parent of the I2C device.

Ideally the connector's kdev would be used as a parent, similarly to
non-MST connectors, however that needs some more refactoring to ensure
the connector's kdev is already available early enough. So keep the
existing (initial) behavior for now.

Cc: <[email protected]>
Signed-off-by: Imre Deak <[email protected]>
Reviewed-by: Stanislav Lisovskiy <[email protected]>
Reviewed-by: Lyude Paul <[email protected]>
Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
Signed-off-by: Greg Kroah-Hartman <[email protected]>
  • Loading branch information
ideak authored and gregkh committed Aug 21, 2020
1 parent 1ff09cb commit 24232c8
Showing 1 changed file with 16 additions and 12 deletions.
28 changes: 16 additions & 12 deletions drivers/gpu/drm/drm_dp_mst_topology.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@ static int drm_dp_send_enum_path_resources(struct drm_dp_mst_topology_mgr *mgr,
static bool drm_dp_validate_guid(struct drm_dp_mst_topology_mgr *mgr,
u8 *guid);

static int drm_dp_mst_register_i2c_bus(struct drm_dp_aux *aux);
static void drm_dp_mst_unregister_i2c_bus(struct drm_dp_aux *aux);
static int drm_dp_mst_register_i2c_bus(struct drm_dp_mst_port *port);
static void drm_dp_mst_unregister_i2c_bus(struct drm_dp_mst_port *port);
static void drm_dp_mst_kick_tx(struct drm_dp_mst_topology_mgr *mgr);

#define DBG_PREFIX "[dp_mst]"
Expand Down Expand Up @@ -1966,7 +1966,7 @@ drm_dp_port_set_pdt(struct drm_dp_mst_port *port, u8 new_pdt,
}

/* remove i2c over sideband */
drm_dp_mst_unregister_i2c_bus(&port->aux);
drm_dp_mst_unregister_i2c_bus(port);
} else {
mutex_lock(&mgr->lock);
drm_dp_mst_topology_put_mstb(port->mstb);
Expand All @@ -1981,7 +1981,7 @@ drm_dp_port_set_pdt(struct drm_dp_mst_port *port, u8 new_pdt,
if (port->pdt != DP_PEER_DEVICE_NONE) {
if (drm_dp_mst_is_end_device(port->pdt, port->mcs)) {
/* add i2c over sideband */
ret = drm_dp_mst_register_i2c_bus(&port->aux);
ret = drm_dp_mst_register_i2c_bus(port);
} else {
lct = drm_dp_calculate_rad(port, rad);
mstb = drm_dp_add_mst_branch_device(lct, rad);
Expand Down Expand Up @@ -5346,34 +5346,38 @@ static const struct i2c_algorithm drm_dp_mst_i2c_algo = {

/**
* drm_dp_mst_register_i2c_bus() - register an I2C adapter for I2C-over-AUX
* @aux: DisplayPort AUX channel
* @port: The port to add the I2C bus on
*
* Returns 0 on success or a negative error code on failure.
*/
static int drm_dp_mst_register_i2c_bus(struct drm_dp_aux *aux)
static int drm_dp_mst_register_i2c_bus(struct drm_dp_mst_port *port)
{
struct drm_dp_aux *aux = &port->aux;
struct device *parent_dev = port->mgr->dev->dev;

aux->ddc.algo = &drm_dp_mst_i2c_algo;
aux->ddc.algo_data = aux;
aux->ddc.retries = 3;

aux->ddc.class = I2C_CLASS_DDC;
aux->ddc.owner = THIS_MODULE;
aux->ddc.dev.parent = aux->dev;
aux->ddc.dev.of_node = aux->dev->of_node;
/* FIXME: set the kdev of the port's connector as parent */
aux->ddc.dev.parent = parent_dev;
aux->ddc.dev.of_node = parent_dev->of_node;

strlcpy(aux->ddc.name, aux->name ? aux->name : dev_name(aux->dev),
strlcpy(aux->ddc.name, aux->name ? aux->name : dev_name(parent_dev),
sizeof(aux->ddc.name));

return i2c_add_adapter(&aux->ddc);
}

/**
* drm_dp_mst_unregister_i2c_bus() - unregister an I2C-over-AUX adapter
* @aux: DisplayPort AUX channel
* @port: The port to remove the I2C bus from
*/
static void drm_dp_mst_unregister_i2c_bus(struct drm_dp_aux *aux)
static void drm_dp_mst_unregister_i2c_bus(struct drm_dp_mst_port *port)
{
i2c_del_adapter(&aux->ddc);
i2c_del_adapter(&port->aux.ddc);
}

/**
Expand Down

0 comments on commit 24232c8

Please sign in to comment.