From: Charles Keepax ckeepax@opensource.cirrus.com
[ Upstream commit 775f5729b47d8737f4f98e0141f61b3358245398 ]
Zero is a valid SDCA IRQ interrupt position so add a special value to indicate that the IRQ is not used.
Reviewed-by: Bard Liao yung-chuan.liao@linux.intel.com Signed-off-by: Charles Keepax ckeepax@opensource.cirrus.com Reviewed-by: Pierre-Louis Bossart pierre-louis.bossart@linux.dev Link: https://patch.msgid.link/20250624122844.2761627-6-ckeepax@opensource.cirrus.... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org ---
LLM Generated explanations, may be completely bogus:
Now I have a complete picture of the issue. Let me provide my analysis:
**Backport Status: YES**
This commit fixes a subtle but important bug in the SDCA (Smart Digital Class-D Amplifier) subsystem's interrupt handling. Here's why this should be backported:
1. **It fixes a real bug**: Without this change, when the `mipi-sdca- control-interrupt-position` property is missing from the device tree/ACPI, the `control->interrupt_position` field remains uninitialized (even though memory is zero-initialized with `devm_kcalloc`, it's still 0). Since 0 is a valid interrupt position in SDCA, this causes the code to incorrectly treat controls without interrupts as having interrupt position 0.
2. **The bug has functional impact**: Looking at the interrupt handling code in `sdca_irq_populate()` (added in commit b126394d9ec6), it checks: ```c if (irq == SDCA_NO_INTERRUPT) { continue; } ``` Without this fix, controls that should have no interrupt (property missing) would be incorrectly processed as having interrupt position 0, potentially causing: - Incorrect interrupt registration - Conflicts with legitimate interrupt position 0 handlers - Runtime errors when the interrupt framework tries to handle non- existent interrupts
3. **The fix is minimal and safe**: The change simply adds: ```c else control->interrupt_position = SDCA_NO_INTERRUPT; ``` This ensures that when the interrupt position property is missing, the field is explicitly set to -1 (SDCA_NO_INTERRUPT) instead of remaining 0.
4. **It follows stable tree rules**: - Fixes a clear bug (uninitialized/incorrectly initialized field) - Small, contained change (2 lines added) - No architectural changes or new features - Low risk of regression - Only affects SDCA subsystem
5. **The bug exists in stable kernels**: The interrupt handling code that depends on this distinction was added in commit b126394d9ec6 ("ASoC: SDCA: Generic interrupt support"), so any stable kernel that includes that commit needs this fix.
The commit message clearly states the problem: "Zero is a valid SDCA IRQ interrupt position so add a special value to indicate that the IRQ is not used." This is a classic initialization bug where the absence of a value (property not present) needs to be distinguished from a valid zero value.
include/sound/sdca_function.h | 2 ++ sound/soc/sdca/sdca_functions.c | 2 ++ 2 files changed, 4 insertions(+)
diff --git a/include/sound/sdca_function.h b/include/sound/sdca_function.h index eaedb54a8322..b43bda42eeca 100644 --- a/include/sound/sdca_function.h +++ b/include/sound/sdca_function.h @@ -16,6 +16,8 @@ struct device; struct sdca_entity; struct sdca_function_desc;
+#define SDCA_NO_INTERRUPT -1 + /* * The addressing space for SDCA relies on 7 bits for Entities, so a * maximum of 128 Entities per function can be represented. diff --git a/sound/soc/sdca/sdca_functions.c b/sound/soc/sdca/sdca_functions.c index de213a69e0da..dd503acc0c77 100644 --- a/sound/soc/sdca/sdca_functions.c +++ b/sound/soc/sdca/sdca_functions.c @@ -911,6 +911,8 @@ static int find_sdca_entity_control(struct device *dev, struct sdca_entity *enti &tmp); if (!ret) control->interrupt_position = tmp; + else + control->interrupt_position = SDCA_NO_INTERRUPT;
control->label = find_sdca_control_label(dev, entity, control); if (!control->label)