Unverified Commit 9e3d4f79 authored by Charles Keepax's avatar Charles Keepax Committed by Mark Brown
Browse files

ASoC: SDCA: Add SDCA IRQ enable/disable helpers



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: default avatarCharles Keepax <ckeepax@opensource.cirrus.com>
Reviewed-by: default avatarPierre-Louis Bossart <pierre-louis.bossart@linux.dev>
Link: https://patch.msgid.link/20260109145206.3456151-2-ckeepax@opensource.cirrus.com


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 8978da8e
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -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
+76 −0
Original line number Diff line number Diff line
@@ -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");