drivers/irqchip/irq-starfive-jhb100-intc.c

Source file repositories/reference/linux-study-clean/drivers/irqchip/irq-starfive-jhb100-intc.c

File Facts

System
Linux kernel
Corpus path
drivers/irqchip/irq-starfive-jhb100-intc.c
Extension
.c
Size
7092 bytes
Lines
255
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 starfive_irq_chip {
	void __iomem		*base;
	struct irq_domain	*domain;
	raw_spinlock_t		lock;
};

static void starfive_intc_mod(struct starfive_irq_chip *irqc, u32 reg, u32 mask, u32 data)
{
	u32 value;

	value = ioread32(irqc->base + reg) & ~mask;
	data &= mask;
	data |= value;
	iowrite32(data, irqc->base + reg);
}

static void starfive_intc_bit_set(struct starfive_irq_chip *irqc,
				  u32 reg, u32 bit_mask)
{
	u32 value;

	value = ioread32(irqc->base + reg);
	value |= bit_mask;
	iowrite32(value, irqc->base + reg);
}

static void starfive_intc_bit_clear(struct starfive_irq_chip *irqc,
				    u32 reg, u32 bit_mask)
{
	u32 value;

	value = ioread32(irqc->base + reg);
	value &= ~bit_mask;
	iowrite32(value, irqc->base + reg);
}

static void starfive_intc_unmask(struct irq_data *d)
{
	struct starfive_irq_chip *irqc = irq_data_get_irq_chip_data(d);
	int i, bitpos;

	i = d->hwirq / STARFIVE_INTC_SRC_IRQ_NUM;
	bitpos = d->hwirq % STARFIVE_INTC_SRC_IRQ_NUM;

	guard(raw_spinlock)(&irqc->lock);
	starfive_intc_bit_clear(irqc, STARFIVE_INTC_SRC_MASK(i), BIT(bitpos));
}

static void starfive_intc_mask(struct irq_data *d)
{
	struct starfive_irq_chip *irqc = irq_data_get_irq_chip_data(d);
	int i, bitpos;

	i = d->hwirq / STARFIVE_INTC_SRC_IRQ_NUM;
	bitpos = d->hwirq % STARFIVE_INTC_SRC_IRQ_NUM;

	guard(raw_spinlock)(&irqc->lock);
	starfive_intc_bit_set(irqc, STARFIVE_INTC_SRC_MASK(i), BIT(bitpos));
}

static void starfive_intc_ack(struct irq_data *d)
{
	/* for handle_edge_irq, nothing to do */
}

static int starfive_intc_set_type(struct irq_data *d, unsigned int type)
{
	struct starfive_irq_chip *irqc = irq_data_get_irq_chip_data(d);
	u32 i, bitpos, ty_pos, ty_shift, trigger, typeval;
	irq_flow_handler_t handler;

	i = d->hwirq / STARFIVE_INTC_SRC_IRQ_NUM;
	bitpos = d->hwirq % STARFIVE_INTC_SRC_IRQ_NUM;
	ty_pos = bitpos / STARFIVE_INTC_TYPE_NUM;
	ty_shift = (bitpos % STARFIVE_INTC_TYPE_NUM) * 2;

	switch (type) {
	case IRQF_TRIGGER_LOW:
		trigger = STARFIVE_INTC_TRIGGER_LOW;
		handler = handle_level_irq;
		break;
	case IRQF_TRIGGER_HIGH:
		trigger = STARFIVE_INTC_TRIGGER_HIGH;
		handler = handle_level_irq;
		break;
	case IRQF_TRIGGER_FALLING:
		trigger = STARFIVE_INTC_TRIGGER_NEGEDGE;
		handler = handle_edge_irq;
		break;
	case IRQF_TRIGGER_RISING:

Annotation

Implementation Notes