drivers/gpio/gpio-aspeed.c

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

File Facts

System
Linux kernel
Corpus path
drivers/gpio/gpio-aspeed.c
Extension
.c
Size
37917 bytes
Lines
1412
Domain
Driver Families
Bucket
drivers/gpio
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 aspeed_bank_props {
	unsigned int bank;
	u32 input;
	u32 output;
};

struct aspeed_gpio_config {
	unsigned int nr_gpios;
	const struct aspeed_bank_props *props;
	const struct aspeed_gpio_llops *llops;
	const int *debounce_timers_array;
	int debounce_timers_num;
	bool require_dcache;
};

/*
 * @offset_timer: Maps an offset to an @timer_users index, or zero if disabled
 * @timer_users: Tracks the number of users for each timer
 *
 * The @timer_users has four elements but the first element is unused. This is
 * to simplify accounting and indexing, as a zero value in @offset_timer
 * represents disabled debouncing for the GPIO. Any other value for an element
 * of @offset_timer is used as an index into @timer_users. This behaviour of
 * the zero value aligns with the behaviour of zero built from the timer
 * configuration registers (i.e. debouncing is disabled).
 */
struct aspeed_gpio {
	struct gpio_chip chip;
	struct device *dev;
	raw_spinlock_t lock;
	void __iomem *base;
	int irq;
	const struct aspeed_gpio_config *config;

	u8 *offset_timer;
	unsigned int timer_users[4];
	struct clk *clk;

	u32 *dcache;
	u8 *cf_copro_bankmap;
};

struct aspeed_gpio_bank {
	uint16_t	val_regs;	/* +0: Rd: read input value, Wr: set write latch
					 * +4: Rd/Wr: Direction (0=in, 1=out)
					 */
	uint16_t	rdata_reg;	/*     Rd: read write latch, Wr: <none>  */
	uint16_t	irq_regs;
	uint16_t	debounce_regs;
	uint16_t	tolerance_regs;
	uint16_t	cmdsrc_regs;
};

/*
 * Note: The "value" register returns the input value sampled on the
 *       line even when the GPIO is configured as an output. Since
 *       that input goes through synchronizers, writing, then reading
 *       back may not return the written value right away.
 *
 *       The "rdata" register returns the content of the write latch
 *       and thus can be used to read back what was last written
 *       reliably.
 */

static const int debounce_timers[4] = { 0x00, 0x50, 0x54, 0x58 };
static const int g7_debounce_timers[4] = { 0x00, 0x00, 0x04, 0x08 };

/*
 * The debounce timers array is used to configure the debounce timer settings.Here’s how it works:
 * Array Value: Indicates the offset for configuring the debounce timer.
 * Array Index: Corresponds to the debounce setting register.
 * The debounce timers array follows this pattern for configuring the debounce setting registers:
 * Array Index 0: No debounce timer is set;
 *		  Array Value is irrelevant (don’t care).
 * Array Index 1: Debounce setting #2 is set to 1, and debounce setting #1 is set to 0.
 *		  Array Value: offset for configuring debounce timer 0 (g4: 0x50, g7: 0x00)
 * Array Index 2: Debounce setting #2 is set to 0, and debounce setting #1 is set to 1.
 *		  Array Value: offset for configuring debounce timer 1 (g4: 0x54, g7: 0x04)
 * Array Index 3: Debounce setting #2 is set to 1, and debounce setting #1 is set to 1.
 *		  Array Value: offset for configuring debounce timer 2 (g4: 0x58, g7: 0x8)
 */

static const struct aspeed_gpio_copro_ops *copro_ops;
static void *copro_data;

static const struct aspeed_gpio_bank aspeed_gpio_banks[] = {
	{
		.val_regs = 0x0000,
		.rdata_reg = 0x00c0,
		.irq_regs = 0x0008,

Annotation

Implementation Notes