Files
linux/include/sound/sdca_interrupts.h
Charles Keepax 050406cbd6 ASoC: SDCA: Populate IRQ data earlier
Currently, the IRQ data (attached Entity/Control/etc) is populated
as the IRQ is requested. However, this can cause issues as
occasionally the setup process wants to access specifics of
an IRQ before the IRQ is actually enabled. To facilitate this
cache all the IRQ data during sdca_irq_populate_early() and make
sdca_irq_populate() simply request the outstanding IRQs. This
also has the advantage that sdca_irq_populate() can now just
iterate through the IRQ array which is much smaller/faster than
going through every Entity in the Function for Controls.

Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
Link: https://patch.msgid.link/20260721143636.361814-5-ckeepax@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2026-07-27 18:47:06 +01:00

110 lines
3.9 KiB
C

/* SPDX-License-Identifier: GPL-2.0 */
/*
* The MIPI SDCA specification is available for public downloads at
* https://www.mipi.org/mipi-sdca-v1-0-download
*
* Copyright (C) 2025 Cirrus Logic, Inc. and
* Cirrus Logic International Semiconductor Ltd.
*/
#ifndef __SDCA_INTERRUPTS_H__
#define __SDCA_INTERRUPTS_H__
#include <linux/interrupt.h>
#include <linux/mutex.h>
#include <linux/regmap.h>
struct device;
struct snd_soc_component;
struct sdca_function_data;
#define SDCA_MAX_INTERRUPTS 31 /* the last bit is reserved for future extensions */
/**
* struct sdca_interrupt - contains information about a single SDCA interrupt
* @name: The name of the interrupt.
* @dev: Pointer to the Function device.
* @device_regmap: Pointer to the IRQ regmap.
* @function_regmap: Pointer to the SDCA Function regmap.
* @component: Pointer to the ASoC component owns the interrupt.
* @function: Pointer to the Function that the interrupt is associated with.
* @entity: Pointer to the Entity that the interrupt is associated with.
* @control: Pointer to the Control that the interrupt is associated with.
* @handler: Handler function to be called for the IRQ.
* @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.
*/
struct sdca_interrupt {
const char *name;
struct device *dev;
struct regmap *device_regmap;
struct regmap *function_regmap;
struct snd_soc_component *component;
struct sdca_function_data *function;
struct sdca_entity *entity;
struct sdca_control *control;
irq_handler_t handler;
void *priv;
void (*free_priv)(struct sdca_interrupt *interrupt);
int irq;
bool early_request;
};
/**
* struct sdca_interrupt_info - contains top-level SDCA interrupt information
* @irq_chip: regmap irq chip structure.
* @irq_data: regmap irq chip data structure.
* @irqs: Array of data for each individual IRQ.
* @irq_lock: Protects access to the list of sdca_interrupt structures.
*/
struct sdca_interrupt_info {
struct regmap_irq_chip irq_chip;
struct regmap_irq_chip_data *irq_data;
struct sdca_interrupt irqs[SDCA_MAX_INTERRUPTS];
struct mutex irq_lock; /* Protect irqs list across functions */
};
int sdca_irq_request(struct device *dev, struct sdca_interrupt_info *interrupt_info,
int sdca_irq, const char *name, irq_handler_t handler,
void *data);
void sdca_irq_free(struct device *dev, struct sdca_interrupt_info *interrupt_info,
int sdca_irq, const char *name, void *data);
int sdca_irq_data_populate(struct device *dev, struct regmap *function_regmap,
struct snd_soc_component *component,
struct sdca_function_data *function,
struct sdca_entity *entity,
struct sdca_control *control,
struct sdca_interrupt *interrupt);
int sdca_irq_populate_early(struct device *dev, struct regmap *function_regmap,
struct sdca_function_data *function,
struct sdca_interrupt_info *info);
int sdca_irq_populate(struct sdca_function_data *function,
struct snd_soc_component *component,
struct sdca_interrupt_info *info);
void sdca_irq_cleanup(struct device *dev,
struct sdca_function_data *function,
struct sdca_interrupt_info *info);
void sdca_irq_cleanup_late(struct device *dev,
struct sdca_function_data *function,
struct sdca_interrupt_info *info);
struct sdca_interrupt_info *devm_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