drivers/irqchip/irq-tegra.c

Source file repositories/reference/linux-study-clean/drivers/irqchip/irq-tegra.c

File Facts

System
Linux kernel
Corpus path
drivers/irqchip/irq-tegra.c
Extension
.c
Size
8776 bytes
Lines
363
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 tegra_ictlr_soc {
	unsigned int num_ictlrs;
};

static const struct tegra_ictlr_soc tegra20_ictlr_soc = {
	.num_ictlrs = 4,
};

static const struct tegra_ictlr_soc tegra30_ictlr_soc = {
	.num_ictlrs = 5,
};

static const struct tegra_ictlr_soc tegra210_ictlr_soc = {
	.num_ictlrs = 6,
};

static const struct of_device_id ictlr_matches[] = {
	{ .compatible = "nvidia,tegra210-ictlr", .data = &tegra210_ictlr_soc },
	{ .compatible = "nvidia,tegra30-ictlr", .data = &tegra30_ictlr_soc },
	{ .compatible = "nvidia,tegra20-ictlr", .data = &tegra20_ictlr_soc },
	{ }
};

struct tegra_ictlr_info {
	void __iomem *base[TEGRA_MAX_NUM_ICTLRS];
#ifdef CONFIG_PM_SLEEP
	u32 cop_ier[TEGRA_MAX_NUM_ICTLRS];
	u32 cop_iep[TEGRA_MAX_NUM_ICTLRS];
	u32 cpu_ier[TEGRA_MAX_NUM_ICTLRS];
	u32 cpu_iep[TEGRA_MAX_NUM_ICTLRS];

	u32 ictlr_wake_mask[TEGRA_MAX_NUM_ICTLRS];
#endif
};

static struct tegra_ictlr_info *lic;

static inline void tegra_ictlr_write_mask(struct irq_data *d, unsigned long reg)
{
	void __iomem *base = (void __iomem __force *)d->chip_data;
	u32 mask;

	mask = BIT(d->hwirq % 32);
	writel_relaxed(mask, base + reg);
}

static void tegra_mask(struct irq_data *d)
{
	tegra_ictlr_write_mask(d, ICTLR_CPU_IER_CLR);
	irq_chip_mask_parent(d);
}

static void tegra_unmask(struct irq_data *d)
{
	tegra_ictlr_write_mask(d, ICTLR_CPU_IER_SET);
	irq_chip_unmask_parent(d);
}

static void tegra_eoi(struct irq_data *d)
{
	tegra_ictlr_write_mask(d, ICTLR_CPU_IEP_FIR_CLR);
	irq_chip_eoi_parent(d);
}

static int tegra_retrigger(struct irq_data *d)
{
	tegra_ictlr_write_mask(d, ICTLR_CPU_IEP_FIR_SET);
	return irq_chip_retrigger_hierarchy(d);
}

#ifdef CONFIG_PM_SLEEP
static int tegra_set_wake(struct irq_data *d, unsigned int enable)
{
	u32 irq = d->hwirq;
	u32 index, mask;

	index = (irq / 32);
	mask = BIT(irq % 32);
	if (enable)
		lic->ictlr_wake_mask[index] |= mask;
	else
		lic->ictlr_wake_mask[index] &= ~mask;

	/*
	 * Do *not* call into the parent, as the GIC doesn't have any
	 * wake-up facility...
	 */
	return 0;
}

Annotation

Implementation Notes