drivers/clocksource/timer-tegra186.c

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

File Facts

System
Linux kernel
Corpus path
drivers/clocksource/timer-tegra186.c
Extension
.c
Size
15885 bytes
Lines
627
Domain
Driver Families
Bucket
drivers/clocksource
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 tegra186_timer_soc {
	unsigned int num_timers;
	unsigned int num_wdts;
};

struct tegra186_tmr {
	struct tegra186_timer *parent;
	void __iomem *regs;
	unsigned int index;
	unsigned int hwirq;
};

struct tegra186_wdt {
	struct watchdog_device base;

	void __iomem *regs;
	unsigned int index;
	bool locked;
	bool is_kernel_wdt;

	struct tegra186_tmr *tmr;
};

static inline struct tegra186_wdt *to_tegra186_wdt(struct watchdog_device *wdd)
{
	return container_of(wdd, struct tegra186_wdt, base);
}

struct tegra186_timer {
	const struct tegra186_timer_soc *soc;
	struct device *dev;
	void __iomem *regs;

	struct tegra186_wdt **wdts;
	struct clocksource usec;
	struct clocksource tsc;
	struct clocksource osc;
};

static void tmr_writel(struct tegra186_tmr *tmr, u32 value, unsigned int offset)
{
	writel_relaxed(value, tmr->regs + offset);
}

static void wdt_writel(struct tegra186_wdt *wdt, u32 value, unsigned int offset)
{
	writel_relaxed(value, wdt->regs + offset);
}

static u32 wdt_readl(struct tegra186_wdt *wdt, unsigned int offset)
{
	return readl_relaxed(wdt->regs + offset);
}

static struct tegra186_tmr *tegra186_tmr_create(struct tegra186_timer *tegra,
						unsigned int index)
{
	unsigned int offset = 0x10000 + index * 0x10000;
	struct tegra186_tmr *tmr;

	tmr = devm_kzalloc(tegra->dev, sizeof(*tmr), GFP_KERNEL);
	if (!tmr)
		return ERR_PTR(-ENOMEM);

	tmr->parent = tegra;
	tmr->regs = tegra->regs + offset;
	tmr->index = index;
	tmr->hwirq = 0;

	return tmr;
}

static const struct watchdog_info tegra186_wdt_info = {
	.options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING,
	.identity = "NVIDIA Tegra186 WDT",
};

static void tegra186_wdt_disable(struct tegra186_wdt *wdt)
{
	/* unlock and disable the watchdog */
	wdt_writel(wdt, WDTUR_UNLOCK_PATTERN, WDTUR);
	wdt_writel(wdt, WDTCMDR_DISABLE_COUNTER, WDTCMDR);

	/* disable timer */
	tmr_writel(wdt->tmr, 0, TMRCR);
}

static void tegra186_wdt_enable(struct tegra186_wdt *wdt)
{
	struct tegra186_timer *tegra = wdt->tmr->parent;

Annotation

Implementation Notes