drivers/gpio/gpio-mt7621.c

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

File Facts

System
Linux kernel
Corpus path
drivers/gpio/gpio-mt7621.c
Extension
.c
Size
12232 bytes
Lines
502
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 mtk_gc {
	struct gpio_generic_chip chip;
	struct mtk *parent_priv;
	int bank;
	u32 rising;
	u32 falling;
	u32 hlevel;
	u32 llevel;
};

/**
 * struct mtk - state container for
 * data of the platform driver. It is 3
 * separate gpio-chip having an IRQ
 * linear domain shared for all of them
 * @pdev: platform device instance
 * @base: memory base address
 * @irq_domain: IRQ linear domain shared across the three gpio chips
 * @gpio_irq: irq number from the device tree
 * @num_gpios: total number of gpio pins on the three gpio chips
 * @gc_map: array of the gpio chips
 */
struct mtk {
	struct platform_device *pdev;
	void __iomem *base;
	struct irq_domain *irq_domain;
	int gpio_irq;
	int num_gpios;
	struct mtk_gc gc_map[MTK_BANK_CNT];
};

static inline struct mtk *
mt7621_gpio_gc_to_priv(struct gpio_chip *gc)
{
	struct mtk_gc *bank = gpiochip_get_data(gc);

	return bank->parent_priv;
}

static inline struct mtk_gc *
to_mediatek_gpio(struct gpio_chip *chip)
{
	struct gpio_generic_chip *gen_gc = to_gpio_generic_chip(chip);

	return container_of(gen_gc, struct mtk_gc, chip);
}

static inline void
mtk_gpio_w32(struct mtk_gc *rg, u32 offset, u32 val)
{
	struct gpio_chip *gc = &rg->chip.gc;
	struct mtk *mtk = mt7621_gpio_gc_to_priv(gc);

	offset = (rg->bank * GPIO_BANK_STRIDE) + offset;
	gpio_generic_write_reg(&rg->chip, mtk->base + offset, val);
}

static inline u32
mtk_gpio_r32(struct mtk_gc *rg, u32 offset)
{
	struct gpio_chip *gc = &rg->chip.gc;
	struct mtk *mtk = mt7621_gpio_gc_to_priv(gc);

	offset = (rg->bank * GPIO_BANK_STRIDE) + offset;
	return gpio_generic_read_reg(&rg->chip, mtk->base + offset);
}

static void
mt7621_gpio_irq_bank_handler(struct mtk_gc *bank)
{
	struct mtk *priv = bank->parent_priv;
	struct irq_domain *domain = priv->irq_domain;
	int hwbase = bank->chip.gc.offset;
	unsigned long pending;
	unsigned int offset;

	pending = mtk_gpio_r32(bank, GPIO_REG_STAT);
	if (!pending)
		return;

	mtk_gpio_w32(bank, GPIO_REG_STAT, pending);

	for_each_set_bit(offset, &pending, MTK_BANK_WIDTH)
		generic_handle_domain_irq(domain, hwbase + offset);
}

static void
mt7621_gpio_irq_handler(struct irq_desc *desc)
{
	struct mtk *priv = irq_desc_get_handler_data(desc);

Annotation

Implementation Notes