drivers/irqchip/irq-qcom-mpm.c

Source file repositories/reference/linux-study-clean/drivers/irqchip/irq-qcom-mpm.c

File Facts

System
Linux kernel
Corpus path
drivers/irqchip/irq-qcom-mpm.c
Extension
.c
Size
13031 bytes
Lines
488
Domain
Driver Families
Bucket
drivers/irqchip
Inferred role
Driver Families: implementation source
Status
source 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 mpm_gic_map {
	int pin;
	irq_hw_number_t hwirq;
};

struct qcom_mpm_priv {
	void __iomem *base;
	raw_spinlock_t lock;
	struct mbox_client mbox_client;
	struct mbox_chan *mbox_chan;
	struct mpm_gic_map *maps;
	unsigned int map_cnt;
	unsigned int reg_stride;
	struct irq_domain *domain;
	struct generic_pm_domain genpd;
};

static u32 qcom_mpm_read(struct qcom_mpm_priv *priv, unsigned int reg,
			 unsigned int index)
{
	unsigned int offset = (reg * priv->reg_stride + index + 2) * 4;

	return readl_relaxed(priv->base + offset);
}

static void qcom_mpm_write(struct qcom_mpm_priv *priv, unsigned int reg,
			   unsigned int index, u32 val)
{
	unsigned int offset = (reg * priv->reg_stride + index + 2) * 4;

	writel_relaxed(val, priv->base + offset);

	/* Ensure the write is completed */
	wmb();
}

static void qcom_mpm_enable_irq(struct irq_data *d, bool en)
{
	struct qcom_mpm_priv *priv = d->chip_data;
	int pin = d->hwirq;
	unsigned int index = pin / 32;
	unsigned int shift = pin % 32;
	unsigned long flags, val;

	raw_spin_lock_irqsave(&priv->lock, flags);

	val = qcom_mpm_read(priv, MPM_REG_ENABLE, index);
	__assign_bit(shift, &val, en);
	qcom_mpm_write(priv, MPM_REG_ENABLE, index, val);

	raw_spin_unlock_irqrestore(&priv->lock, flags);
}

static void qcom_mpm_mask(struct irq_data *d)
{
	qcom_mpm_enable_irq(d, false);

	if (d->parent_data)
		irq_chip_mask_parent(d);
}

static void qcom_mpm_unmask(struct irq_data *d)
{
	qcom_mpm_enable_irq(d, true);

	if (d->parent_data)
		irq_chip_unmask_parent(d);
}

static void mpm_set_type(struct qcom_mpm_priv *priv, bool set, unsigned int reg,
			 unsigned int index, unsigned int shift)
{
	unsigned long flags, val;

	raw_spin_lock_irqsave(&priv->lock, flags);

	val = qcom_mpm_read(priv, reg, index);
	__assign_bit(shift, &val, set);
	qcom_mpm_write(priv, reg, index, val);

	raw_spin_unlock_irqrestore(&priv->lock, flags);
}

static int qcom_mpm_set_type(struct irq_data *d, unsigned int type)
{
	struct qcom_mpm_priv *priv = d->chip_data;
	int pin = d->hwirq;
	unsigned int index = pin / 32;
	unsigned int shift = pin % 32;

Annotation

Implementation Notes