]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ASoC: SDCA: Add SDCA IRQ enable/disable helpers
authorCharles Keepax <ckeepax@opensource.cirrus.com>
Fri, 9 Jan 2026 14:52:03 +0000 (14:52 +0000)
committerMark Brown <broonie@kernel.org>
Wed, 14 Jan 2026 13:35:51 +0000 (13:35 +0000)
Add helpers to enable and disable the SDCA IRQs by Function. These are
useful to sequence the powering down and up around system suspend.

Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.dev>
Link: https://patch.msgid.link/20260109145206.3456151-2-ckeepax@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
include/sound/sdca_interrupts.h
sound/soc/sdca/sdca_interrupts.c

index 8f13417d129abac6d2ec52b0428e4ffc59f46a26..9bcb5d8fd592bf1e028b258bcd90aca4ccdf09e6 100644 (file)
@@ -84,4 +84,11 @@ int sdca_irq_populate(struct sdca_function_data *function,
 struct sdca_interrupt_info *sdca_irq_allocate(struct device *dev,
                                              struct regmap *regmap, int irq);
 
+void sdca_irq_enable_early(struct sdca_function_data *function,
+                          struct sdca_interrupt_info *info);
+void sdca_irq_enable(struct sdca_function_data *function,
+                    struct sdca_interrupt_info *info);
+void sdca_irq_disable(struct sdca_function_data *function,
+                     struct sdca_interrupt_info *info);
+
 #endif
index ff3a7e405fdcb5a5abc78973c890bd2098cb4d31..afef7bbf613c9cc4d749fc06919b269f274a1966 100644 (file)
@@ -541,3 +541,79 @@ struct sdca_interrupt_info *sdca_irq_allocate(struct device *sdev,
        return info;
 }
 EXPORT_SYMBOL_NS_GPL(sdca_irq_allocate, "SND_SOC_SDCA");
+
+static void irq_enable_flags(struct sdca_function_data *function,
+                            struct sdca_interrupt_info *info, bool early)
+{
+       struct sdca_interrupt *interrupt;
+       int i;
+
+       for (i = 0; i < SDCA_MAX_INTERRUPTS; i++) {
+               interrupt = &info->irqs[i];
+
+               if (!interrupt || interrupt->function != function)
+                       continue;
+
+               switch (SDCA_CTL_TYPE(interrupt->entity->type,
+                                     interrupt->control->sel)) {
+               case SDCA_CTL_TYPE_S(XU, FDL_CURRENTOWNER):
+                       if (early)
+                               enable_irq(interrupt->irq);
+                       break;
+               default:
+                       if (!early)
+                               enable_irq(interrupt->irq);
+                       break;
+               }
+       }
+}
+
+/**
+ * sdca_irq_enable_early - Re-enable early SDCA IRQs for a given function
+ * @function: Pointer to the SDCA Function.
+ * @info: Pointer to the SDCA interrupt info for this device.
+ *
+ * The early version of the IRQ enable allows enabling IRQs which may be
+ * necessary to bootstrap functionality for other IRQs, such as the FDL
+ * process.
+ */
+void sdca_irq_enable_early(struct sdca_function_data *function,
+                          struct sdca_interrupt_info *info)
+{
+       irq_enable_flags(function, info, true);
+}
+EXPORT_SYMBOL_NS_GPL(sdca_irq_enable_early, "SND_SOC_SDCA");
+
+/**
+ * sdca_irq_enable - Re-enable SDCA IRQs for a given function
+ * @function: Pointer to the SDCA Function.
+ * @info: Pointer to the SDCA interrupt info for this device.
+ */
+void sdca_irq_enable(struct sdca_function_data *function,
+                    struct sdca_interrupt_info *info)
+{
+       irq_enable_flags(function, info, false);
+}
+EXPORT_SYMBOL_NS_GPL(sdca_irq_enable, "SND_SOC_SDCA");
+
+/**
+ * sdca_irq_disable - Disable SDCA IRQs for a given function
+ * @function: Pointer to the SDCA Function.
+ * @info: Pointer to the SDCA interrupt info for this device.
+ */
+void sdca_irq_disable(struct sdca_function_data *function,
+                     struct sdca_interrupt_info *info)
+{
+       struct sdca_interrupt *interrupt;
+       int i;
+
+       for (i = 0; i < SDCA_MAX_INTERRUPTS; i++) {
+               interrupt = &info->irqs[i];
+
+               if (!interrupt || interrupt->function != function)
+                       continue;
+
+               disable_irq(interrupt->irq);
+       }
+}
+EXPORT_SYMBOL_NS_GPL(sdca_irq_disable, "SND_SOC_SDCA");