Skip to content

Commit 5302015

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 d4ac875 commit 5302015

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
@@ -810,7 +810,7 @@ static void cdns_mhdp_fw_cb(const struct firmware *fw, void *context)
810810
bridge_attached = mhdp->bridge_attached;
811811
spin_unlock(&mhdp->start_lock);
812812
if (bridge_attached) {
813-
if (mhdp->connector.dev)
813+
if (mhdp->connector_ptr)
814814
drm_kms_helper_hotplug_event(mhdp->bridge.dev);
815815
else
816816
drm_bridge_hpd_notify(&mhdp->bridge, cdns_mhdp_detect(mhdp));
@@ -1709,6 +1709,7 @@ static int cdns_mhdp_connector_init(struct cdns_mhdp_device *mhdp)
17091709
return ret;
17101710
}
17111711

1712+
mhdp->connector_ptr = conn;
17121713
drm_connector_helper_add(conn, &cdns_mhdp_conn_helper_funcs);
17131714

17141715
ret = drm_display_info_set_bus_formats(&conn->display_info,
@@ -1988,17 +1989,25 @@ static void cdns_mhdp_atomic_enable(struct drm_bridge *bridge,
19881989
struct drm_atomic_state *state = bridge_state->base.state;
19891990
struct cdns_mhdp_bridge_state *mhdp_state;
19901991
struct drm_crtc_state *crtc_state;
1991-
struct drm_connector *connector;
19921992
struct drm_connector_state *conn_state;
19931993
struct drm_bridge_state *new_state;
19941994
const struct drm_display_mode *mode;
19951995
u32 resp;
1996-
int ret;
1996+
int ret = 0;
19971997

19981998
dev_dbg(mhdp->dev, "bridge enable\n");
19991999

20002000
mutex_lock(&mhdp->link_mutex);
20012001

2002+
mhdp->connector_ptr = drm_atomic_get_new_connector_for_encoder(state,
2003+
bridge->encoder);
2004+
if (WARN_ON(!mhdp->connector_ptr))
2005+
goto out;
2006+
2007+
conn_state = drm_atomic_get_new_connector_state(state, mhdp->connector_ptr);
2008+
if (WARN_ON(!conn_state))
2009+
goto out;
2010+
20022011
if (mhdp->plugged && !mhdp->link_up) {
20032012
ret = cdns_mhdp_link_up(mhdp);
20042013
if (ret < 0)
@@ -2018,15 +2027,6 @@ static void cdns_mhdp_atomic_enable(struct drm_bridge *bridge,
20182027
cdns_mhdp_reg_write(mhdp, CDNS_DPTX_CAR,
20192028
resp | CDNS_VIF_CLK_EN | CDNS_VIF_CLK_RSTN);
20202029

2021-
connector = drm_atomic_get_new_connector_for_encoder(state,
2022-
bridge->encoder);
2023-
if (WARN_ON(!connector))
2024-
goto out;
2025-
2026-
conn_state = drm_atomic_get_new_connector_state(state, connector);
2027-
if (WARN_ON(!conn_state))
2028-
goto out;
2029-
20302030
if (mhdp->hdcp_supported &&
20312031
mhdp->hw_state == MHDP_HW_READY &&
20322032
conn_state->content_protection ==
@@ -2103,6 +2103,7 @@ static void cdns_mhdp_atomic_disable(struct drm_bridge *bridge,
21032103
if (mhdp->info && mhdp->info->ops && mhdp->info->ops->disable)
21042104
mhdp->info->ops->disable(mhdp);
21052105

2106+
mhdp->connector_ptr = NULL;
21062107
mutex_unlock(&mhdp->link_mutex);
21072108
}
21082109

@@ -2368,7 +2369,7 @@ static void cdns_mhdp_modeset_retry_fn(struct work_struct *work)
23682369

23692370
mhdp = container_of(work, typeof(*mhdp), modeset_retry_work);
23702371

2371-
conn = &mhdp->connector;
2372+
conn = mhdp->connector_ptr;
23722373

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

24472448
ret = cdns_mhdp_update_link_status(mhdp);
2448-
if (mhdp->connector.dev) {
2449+
if (mhdp->connector_ptr) {
24492450
if (ret < 0)
24502451
schedule_work(&mhdp->modeset_retry_work);
24512452
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)