]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
ASoC: SDCA: Remove devm from primary IRQ cleanup
authorCharles Keepax <ckeepax@opensource.cirrus.com>
Tue, 21 Jul 2026 14:36:32 +0000 (15:36 +0100)
committerMark Brown <broonie@kernel.org>
Mon, 27 Jul 2026 17:47:05 +0000 (18:47 +0100)
To provide greater flexibility on when the IRQs are requested for
client drivers don't use devm for the primary IRQ request/cleanup
helper functions.

Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
Link: https://patch.msgid.link/20260721143636.361814-4-ckeepax@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
include/sound/sdca_fdl.h
include/sound/sdca_interrupts.h
include/sound/sdca_jack.h
sound/soc/sdca/sdca_fdl.c
sound/soc/sdca/sdca_interrupts.c
sound/soc/sdca/sdca_jack.c

index fbaf4b384c8af8e9162bf619287f2d1c197a149c..dc33927b82bde6aec28f4190703ab5b7aa80ad05 100644 (file)
@@ -67,6 +67,8 @@ struct fdl_state {
 #if IS_ENABLED(CONFIG_SND_SOC_SDCA_FDL)
 
 int sdca_fdl_alloc_state(struct sdca_interrupt *interrupt);
+void sdca_fdl_free_state(struct sdca_interrupt *interrupt);
+
 int sdca_fdl_process(struct sdca_interrupt *interrupt);
 int sdca_fdl_sync(struct device *dev, struct sdca_function_data *function,
                  struct sdca_interrupt_info *info);
index 38c6c58c2cc78eb78ab05ad7d3724784e197c415..8a44c19e917ce1f3bffc87e834816a56dbb775fe 100644 (file)
@@ -31,6 +31,7 @@ struct sdca_function_data;
  * @entity: Pointer to the Entity that the interrupt is associated with.
  * @control: Pointer to the Control that the interrupt is associated with.
  * @priv: Pointer to private data for use by the handler.
+ * @free_priv: Pointer to a function that can be used to free the priv data.
  * @irq: IRQ number allocated to this interrupt, also used internally to track
  * the IRQ being assigned.
  * @early_request: Flag to indicate this IRQ was requested at bus probe time.
@@ -47,6 +48,7 @@ struct sdca_interrupt {
        struct sdca_control *control;
 
        void *priv;
+       void (*free_priv)(struct sdca_interrupt *interrupt);
 
        int irq;
        bool early_request;
index 181541f0f4d8c46b308a92a583c2154a260e57f9..59de40b7d7d01d3eab717b5bd6f1835e2d6ad613 100644 (file)
@@ -28,6 +28,8 @@ struct jack_state {
 };
 
 int sdca_jack_alloc_state(struct sdca_interrupt *interrupt);
+void sdca_jack_free_state(struct sdca_interrupt *interrupt);
+
 int sdca_jack_process(struct sdca_interrupt *interrupt);
 int sdca_jack_set_jack(struct sdca_interrupt_info *info, struct snd_soc_jack *jack);
 int sdca_jack_report(struct sdca_interrupt *interrupt);
index 994821a6df617d9c5d4c32a9ff055b17b88d040f..82e09d960c1275c2a7de3f6227a9688522639503 100644 (file)
@@ -481,10 +481,9 @@ EXPORT_SYMBOL_NS_GPL(sdca_fdl_process, "SND_SOC_SDCA");
  */
 int sdca_fdl_alloc_state(struct sdca_interrupt *interrupt)
 {
-       struct device *dev = interrupt->dev;
        struct fdl_state *fdl_state;
 
-       fdl_state = devm_kzalloc(dev, sizeof(*fdl_state), GFP_KERNEL);
+       fdl_state = kzalloc_obj(*fdl_state);
        if (!fdl_state)
                return -ENOMEM;
 
@@ -499,3 +498,13 @@ int sdca_fdl_alloc_state(struct sdca_interrupt *interrupt)
        return 0;
 }
 EXPORT_SYMBOL_NS_GPL(sdca_fdl_alloc_state, "SND_SOC_SDCA");
+
+/**
+ * sdca_fdl_free_state - free state for an FDL interrupt
+ * @interrupt: SDCA interrupt structure.
+ */
+void sdca_fdl_free_state(struct sdca_interrupt *interrupt)
+{
+       kfree(interrupt->priv);
+}
+EXPORT_SYMBOL_NS_GPL(sdca_fdl_free_state, "SND_SOC_SDCA");
index d86884a89c4059d92ecdfe5931d360ce141b67f2..cd2c5d49bb95b3b7ccdd1ed4b09aaaeb8b233c39 100644 (file)
@@ -457,6 +457,7 @@ int sdca_irq_populate_early(struct device *dev, struct regmap *regmap,
                                        return ret;
 
                                interrupt->early_request = true;
+                               interrupt->free_priv = sdca_fdl_free_state;
 
                                ret = sdca_fdl_alloc_state(interrupt);
                                if (ret)
@@ -530,6 +531,8 @@ int sdca_irq_populate(struct sdca_function_data *function,
                                handler = function_status_handler;
                                break;
                        case SDCA_CTL_TYPE_S(GE, DETECTED_MODE):
+                               interrupt->free_priv = sdca_jack_free_state;
+
                                ret = sdca_jack_alloc_state(interrupt);
                                if (ret)
                                        return ret;
@@ -537,6 +540,8 @@ int sdca_irq_populate(struct sdca_function_data *function,
                                handler = detected_mode_handler;
                                break;
                        case SDCA_CTL_TYPE_S(XU, FDL_CURRENTOWNER):
+                               interrupt->free_priv = sdca_fdl_free_state;
+
                                ret = sdca_fdl_alloc_state(interrupt);
                                if (ret)
                                        return ret;
@@ -584,6 +589,9 @@ static void sdca_irq_cleanup_flags(struct device *dev,
 
                sdca_irq_free_locked(dev, info, i, interrupt->name, interrupt);
 
+               if (interrupt->free_priv)
+                       interrupt->free_priv(interrupt);
+
                kfree(interrupt->name);
        }
 }
index ae9636622a840246de6650b113b7f670b59882c3..ffa87096492480e6f3f12ed6503517b6f737eb05 100644 (file)
@@ -132,10 +132,9 @@ EXPORT_SYMBOL_NS_GPL(sdca_jack_process, "SND_SOC_SDCA");
  */
 int sdca_jack_alloc_state(struct sdca_interrupt *interrupt)
 {
-       struct device *dev = interrupt->dev;
        struct jack_state *jack_state;
 
-       jack_state = devm_kzalloc(dev, sizeof(*jack_state), GFP_KERNEL);
+       jack_state = kzalloc_obj(*jack_state);
        if (!jack_state)
                return -ENOMEM;
 
@@ -145,6 +144,16 @@ int sdca_jack_alloc_state(struct sdca_interrupt *interrupt)
 }
 EXPORT_SYMBOL_NS_GPL(sdca_jack_alloc_state, "SND_SOC_SDCA");
 
+/**
+ * sdca_jack_free_state - free state for a jack interrupt
+ * @interrupt: SDCA interrupt structure.
+ */
+void sdca_jack_free_state(struct sdca_interrupt *interrupt)
+{
+       kfree(interrupt->priv);
+}
+EXPORT_SYMBOL_NS_GPL(sdca_jack_free_state, "SND_SOC_SDCA");
+
 static int type_get_mask(enum sdca_terminal_type type)
 {
        switch (type) {