drivers/gpio/gpio-blzp1600.c

Source file repositories/reference/linux-study-clean/drivers/gpio/gpio-blzp1600.c

File Facts

System
Linux kernel
Corpus path
drivers/gpio/gpio-blzp1600.c
Extension
.c
Size
7806 bytes
Lines
291
Domain
Driver Families
Bucket
drivers/gpio
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 blzp1600_gpio {
	void __iomem *base;
	struct gpio_generic_chip gen_gc;
	int irq;
};

static inline struct blzp1600_gpio *get_blzp1600_gpio_from_irq_data(struct irq_data *d)
{
	return gpiochip_get_data(irq_data_get_irq_chip_data(d));
}

static inline struct blzp1600_gpio *get_blzp1600_gpio_from_irq_desc(struct irq_desc *d)
{
	return gpiochip_get_data(irq_desc_get_handler_data(d));
}

static inline u32 blzp1600_gpio_read(struct blzp1600_gpio *chip, unsigned int offset)
{
	return readl_relaxed(chip->base + offset);
}

static inline void blzp1600_gpio_write(struct blzp1600_gpio *chip, unsigned int offset, u32 val)
{
	writel_relaxed(val, chip->base + offset);
}

static inline void blzp1600_gpio_rmw(void __iomem *reg, u32 mask, bool set)
{
	u32 val = readl_relaxed(reg);

	if (set)
		val |= mask;
	else
		val &= ~mask;

	writel_relaxed(val, reg);
}

static void blzp1600_gpio_irq_mask(struct irq_data *d)
{
	struct blzp1600_gpio *chip = get_blzp1600_gpio_from_irq_data(d);

	guard(gpio_generic_lock_irqsave)(&chip->gen_gc);
	blzp1600_gpio_rmw(chip->base + GPIO_IM_REG, BIT(d->hwirq), 1);
}

static void blzp1600_gpio_irq_unmask(struct irq_data *d)
{
	struct blzp1600_gpio *chip = get_blzp1600_gpio_from_irq_data(d);

	guard(gpio_generic_lock_irqsave)(&chip->gen_gc);
	blzp1600_gpio_rmw(chip->base + GPIO_IM_REG, BIT(d->hwirq), 0);
}

static void blzp1600_gpio_irq_ack(struct irq_data *d)
{
	struct blzp1600_gpio *chip = get_blzp1600_gpio_from_irq_data(d);

	blzp1600_gpio_write(chip, GPIO_IC_REG, BIT(d->hwirq));
}

static void blzp1600_gpio_irq_enable(struct irq_data *d)
{
	struct blzp1600_gpio *chip = get_blzp1600_gpio_from_irq_data(d);

	gpiochip_enable_irq(&chip->gen_gc.gc, irqd_to_hwirq(d));

	guard(gpio_generic_lock_irqsave)(&chip->gen_gc);
	blzp1600_gpio_rmw(chip->base + GPIO_DIR_REG, BIT(d->hwirq), 0);
	blzp1600_gpio_rmw(chip->base + GPIO_IEN_REG, BIT(d->hwirq), 1);
}

static void blzp1600_gpio_irq_disable(struct irq_data *d)
{
	struct blzp1600_gpio *chip = get_blzp1600_gpio_from_irq_data(d);

	guard(gpio_generic_lock_irqsave)(&chip->gen_gc);
	blzp1600_gpio_rmw(chip->base + GPIO_IEN_REG, BIT(d->hwirq), 0);
	gpiochip_disable_irq(&chip->gen_gc.gc, irqd_to_hwirq(d));
}

static int blzp1600_gpio_irq_set_type(struct irq_data *d, u32 type)
{
	struct blzp1600_gpio *chip = get_blzp1600_gpio_from_irq_data(d);
	u32 edge_level, single_both, fall_rise;
	int mask = BIT(d->hwirq);

	guard(gpio_generic_lock_irqsave)(&chip->gen_gc);
	edge_level = blzp1600_gpio_read(chip, GPIO_IS_REG);
	single_both = blzp1600_gpio_read(chip, GPIO_IBE_REG);

Annotation

Implementation Notes