From: Wang Jiang <[email protected]> The audio detection process in the Radeon driver is as follows: radeon_dvi_detect/radeon_dp_detect -> radeon_audio_detect -> radeon_audio_enable -> radeon_audio_component_notify -> radeon_audio_component_get_eld When HDMI is unplugged, radeon_dvi_detect is triggered. At this point, radeon_audio_detect is triggered before radeon_dvi_detect has finished (which also means the new state of the connector has not been reported). In this scenario, radeon_audio_detect can detect that the connector is disconnected (because the parameter is passed down), but it is very likely that the audio callback function radeon_audio_component_get_eld cannot detect the disconnection of the connector. As a result, when the audio component (radeon_audio_component_get_eld) performs detection, the connector's state is not shown as disconnected, and connector->eld is not zero, causing the audio component to think the audio driver is still working. I have added a new member (enable_mask) to the audio structure to record the audio enable status. Only when radeon_audio_component_get_eld detects that enable_mask is not zero will it continue to work.
Signed-off-by: Wang Jiang <[email protected]> --- drivers/gpu/drm/radeon/radeon.h | 1 + drivers/gpu/drm/radeon/radeon_audio.c | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 63c47585afbc..2d0a411e3ed6 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -1745,6 +1745,7 @@ struct r600_audio_pin { u32 offset; bool connected; u32 id; + u8 enable_mask; }; struct r600_audio { diff --git a/drivers/gpu/drm/radeon/radeon_audio.c b/drivers/gpu/drm/radeon/radeon_audio.c index 8d64ba18572e..a0717895cc8a 100644 --- a/drivers/gpu/drm/radeon/radeon_audio.c +++ b/drivers/gpu/drm/radeon/radeon_audio.c @@ -212,6 +212,7 @@ static void radeon_audio_enable(struct radeon_device *rdev, if (rdev->audio.funcs->enable) rdev->audio.funcs->enable(rdev, pin, enable_mask); + rdev->audio.pin[pin->id].enable_mask = enable_mask; radeon_audio_component_notify(rdev, pin->id); } @@ -274,6 +275,7 @@ int radeon_audio_init(struct radeon_device *rdev) rdev->audio.pin[i].connected = false; rdev->audio.pin[i].offset = pin_offsets[i]; rdev->audio.pin[i].id = i; + rdev->audio.pin[i].enable_mask = 0; } radeon_audio_interface_init(rdev); @@ -760,6 +762,9 @@ static int radeon_audio_component_get_eld(struct device *kdev, int port, if (!rdev->audio.enabled || !rdev->mode_info.mode_config_initialized) return 0; + if (rdev->audio.pin[port].enable_mask == 0) + return 0; + list_for_each_entry(connector, &dev->mode_config.connector_list, head) { const struct drm_connector_helper_funcs *connector_funcs = connector->helper_private; -- 2.25.1
