summaryrefslogtreecommitdiff
path: root/sound/soc/sdca
diff options
context:
space:
mode:
authorCharles Keepax <ckeepax@opensource.cirrus.com>2025-10-20 16:55:11 +0100
committerMark Brown <broonie@kernel.org>2025-10-27 15:31:28 +0000
commit12aa3160c10a3179c73c4f99a2d5aec0fd907d0c (patch)
tree67f5973c0391c13cbffbc40b49dd1900646699d5 /sound/soc/sdca
parente92e25f777483b7cc3e170214cc84337d7a415cf (diff)
ASoC: SDCA: Add early IRQ handling
Some IRQs (FDL) require processing before the primary soundcard is brought up, as the downloaded files could be firmware required for operation of the audio functions of the device. Add a new helper function which registers the required IRQs. 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/20251020155512.353774-19-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/sdca')
-rw-r--r--sound/soc/sdca/sdca_interrupts.c71
1 files changed, 71 insertions, 0 deletions
diff --git a/sound/soc/sdca/sdca_interrupts.c b/sound/soc/sdca/sdca_interrupts.c
index 3a3b966b5782..51342b8aacae 100644
--- a/sound/soc/sdca/sdca_interrupts.c
+++ b/sound/soc/sdca/sdca_interrupts.c
@@ -397,6 +397,77 @@ static struct sdca_interrupt *get_interrupt_data(struct device *dev, int irq,
}
/**
+ * sdca_irq_populate_early - process pre-audio card IRQ registrations
+ * @dev: Device pointer for SDCA Function.
+ * @regmap: Regmap pointer for the SDCA Function.
+ * @function: Pointer to the SDCA Function.
+ * @info: Pointer to the SDCA interrupt info for this device.
+ *
+ * This is intended to be used as part of the Function boot process. It
+ * can be called before the soundcard is registered (ie. doesn't depend
+ * on component) and will register the FDL interrupts.
+ *
+ * Return: Zero on success, and a negative error code on failure.
+ */
+int sdca_irq_populate_early(struct device *dev, struct regmap *regmap,
+ struct sdca_function_data *function,
+ struct sdca_interrupt_info *info)
+{
+ int i, j;
+
+ guard(mutex)(&info->irq_lock);
+
+ for (i = 0; i < function->num_entities; i++) {
+ struct sdca_entity *entity = &function->entities[i];
+
+ for (j = 0; j < entity->num_controls; j++) {
+ struct sdca_control *control = &entity->controls[j];
+ int irq = control->interrupt_position;
+ struct sdca_interrupt *interrupt;
+ int ret;
+
+ interrupt = get_interrupt_data(dev, irq, info);
+ if (IS_ERR(interrupt))
+ return PTR_ERR(interrupt);
+ else if (!interrupt)
+ continue;
+
+ switch (entity->type) {
+ case SDCA_ENTITY_TYPE_XU:
+ if (control->sel != SDCA_CTL_XU_FDL_CURRENTOWNER)
+ break;
+
+ ret = sdca_irq_data_populate(dev, regmap, NULL,
+ function, entity,
+ control, interrupt);
+ if (ret)
+ return ret;
+
+ ret = sdca_fdl_alloc_state(interrupt);
+ if (ret)
+ return ret;
+
+ ret = sdca_irq_request_locked(dev, info, irq,
+ interrupt->name,
+ fdl_owner_handler,
+ interrupt);
+ if (ret) {
+ dev_err(dev, "failed to request irq %s: %d\n",
+ interrupt->name, ret);
+ return ret;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_NS_GPL(sdca_irq_populate_early, "SND_SOC_SDCA");
+
+/**
* sdca_irq_populate - Request all the individual IRQs for an SDCA Function
* @function: Pointer to the SDCA Function.
* @component: Pointer to the ASoC component for the Function.