From nobody Sat Jul 25 01:34:41 2026 Received: from pidgin.makrotopia.org (pidgin.makrotopia.org [185.142.180.65]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A9BB13D413C for ; Tue, 21 Jul 2026 02:26:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.142.180.65 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784600794; cv=none; b=VcKMlbugV7KmNRJOLIeW8IAK6YwQ1Ana16W6r29SPbw+9fyyR3eo4iXM4u7q3DxhcVV0xe30NzbMjR/ScaJvrcedu4iNBecsf6mgTM2Bznz5407+w/v3qNvIlqzoVb7xQmfAvPprcu3em8Q7srXa4ojb0/yy5leId/eTU+fqWHQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784600794; c=relaxed/simple; bh=JGZdKSKVtozoJfKlkkY5TYFQV40F7kFcy47RHqCy4YE=; h=Date:From:To:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=IMVruPiO+5o8Fm11aryiJ+y8CBo0Hs+XtvmigTqU8+fskB3hYS/mtLJGz5Jly1jHKefHLdM68EOWt1u0chja9GmzJHJC92vZ3d12WLjmVF9MKwDt1tU5gRi6znbj52RMA3Pz9L5SjmJ8AJea/2CCRQmts0MV9asHah8JrKAXSXo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=makrotopia.org; spf=pass smtp.mailfrom=makrotopia.org; arc=none smtp.client-ip=185.142.180.65 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=makrotopia.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=makrotopia.org Received: from local by pidgin.makrotopia.org with esmtpsa (TLS1.3:TLS_AES_256_GCM_SHA384:256) (Exim 4.99) (envelope-from ) id 1wm0BX-000000000D4-2tJm; Tue, 21 Jul 2026 02:26:19 +0000 Date: Tue, 21 Jul 2026 03:26:16 +0100 From: Daniel Golle To: Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Luca Ceresoli , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Matthias Brugger , AngeloGioacchino Del Regno , Allen Chen , Hermes Wu , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org Subject: [PATCH v3 1/4] drm/bridge: it6505: cancel outstanding work before teardown in remove() Message-ID: <91b40322b07b967fcf286b3e4bd11e5f821bff1c.1784600387.git.daniel@makrotopia.org> References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" it6505_i2c_remove() tears down the bridge and frees its state without cancelling any of the driver's background work. struct it6505 is allocated with devm_drm_bridge_alloc(), so devres frees it as soon as remove() returns; link_works, hdcp_wait_ksv_list, hdcp_work and extcon_wq can all still be pending or running at that point and will then dereference freed memory. link_works and extcon_wq are flushed in it6505_bridge_detach(), but that only runs if DRM core calls the bridge's .detach() before the i2c client is unbound -- not guaranteed if the i2c driver is unbound independently of the DRM device that consumes it. hdcp_wait_ksv_list and hdcp_work are never cancelled anywhere. Cancel all four synchronously in remove() itself so teardown is safe regardless of ordering. cancel_work_sync() on extcon_wq is safe even when it was never INIT_WORK()'d, since it6505 is zero-allocated and a zeroed work_struct is reported as not pending. Fixes: b5c84a9edcd4 ("drm/bridge: add it6505 driver") Signed-off-by: Daniel Golle --- v3: new patch, split out to fix a pre-existing use-after-free flagged by automated review of v2's audio series; needed before that series adds another cancel_delayed_work_sync() call next to the ones this commit is adding. drivers/gpu/drm/bridge/ite-it6505.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/bridge/ite-it6505.c b/drivers/gpu/drm/bridge/i= te-it6505.c index 8ecb43611dba..2f349aefb705 100644 --- a/drivers/gpu/drm/bridge/ite-it6505.c +++ b/drivers/gpu/drm/bridge/ite-it6505.c @@ -3644,6 +3644,10 @@ static void it6505_i2c_remove(struct i2c_client *cli= ent) { struct it6505 *it6505 =3D i2c_get_clientdata(client); =20 + cancel_work_sync(&it6505->link_works); + cancel_work_sync(&it6505->hdcp_wait_ksv_list); + cancel_delayed_work_sync(&it6505->hdcp_work); + cancel_work_sync(&it6505->extcon_wq); drm_bridge_remove(&it6505->bridge); drm_dp_aux_unregister(&it6505->aux); it6505_debugfs_remove(it6505); --=20 2.55.0 From nobody Sat Jul 25 01:34:41 2026 Received: from pidgin.makrotopia.org (pidgin.makrotopia.org [185.142.180.65]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DBF87400961 for ; Tue, 21 Jul 2026 02:26:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.142.180.65 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784600815; cv=none; b=hH4gtzwcAPnwjuwO0kwvt/FpD7/ro2WpZRXIuGIUy1pixA5VClLwYy0YNOrsbiVY+aeJJVdXGrv2K2kHpNJBvnKX+FVjaShQEwfOeBAfJdwS7GjUb7fD8gFgajKjt4yzJdnE5t8CqLf9oy1xK0r9ZGulqeG9j3f2C+/WBtyL5/s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784600815; c=relaxed/simple; bh=WPUiPV46ZDZLWjnemOSyVRGyK98S1i8I98tkF3k0jYA=; h=Date:From:To:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=ro0rDlCzRO9lMrrzeLB3huG2uvH4NQvqR5yzY6DDXzKfPJyl84MvD64Rpfl2+jIZ9hu6bKpUBx2t4covhWFH9IZ5OgiAsTfffN0dDq+EQQuSxRB0NUhmpvg4OxOGZtxuTRwaeLCCcmjQcrpXXGpD7IZNKzabJvLPNL6rkXc4cxs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=makrotopia.org; spf=pass smtp.mailfrom=makrotopia.org; arc=none smtp.client-ip=185.142.180.65 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=makrotopia.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=makrotopia.org Received: from local by pidgin.makrotopia.org with esmtpsa (TLS1.3:TLS_AES_256_GCM_SHA384:256) (Exim 4.99) (envelope-from ) id 1wm0Bz-000000000F1-2BJV; Tue, 21 Jul 2026 02:26:47 +0000 Date: Tue, 21 Jul 2026 03:26:44 +0100 From: Daniel Golle To: Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Luca Ceresoli , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Matthias Brugger , AngeloGioacchino Del Regno , Allen Chen , Hermes Wu , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org Subject: [PATCH v3 2/4] drm/bridge: it6505: guard against zero channel count in audio infoframe Message-ID: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" it6505->audio.channel_count is zero from allocation until either DP link training has run once (it6505_variable_config()) or a valid hw_params call has cached a channel count. it6505_enable_audio() can be reached before either of those has happened, e.g. from the audio-FIFO-error IRQ, which is unmasked unconditionally at poweron. it6505_enable_audio_infoframe() then indexes the 8-entry audio_info_ca[] table with channel_count - 1, an out-of-bounds stack read when channel_count is still 0. Bail out of it6505_enable_audio_infoframe() when channel_count is not yet known instead of indexing with it. While here, fix the debug print in it6505_audio_setup_hw_params(): on the invalid-channel-count path it logged the previously cached channel_count instead of the actually-rejected params->cea.channels. Fixes: b5c84a9edcd4 ("drm/bridge: add it6505 driver") Signed-off-by: Daniel Golle Reviewed-by: Chen-Yu Tsai --- v3: new patch drivers/gpu/drm/bridge/ite-it6505.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/ite-it6505.c b/drivers/gpu/drm/bridge/i= te-it6505.c index 2f349aefb705..f2ed76a05f6b 100644 --- a/drivers/gpu/drm/bridge/ite-it6505.c +++ b/drivers/gpu/drm/bridge/ite-it6505.c @@ -1575,6 +1575,9 @@ static void it6505_enable_audio_infoframe(struct it65= 05 *it6505) struct device *dev =3D it6505->dev; u8 audio_info_ca[] =3D { 0x00, 0x00, 0x01, 0x03, 0x07, 0x0B, 0x0F, 0x1F }; =20 + if (!it6505->audio.channel_count) + return; + DRM_DEV_DEBUG_DRIVER(dev, "infoframe channel_allocation:0x%02x", audio_info_ca[it6505->audio.channel_count - 1]); =20 @@ -2990,7 +2993,7 @@ static int __maybe_unused it6505_audio_setup_hw_param= s(struct it6505 *it6505, =20 if (params->cea.channels <=3D 1 || params->cea.channels > 8) { DRM_DEV_DEBUG_DRIVER(dev, "channel number: %d not support", - it6505->audio.channel_count); + params->cea.channels); return -EINVAL; } =20 --=20 2.55.0 From nobody Sat Jul 25 01:34:41 2026 Received: from pidgin.makrotopia.org (pidgin.makrotopia.org [185.142.180.65]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 188153D413C for ; Tue, 21 Jul 2026 02:27:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.142.180.65 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784600873; cv=none; b=pWdOux+u0Cot8aqoN5qUJpsm6c2wfrF+Qw5mrSn8I2Cbbf7ZCuh8Gmri3B+HPG/M1/QSX930kgWejjYOXbGNU79yYp288N3cqV0SgL6OoBZj9JimFMsGixfN0PXbcNJ4I0jLFOsmt9JSdpOBmElDK7l2w15K65lB5RcK0A45wdE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784600873; c=relaxed/simple; bh=N07FSALEZZxGv1mz6j4Y/WfsrXKoxOVWGtvVsBL8bRA=; h=Date:From:To:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=mllvbGP+1NYxZT+FeMvMLMlFmfxXIhkj3tMj8B4khNGaQEhP65tk0A0dJFWQZ6X6QS1LDQrH9X6P5YHrMW+/jdn//NF81WBg7MH2PfBy1rf2cEk7QsXCz1R/2OTDIf6P4xj5W6SX2N37sTIAN3nB0eKT26HhTYXHIu7lKkOxxPQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=makrotopia.org; spf=pass smtp.mailfrom=makrotopia.org; arc=none smtp.client-ip=185.142.180.65 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=makrotopia.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=makrotopia.org Received: from local by pidgin.makrotopia.org with esmtpsa (TLS1.3:TLS_AES_256_GCM_SHA384:256) (Exim 4.99) (envelope-from ) id 1wm0Cv-000000000Gf-1LLR; Tue, 21 Jul 2026 02:27:45 +0000 Date: Tue, 21 Jul 2026 03:27:42 +0100 From: Daniel Golle To: Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Luca Ceresoli , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Matthias Brugger , AngeloGioacchino Del Regno , Allen Chen , Hermes Wu , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org Subject: [PATCH v3 3/4] drm/bridge: it6505: Add audio support Message-ID: <6e27cdb00758a7a55a12293be21e3a3bafe34296.1784600387.git.daniel@makrotopia.org> References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Jiaxin Yu Add audio support for it6505 by bridging to the hdmi-codec, registering an "hdmi-audio-codec" platform device from probe. The it6505's audio setup/shutdown helpers were merged earlier as unused code; wire them up via hdmi_codec_ops so the DAI actually appears, which unblocks the mt8186-mt6366 sound card that references it6505 as the I2S3 codec. Some DP-to-HDMI dongles get into a bad state if InfoFrame is sent without audio data, so it6505's audio is only enabled once the stream is unmuted. it6505_enable_audio()/it6505_disable_audio() can be called from several contexts: DP link training (link_works), the HPD-low path, the audio-FIFO-error IRQ, and now also the delayed audio-enable work and the .mute_stream/.audio_shutdown hdmi_codec_ops added here. None of these are mutually exclusive, so serialize the actual register sequences with a new audio_lock mutex. Also track the mute state requested through .mute_stream/ .audio_shutdown in it6505->audio.mute, and have the audio-FIFO-error IRQ handler skip re-enabling audio while muted: without this, an audio-FIFO error following an ALSA-requested mute would silently re-enable audio and could send the very InfoFrame-without-data sequence the delayed-enable logic above is meant to avoid. Link: https://lore.kernel.org/all/20230730180803.22570-4-jiaxin.yu@mediatek= .com/ Signed-off-by: Jiaxin Yu Signed-off-by: Daniel Golle --- v3: * serialise it6505_enable_audio()/it6505_disable_audio() with a new audio_lock mutex, resolving the "input welcome on whether a lock is warranted" note below * track requested mute state in it6505->audio.mute and have the audio-FIFO-error IRQ handler skip re-enabling audio while muted, both addressing automated review of v2 v2: * store the hdmi-codec platform_device and unregister it on i2c remove, fixing a resource leak and use-after-free on unbind * initialise the delayed audio work before registering the codec device instead of after * synchronously cancel the delayed audio work on audio shutdown and on driver remove (cancel_delayed_work_sync) * rework the mute path to cancel pending work synchronously and disable audio immediately when muting, removing a race with the delayed enable work djg: respin of Jiaxin Yu's v3, rebased onto current mainline. Changes from v3: hdmi_codec_ops lost .trigger, so drive enable/disable from .mute_stream; drop the now-redundant __maybe_unused; use it6505->dev instead of &client->dev, addressing AngeloGioacchino Del Regno's v3 review. Also fix issues in v3: initialise delayed_audio before registering the codec device; keep and unregister the platform_device and cancel delayed_audio on remove to avoid a leak and a use-after-free; cancel the delayed work on audio shutdown; and actually disable audio (not just cancel the pending enable) when the stream is muted. --- drivers/gpu/drm/bridge/ite-it6505.c | 126 ++++++++++++++++++++++++---- 1 file changed, 108 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/bridge/ite-it6505.c b/drivers/gpu/drm/bridge/i= te-it6505.c index f2ed76a05f6b..37036ef5403f 100644 --- a/drivers/gpu/drm/bridge/ite-it6505.c +++ b/drivers/gpu/drm/bridge/ite-it6505.c @@ -407,6 +407,7 @@ struct it6505_audio_data { u8 i2s_data_delay; u8 i2s_ws_channel; u8 i2s_data_sequence; + bool mute; }; =20 struct it6505_audio_sample_rate_map { @@ -439,6 +440,7 @@ struct it6505 { struct mutex extcon_lock; struct mutex mode_lock; /* used to bridge_detect */ struct mutex aux_lock; /* used to aux data transfers */ + struct mutex audio_lock; /* serializes audio enable/disable */ struct regmap *regmap; struct drm_display_mode source_output_mode; struct drm_display_mode video_info; @@ -476,6 +478,7 @@ struct it6505 { bool enable_enhanced_frame; hdmi_codec_plugged_cb plugged_cb; struct device *codec_dev; + struct platform_device *audio_pdev; struct delayed_work delayed_audio; struct it6505_audio_data audio; struct dentry *debugfs; @@ -1594,7 +1597,7 @@ static void it6505_enable_audio_infoframe(struct it65= 05 *it6505) EN_AUD_CTRL_PKT); } =20 -static void it6505_disable_audio(struct it6505 *it6505) +static void __it6505_disable_audio(struct it6505 *it6505) { it6505_set_bits(it6505, REG_DATA_MUTE_CTRL, EN_AUD_MUTE, EN_AUD_MUTE); it6505_set_bits(it6505, REG_AUDIO_SRC_CTRL, M_AUDIO_I2S_EN, 0x00); @@ -1602,13 +1605,23 @@ static void it6505_disable_audio(struct it6505 *it6= 505) it6505_set_bits(it6505, REG_RESET_CTRL, AUDIO_RESET, AUDIO_RESET); } =20 +static void it6505_disable_audio(struct it6505 *it6505) +{ + mutex_lock(&it6505->audio_lock); + __it6505_disable_audio(it6505); + mutex_unlock(&it6505->audio_lock); +} + static void it6505_enable_audio(struct it6505 *it6505) { struct device *dev =3D it6505->dev; int regbe; =20 DRM_DEV_DEBUG_DRIVER(dev, "start"); - it6505_disable_audio(it6505); + + mutex_lock(&it6505->audio_lock); + + __it6505_disable_audio(it6505); =20 it6505_setup_audio_channel_status(it6505); it6505_setup_audio_format(it6505); @@ -1627,6 +1640,8 @@ static void it6505_enable_audio(struct it6505 *it6505) DRM_DEV_DEBUG_DRIVER(dev, "regbe:0x%02x audio input fs: %d.%d kHz", regbe, 6750 / regbe, (6750 % regbe) * 10 / regbe); it6505_set_bits(it6505, REG_DATA_MUTE_CTRL, EN_AUD_MUTE, 0x00); + + mutex_unlock(&it6505->audio_lock); } =20 static bool it6505_use_step_train_check(struct it6505 *it6505) @@ -2323,19 +2338,12 @@ static void it6505_stop_link_train(struct it6505 *i= t6505) =20 static void it6505_link_train_ok(struct it6505 *it6505) { - struct device *dev =3D it6505->dev; - it6505->link_state =3D LINK_OK; /* disalbe mute enable avi info frame */ it6505_set_bits(it6505, REG_DATA_MUTE_CTRL, EN_VID_MUTE, 0x00); it6505_set_bits(it6505, REG_INFOFRAME_CTRL, EN_VID_CTRL_PKT, EN_VID_CTRL_PKT); =20 - if (it6505_audio_input(it6505)) { - DRM_DEV_DEBUG_DRIVER(dev, "Enable audio!"); - it6505_enable_audio(it6505); - } - if (it6505->hdcp_desired) it6505_start_hdcp(it6505); } @@ -2627,6 +2635,9 @@ static void it6505_irq_audio_fifo_error(struct it6505= *it6505) =20 DRM_DEV_DEBUG_DRIVER(dev, "audio fifo error Interrupt"); =20 + if (it6505->audio.mute) + return; + if (it6505_audio_input(it6505)) it6505_enable_audio(it6505); } @@ -2963,7 +2974,7 @@ static void it6505_remove_notifier_module(struct it65= 05 *it6505) } } =20 -static void __maybe_unused it6505_delayed_audio(struct work_struct *work) +static void it6505_delayed_audio(struct work_struct *work) { struct it6505 *it6505 =3D container_of(work, struct it6505, delayed_audio.work); @@ -2977,9 +2988,9 @@ static void __maybe_unused it6505_delayed_audio(struc= t work_struct *work) it6505_enable_audio(it6505); } =20 -static int __maybe_unused it6505_audio_setup_hw_params(struct it6505 *it65= 05, - struct hdmi_codec_params - *params) +static int it6505_audio_setup_hw_params(struct it6505 *it6505, + struct hdmi_codec_params + *params) { struct device *dev =3D it6505->dev; int i =3D 0; @@ -3034,18 +3045,55 @@ static int __maybe_unused it6505_audio_setup_hw_par= ams(struct it6505 *it6505, return 0; } =20 -static void __maybe_unused it6505_audio_shutdown(struct device *dev, void = *data) +static void it6505_audio_shutdown(struct device *dev, void *data) { struct it6505 *it6505 =3D dev_get_drvdata(dev); =20 + it6505->audio.mute =3D true; + cancel_delayed_work_sync(&it6505->delayed_audio); if (it6505->powered) it6505_disable_audio(it6505); } =20 -static int __maybe_unused it6505_audio_hook_plugged_cb(struct device *dev, - void *data, - hdmi_codec_plugged_cb fn, - struct device *codec_dev) +static int it6505_audio_hw_params(struct device *dev, void *data, + struct hdmi_codec_daifmt *daifmt, + struct hdmi_codec_params *params) +{ + struct it6505 *it6505 =3D dev_get_drvdata(dev); + + return it6505_audio_setup_hw_params(it6505, params); +} + +static int it6505_audio_mute(struct device *dev, void *data, + bool enable, int direction) +{ + struct it6505 *it6505 =3D dev_get_drvdata(dev); + + DRM_DEV_DEBUG_DRIVER(dev, "mute: %d", enable); + + it6505->audio.mute =3D enable; + + /* + * Some DP-to-HDMI dongles get into a bad state if the InfoFrame is + * sent without audio data, so only enable it6505's audio once the + * stream is unmuted (i.e. actually playing). + */ + if (enable) { + cancel_delayed_work_sync(&it6505->delayed_audio); + if (it6505->powered) + it6505_disable_audio(it6505); + } else { + queue_delayed_work(system_wq, &it6505->delayed_audio, + msecs_to_jiffies(180)); + } + + return 0; +} + +static int it6505_audio_hook_plugged_cb(struct device *dev, + void *data, + hdmi_codec_plugged_cb fn, + struct device *codec_dev) { struct it6505 *it6505 =3D data; =20 @@ -3056,6 +3104,39 @@ static int __maybe_unused it6505_audio_hook_plugged_= cb(struct device *dev, return 0; } =20 +static const struct hdmi_codec_ops it6505_audio_codec_ops =3D { + .hw_params =3D it6505_audio_hw_params, + .mute_stream =3D it6505_audio_mute, + .audio_shutdown =3D it6505_audio_shutdown, + .hook_plugged_cb =3D it6505_audio_hook_plugged_cb, +}; + +static int it6505_register_audio_driver(struct device *dev) +{ + struct it6505 *it6505 =3D dev_get_drvdata(dev); + struct hdmi_codec_pdata codec_data =3D { + .ops =3D &it6505_audio_codec_ops, + .max_i2s_channels =3D 8, + .i2s =3D 1, + .no_capture_mute =3D 1, + .data =3D it6505, + }; + struct platform_device *pdev; + + INIT_DELAYED_WORK(&it6505->delayed_audio, it6505_delayed_audio); + + pdev =3D platform_device_register_data(dev, HDMI_CODEC_DRV_NAME, + PLATFORM_DEVID_AUTO, &codec_data, + sizeof(codec_data)); + if (IS_ERR(pdev)) + return PTR_ERR(pdev); + + it6505->audio_pdev =3D pdev; + DRM_DEV_DEBUG_DRIVER(dev, "bound to %s", HDMI_CODEC_DRV_NAME); + + return 0; +} + static inline struct it6505 *bridge_to_it6505(struct drm_bridge *bridge) { return container_of(bridge, struct it6505, bridge); @@ -3565,6 +3646,7 @@ static int it6505_i2c_probe(struct i2c_client *client) mutex_init(&it6505->extcon_lock); mutex_init(&it6505->mode_lock); mutex_init(&it6505->aux_lock); + mutex_init(&it6505->audio_lock); =20 it6505->bridge.of_node =3D client->dev.of_node; it6505->connector_status =3D connector_status_disconnected; @@ -3615,6 +3697,12 @@ static int it6505_i2c_probe(struct i2c_client *clien= t) return err; } =20 + err =3D it6505_register_audio_driver(dev); + if (err < 0) { + dev_err(dev, "Failed to register audio driver: %d", err); + return err; + } + INIT_WORK(&it6505->link_works, it6505_link_training_work); INIT_WORK(&it6505->hdcp_wait_ksv_list, it6505_hdcp_wait_ksv_list); INIT_DELAYED_WORK(&it6505->hdcp_work, it6505_hdcp_work); @@ -3647,6 +3735,8 @@ static void it6505_i2c_remove(struct i2c_client *clie= nt) { struct it6505 *it6505 =3D i2c_get_clientdata(client); =20 + platform_device_unregister(it6505->audio_pdev); + cancel_delayed_work_sync(&it6505->delayed_audio); cancel_work_sync(&it6505->link_works); cancel_work_sync(&it6505->hdcp_wait_ksv_list); cancel_delayed_work_sync(&it6505->hdcp_work); --=20 2.55.0 From nobody Sat Jul 25 01:34:41 2026 Received: from pidgin.makrotopia.org (pidgin.makrotopia.org [185.142.180.65]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8BD82400963 for ; Tue, 21 Jul 2026 02:28:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.142.180.65 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784600891; cv=none; b=LIuUpFConijkETSVwWFs8c4sN/WZ1Rnbai3/eYdh8cufc621ojWt/kE5b0BnIOaUCfOnXSmXlrTw9GyL+zmTzOprotp0FNHEZGTvjkoqX3ray4TzTqyVPl2oGJe8lFtHZujlidmCG2TWYmVPbKtCuw2qFl6//A8rPB3IiHH7zy0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784600891; c=relaxed/simple; bh=6l88fBS2Nj7pUcUlE5lMnALqt8p7PzAXsDF1wCdksVE=; h=Date:From:To:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=fQ9kRFRwetB7yvp98TQ9rZKYNPRiMGYjYPK71j3zMqhYP7D2VdtV0qlpIODUWcothrTHj70acKJnnkm+F8ldMGg3bALiRpUQIqKZGkElqIgxbjidsRU6+t/Nqgbj6+b/rA0P1GRfi9GGs+h5UF7537SY++s4QJwd7CiL3H2brZ0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=makrotopia.org; spf=pass smtp.mailfrom=makrotopia.org; arc=none smtp.client-ip=185.142.180.65 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=makrotopia.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=makrotopia.org Received: from local by pidgin.makrotopia.org with esmtpsa (TLS1.3:TLS_AES_256_GCM_SHA384:256) (Exim 4.99) (envelope-from ) id 1wm0DD-000000000Hf-2RzL; Tue, 21 Jul 2026 02:28:03 +0000 Date: Tue, 21 Jul 2026 03:28:00 +0100 From: Daniel Golle To: Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Luca Ceresoli , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Matthias Brugger , AngeloGioacchino Del Regno , Allen Chen , Hermes Wu , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org Subject: [PATCH v3 4/4] drm/bridge: it6505: Don't reject audio hw_params without an encoder Message-ID: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" it6505_audio_setup_hw_params() returns -ENODEV when the bridge is not attached to a DRM encoder. Now that it6505 registers an hdmi-audio-codec, this callback runs whenever a stream is configured on the I2S DAI it is wired to, including when that DAI is shared with another codec. On mt8186-corsola the speaker amplifier (rt1019) and it6505 share I2S3, so when the it6505 DP output has no display attached (bridge.encoder is NULL) the -ENODEV propagates up through dpcm_be_dai_hw_params() and tears down the whole backend, breaking speaker playback. The check is harmful in its own right: the rest of the function only caches the stream parameters (channel count, rate, word length) in software, none of which needs an encoder. Returning early leaves it6505->audio.channel_count at 0, which would then index audio_info_ca[-1] in it6505_enable_audio_infoframe() should a display be hotplugged while a stream is running, and makes such a hotplug play with stale parameters. Drop the encoder check so the parameters are always cached; the actual audio output is already gated by it6505->powered. Fixes: b5c84a9edcd4 ("drm/bridge: add it6505 driver") Signed-off-by: Daniel Golle --- v3: no changes v2: * drop the encoder check entirely instead of returning 0 early, so the stream parameters are always cached even while no display is attached; rewrite the commit message to explain why the check is harmful drivers/gpu/drm/bridge/ite-it6505.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/gpu/drm/bridge/ite-it6505.c b/drivers/gpu/drm/bridge/i= te-it6505.c index 37036ef5403f..435601b6929e 100644 --- a/drivers/gpu/drm/bridge/ite-it6505.c +++ b/drivers/gpu/drm/bridge/ite-it6505.c @@ -2999,9 +2999,6 @@ static int it6505_audio_setup_hw_params(struct it6505= *it6505, params->sample_rate, params->sample_width, params->cea.channels); =20 - if (!it6505->bridge.encoder) - return -ENODEV; - if (params->cea.channels <=3D 1 || params->cea.channels > 8) { DRM_DEV_DEBUG_DRIVER(dev, "channel number: %d not support", params->cea.channels); --=20 2.55.0