drivers/base/regmap/regmap-irq.c

Source file repositories/reference/linux-study-clean/drivers/base/regmap/regmap-irq.c

File Facts

System
Linux kernel
Corpus path
drivers/base/regmap/regmap-irq.c
Extension
.c
Size
32451 bytes
Lines
1211
Domain
Driver Families
Bucket
drivers/base
Inferred role
Driver Families: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct regmap_irq_chip_data {
	struct mutex lock;
	struct lock_class_key lock_key;
	struct irq_chip irq_chip;

	struct regmap *map;
	const struct regmap_irq_chip *chip;

	int irq_base;
	struct irq_domain *domain;

	int irq;
	int wake_count;

	void *status_reg_buf;
	unsigned int *main_status_buf;
	unsigned int *status_buf;
	unsigned int *prev_status_buf;
	unsigned int *mask_buf;
	unsigned int *mask_buf_def;
	unsigned int *wake_buf;
	unsigned int *type_buf;
	unsigned int *type_buf_def;
	unsigned int **config_buf;

	unsigned int irq_reg_stride;

	unsigned int (*get_irq_reg)(struct regmap_irq_chip_data *data,
				    unsigned int base, int index);

	unsigned int clear_status:1;
};

static inline const
struct regmap_irq *irq_to_regmap_irq(struct regmap_irq_chip_data *data,
				     int irq)
{
	return &data->chip->irqs[irq];
}

static bool regmap_irq_can_bulk_read_status(struct regmap_irq_chip_data *data)
{
	struct regmap *map = data->map;

	/*
	 * While possible that a user-defined ->get_irq_reg() callback might
	 * be linear enough to support bulk reads, most of the time it won't.
	 * Therefore only allow them if the default callback is being used.
	 */
	return data->irq_reg_stride == 1 && map->reg_stride == 1 &&
	       data->get_irq_reg == regmap_irq_get_irq_reg_linear &&
	       !map->use_single_read;
}

static void regmap_irq_lock(struct irq_data *data)
{
	struct regmap_irq_chip_data *d = irq_data_get_irq_chip_data(data);

	mutex_lock(&d->lock);
}

static void regmap_irq_sync_unlock(struct irq_data *data)
{
	struct regmap_irq_chip_data *d = irq_data_get_irq_chip_data(data);
	struct regmap *map = d->map;
	int i, j, ret;
	u32 reg;
	u32 val;

	if (d->chip->runtime_pm) {
		ret = pm_runtime_get_sync(map->dev);
		if (ret < 0)
			dev_err(map->dev, "IRQ sync failed to resume: %d\n",
				ret);
	}

	if (d->clear_status) {
		for (i = 0; i < d->chip->num_regs; i++) {
			reg = d->get_irq_reg(d, d->chip->status_base, i);

			ret = regmap_read(map, reg, &val);
			if (ret)
				dev_err(d->map->dev,
					"Failed to clear the interrupt status bits\n");
		}

		d->clear_status = false;
	}

	/*

Annotation

Implementation Notes