From 67a617d8417498785b6f5b6a339e2ee3acedd6c1 Mon Sep 17 00:00:00 2001 From: Erik Bourget Date: Sat, 31 Oct 2026 20:53:53 -0400 Subject: [PATCH] ASoC: apple: aop_audio: Accept devices still attached after a reload The AOP firmware keeps a device attachment for as long as it runs, and the driver has no way to drop one at removal. When the module is loaded again, the probe's attach calls for the microphone devices get kIOReturnBusy back and the probe fails. The machine then has no audio until it reboots: with the T6040 flow the speaker and jack streams are registered by the same probe and are lost as well. The speaker and jack services already treat that return as attached. Do the same in the probe, and share the constant with aop_spkr. The probe's property writes that follow are accepted by the still attached devices. Signed-off-by: Erik Bourget --- sound/soc/apple/aop_audio.rs | 7 +++++++ sound/soc/apple/aop_spkr.rs | 5 ++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/sound/soc/apple/aop_audio.rs b/sound/soc/apple/aop_audio.rs index 4ca40688034bb..41d159881a756 100644 --- a/sound/soc/apple/aop_audio.rs +++ b/sound/soc/apple/aop_audio.rs @@ -81,6 +81,8 @@ impl fmt::Debug for U32 { const EPIC_SUBTYPE_WRAPPED_CALL: u16 = 0x20; const CALLTYPE_AUDIO_ATTACH_DEVICE: u32 = 0xc3000002; +/// kIOReturnBusy: the firmware keeps an attachment for its lifetime, so a reload sees this. +const AUDIO_RET_BUSY: u32 = 0xe00002d5; const CALLTYPE_AUDIO_SET_PROP: u32 = 0xc3000005; const DECIM_NUM_COEFFS: usize = 120; const DECIM_NUM_COEFFS_HF: usize = 1023; @@ -697,9 +699,14 @@ impl SndSocAopData { } Ok(()) } + /// A device the firmware still holds from before a module reload counts as attached. fn audio_attach_device(&self, dev_id: u32) -> Result<()> { let msg = AudioAttachDevice::new(dev_id); let ret = self.epic_wrapped_call(&msg)?; + if ret == AUDIO_RET_BUSY { + dev_dbg!(self.dev, "device {:#x} still attached\n", dev_id); + return Ok(()); + } if ret != 0 { dev_err!( self.dev, diff --git a/sound/soc/apple/aop_spkr.rs b/sound/soc/apple/aop_spkr.rs index b5b2f5a7f6acf..06ee4f93eca01 100644 --- a/sound/soc/apple/aop_spkr.rs +++ b/sound/soc/apple/aop_spkr.rs @@ -76,7 +76,8 @@ use kernel::{ }; use super::{ - AudioAttachDevice, AudioSetDeviceProp, PowerSetting, SndSocAopData, EPIC_SUBTYPE_WRAPPED_CALL, + AudioAttachDevice, AudioSetDeviceProp, PowerSetting, SndSocAopData, AUDIO_RET_BUSY, + EPIC_SUBTYPE_WRAPPED_CALL, }; const CALLTYPE_AUDIO_GET_PROP: u32 = 0xc3000004; @@ -93,8 +94,6 @@ const STATE_PWRD: u32 = from_fourcc(b"pwrd"); const PWRD_OUTPUT: u32 = 2; /// The same for an input stream (the microphones' `pwrd` request uses 1). const PWRD_INPUT: u32 = 1; -/// kIOReturnBusy: the firmware keeps an attachment for its lifetime, so a reload sees this. -const AUDIO_RET_BUSY: u32 = 0xe00002d5; /// Property read (0xc3000004): the same header as the property write, with a trailing 1. #[repr(C, packed(4))]