drivers/gpio/gpio-tegra186.c

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

File Facts

System
Linux kernel
Corpus path
drivers/gpio/gpio-tegra186.c
Extension
.c
Size
44851 bytes
Lines
1563
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 tegra_gpio_port {
	const char *name;
	unsigned int bank;
	unsigned int port;
	unsigned int pins;
};

struct tegra186_pin_range {
	unsigned int offset;
	const char *group;
};

struct tegra_gpio_soc {
	const struct tegra_gpio_port *ports;
	unsigned int num_ports;
	const char *name;
	const char *prefix;
	unsigned int instance;

	unsigned int num_irqs_per_bank;

	const struct tegra186_pin_range *pin_ranges;
	unsigned int num_pin_ranges;
	const char *pinmux;
	bool has_gte;
	bool has_vm_support;
};

struct tegra_gpio {
	struct gpio_chip gpio;
	unsigned int num_irq;

	const struct tegra_gpio_soc *soc;
	unsigned int num_irqs_per_bank;
	unsigned int num_banks;

	void __iomem *secure;
	void __iomem *base;

	unsigned int irq[] __counted_by(num_irq);
};

static const struct tegra_gpio_port *
tegra186_gpio_get_port(struct tegra_gpio *gpio, unsigned int *pin)
{
	unsigned int start = 0, i;

	for (i = 0; i < gpio->soc->num_ports; i++) {
		const struct tegra_gpio_port *port = &gpio->soc->ports[i];

		if (*pin >= start && *pin < start + port->pins) {
			*pin -= start;
			return port;
		}

		start += port->pins;
	}

	return NULL;
}

static void __iomem *tegra186_gpio_get_base(struct tegra_gpio *gpio,
					    unsigned int pin)
{
	const struct tegra_gpio_port *port;
	unsigned int offset;

	port = tegra186_gpio_get_port(gpio, &pin);
	if (!port)
		return NULL;

	offset = port->bank * 0x1000 + port->port * 0x200;

	return gpio->base + offset + pin * 0x20;
}

static void __iomem *tegra186_gpio_get_secure_base(struct tegra_gpio *gpio,
						   unsigned int pin)
{
	const struct tegra_gpio_port *port;
	unsigned int offset;

	port = tegra186_gpio_get_port(gpio, &pin);
	if (!port)
		return NULL;

	offset = port->bank * 0x1000 + port->port * TEGRA186_GPIO_SCR_PORT_SIZE;

	return gpio->secure + offset + pin * TEGRA186_GPIO_SCR_PIN_SIZE;
}

Annotation

Implementation Notes