Skip to content

Commit cf2ac2c

Browse files
jayesh-tigregkh
authored andcommitted
drm/bridge: cadence: cdns-mhdp8546-core: Set the mhdp connector earlier in atomic_enable()
[ Upstream commit 43d6508 ] In case if we get errors in cdns_mhdp_link_up() or cdns_mhdp_reg_read() in atomic_enable, we will go to cdns_mhdp_modeset_retry_fn() and will hit NULL pointer while trying to access the mutex. We need the connector to be set before that. Unlike in legacy cases with flag !DRM_BRIDGE_ATTACH_NO_CONNECTOR, we do not have connector initialised in bridge_attach(), so add the mhdp->connector_ptr in device structure to handle both cases with DRM_BRIDGE_ATTACH_NO_CONNECTOR and !DRM_BRIDGE_ATTACH_NO_CONNECTOR, set it in atomic_enable() earlier to avoid possible NULL pointer dereference in recovery paths like modeset_retry_fn() with the DRM_BRIDGE_ATTACH_NO_CONNECTOR flag set. Fixes: c932ced ("drm/tidss: Update encoder/bridge chain connect model") Signed-off-by: Jayesh Choudhary <j-choudhary@ti.com> Signed-off-by: Harikrishna Shenoy <h-shenoy@ti.com> Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com> Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> Link: https://patch.msgid.link/20251209120332.3559893-2-h-shenoy@ti.com Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent 3149c4f commit cf2ac2c

3 files changed

Lines changed: 30 additions & 18 deletions

File tree

drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -740,7 +740,7 @@ static void cdns_mhdp_fw_cb(const struct firmware *fw, void *context)
740740
bridge_attached = mhdp->bridge_attached;
741741
spin_unlock(&mhdp->start_lock);
742742
if (bridge_attached) {
743-
if (mhdp->connector.dev)
743+
if (mhdp->connector_ptr)
744744
drm_kms_helper_hotplug_event(mhdp->bridge.dev);
745745
else
746746
drm_bridge_hpd_notify(&mhdp->bridge, cdns_mhdp_detect(mhdp));
@@ -1636,6 +1636,7 @@ static int cdns_mhdp_connector_init(struct cdns_mhdp_device *mhdp)
16361636
return ret;
16371637
}
16381638

1639+
mhdp->connector_ptr = conn;
16391640
drm_connector_helper_add(conn, &cdns_mhdp_conn_helper_funcs);
16401641

16411642
ret = drm_display_info_set_bus_formats(&conn->display_info,
@@ -1915,17 +1916,25 @@ static void cdns_mhdp_atomic_enable(struct drm_bridge *bridge,
19151916
struct cdns_mhdp_device *mhdp = bridge_to_mhdp(bridge);
19161917
struct cdns_mhdp_bridge_state *mhdp_state;
19171918
struct drm_crtc_state *crtc_state;
1918-
struct drm_connector *connector;
19191919
struct drm_connector_state *conn_state;
19201920
struct drm_bridge_state *new_state;
19211921
const struct drm_display_mode *mode;
19221922
u32 resp;
1923-
int ret;
1923+
int ret = 0;
19241924

19251925
dev_dbg(mhdp->dev, "bridge enable\n");
19261926

19271927
mutex_lock(&mhdp->link_mutex);
19281928

1929+
mhdp->connector_ptr = drm_atomic_get_new_connector_for_encoder(state,
1930+
bridge->encoder);
1931+
if (WARN_ON(!mhdp->connector_ptr))
1932+
goto out;
1933+
1934+
conn_state = drm_atomic_get_new_connector_state(state, mhdp->connector_ptr);
1935+
if (WARN_ON(!conn_state))
1936+
goto out;
1937+
19291938
if (mhdp->plugged && !mhdp->link_up) {
19301939
ret = cdns_mhdp_link_up(mhdp);
19311940
if (ret < 0)
@@ -1945,15 +1954,6 @@ static void cdns_mhdp_atomic_enable(struct drm_bridge *bridge,
19451954
cdns_mhdp_reg_write(mhdp, CDNS_DPTX_CAR,
19461955
resp | CDNS_VIF_CLK_EN | CDNS_VIF_CLK_RSTN);
19471956

1948-
connector = drm_atomic_get_new_connector_for_encoder(state,
1949-
bridge->encoder);
1950-
if (WARN_ON(!connector))
1951-
goto out;
1952-
1953-
conn_state = drm_atomic_get_new_connector_state(state, connector);
1954-
if (WARN_ON(!conn_state))
1955-
goto out;
1956-
19571957
if (mhdp->hdcp_supported &&
19581958
mhdp->hw_state == MHDP_HW_READY &&
19591959
conn_state->content_protection ==
@@ -2030,6 +2030,7 @@ static void cdns_mhdp_atomic_disable(struct drm_bridge *bridge,
20302030
if (mhdp->info && mhdp->info->ops && mhdp->info->ops->disable)
20312031
mhdp->info->ops->disable(mhdp);
20322032

2033+
mhdp->connector_ptr = NULL;
20332034
mutex_unlock(&mhdp->link_mutex);
20342035
}
20352036

@@ -2296,7 +2297,7 @@ static void cdns_mhdp_modeset_retry_fn(struct work_struct *work)
22962297

22972298
mhdp = container_of(work, typeof(*mhdp), modeset_retry_work);
22982299

2299-
conn = &mhdp->connector;
2300+
conn = mhdp->connector_ptr;
23002301

23012302
/* Grab the locks before changing connector property */
23022303
mutex_lock(&conn->dev->mode_config.mutex);
@@ -2373,7 +2374,7 @@ static void cdns_mhdp_hpd_work(struct work_struct *work)
23732374
int ret;
23742375

23752376
ret = cdns_mhdp_update_link_status(mhdp);
2376-
if (mhdp->connector.dev) {
2377+
if (mhdp->connector_ptr) {
23772378
if (ret < 0)
23782379
schedule_work(&mhdp->modeset_retry_work);
23792380
else

drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,7 @@ struct cdns_mhdp_device {
376376
struct mutex link_mutex;
377377

378378
struct drm_connector connector;
379+
struct drm_connector *connector_ptr;
379380
struct drm_bridge bridge;
380381

381382
struct cdns_mhdp_link link;

drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-hdcp.c

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,7 @@ static int _cdns_mhdp_hdcp_disable(struct cdns_mhdp_device *mhdp)
394394
int ret;
395395

396396
dev_dbg(mhdp->dev, "[%s:%d] HDCP is being disabled...\n",
397-
mhdp->connector.name, mhdp->connector.base.id);
397+
mhdp->connector_ptr->name, mhdp->connector_ptr->base.id);
398398

399399
ret = cdns_mhdp_hdcp_set_config(mhdp, 0, false);
400400

@@ -436,6 +436,10 @@ static int cdns_mhdp_hdcp_check_link(struct cdns_mhdp_device *mhdp)
436436
int ret = 0;
437437

438438
mutex_lock(&mhdp->hdcp.mutex);
439+
440+
if (!mhdp->connector_ptr)
441+
goto out;
442+
439443
if (mhdp->hdcp.value == DRM_MODE_CONTENT_PROTECTION_UNDESIRED)
440444
goto out;
441445

@@ -445,7 +449,7 @@ static int cdns_mhdp_hdcp_check_link(struct cdns_mhdp_device *mhdp)
445449

446450
dev_err(mhdp->dev,
447451
"[%s:%d] HDCP link failed, retrying authentication\n",
448-
mhdp->connector.name, mhdp->connector.base.id);
452+
mhdp->connector_ptr->name, mhdp->connector_ptr->base.id);
449453

450454
ret = _cdns_mhdp_hdcp_disable(mhdp);
451455
if (ret) {
@@ -487,13 +491,19 @@ static void cdns_mhdp_hdcp_prop_work(struct work_struct *work)
487491
struct cdns_mhdp_device *mhdp = container_of(hdcp,
488492
struct cdns_mhdp_device,
489493
hdcp);
490-
struct drm_device *dev = mhdp->connector.dev;
494+
struct drm_device *dev = NULL;
491495
struct drm_connector_state *state;
492496

497+
if (mhdp->connector_ptr)
498+
dev = mhdp->connector_ptr->dev;
499+
500+
if (!dev)
501+
return;
502+
493503
drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
494504
mutex_lock(&mhdp->hdcp.mutex);
495505
if (mhdp->hdcp.value != DRM_MODE_CONTENT_PROTECTION_UNDESIRED) {
496-
state = mhdp->connector.state;
506+
state = mhdp->connector_ptr->state;
497507
state->content_protection = mhdp->hdcp.value;
498508
}
499509
mutex_unlock(&mhdp->hdcp.mutex);

0 commit comments

Comments
 (0)