drivers/watchdog/pic32-dmt.c

Source file repositories/reference/linux-study-clean/drivers/watchdog/pic32-dmt.c

File Facts

System
Linux kernel
Corpus path
drivers/watchdog/pic32-dmt.c
Extension
.c
Size
4929 bytes
Lines
226
Domain
Driver Families
Bucket
drivers/watchdog
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 pic32_dmt {
	void __iomem	*regs;
	struct clk	*clk;
};

static inline void dmt_enable(struct pic32_dmt *dmt)
{
	writel(DMT_ON, PIC32_SET(dmt->regs + DMTCON_REG));
}

static inline void dmt_disable(struct pic32_dmt *dmt)
{
	writel(DMT_ON, PIC32_CLR(dmt->regs + DMTCON_REG));
	/*
	 * Cannot touch registers in the CPU cycle following clearing the
	 * ON bit.
	 */
	nop();
}

static inline int dmt_bad_status(struct pic32_dmt *dmt)
{
	u32 val;

	val = readl(dmt->regs + DMTSTAT_REG);
	val &= (DMTSTAT_BAD1 | DMTSTAT_BAD2 | DMTSTAT_EVENT);
	if (val)
		return -EAGAIN;

	return 0;
}

static inline int dmt_keepalive(struct pic32_dmt *dmt)
{
	u32 v;
	u32 timeout = 500;

	/* set pre-clear key */
	writel(DMT_STEP1_KEY << 8, dmt->regs + DMTPRECLR_REG);

	/* wait for DMT window to open */
	while (--timeout) {
		v = readl(dmt->regs + DMTSTAT_REG) & DMTSTAT_WINOPN;
		if (v == DMTSTAT_WINOPN)
			break;
	}

	/* apply key2 */
	writel(DMT_STEP2_KEY, dmt->regs + DMTCLR_REG);

	/* check whether keys are latched correctly */
	return dmt_bad_status(dmt);
}

static inline u32 pic32_dmt_get_timeout_secs(struct pic32_dmt *dmt)
{
	unsigned long rate;

	rate = clk_get_rate(dmt->clk);
	if (rate)
		return readl(dmt->regs + DMTPSCNT_REG) / rate;

	return 0;
}

static inline u32 pic32_dmt_bootstatus(struct pic32_dmt *dmt)
{
	u32 v;
	void __iomem *rst_base;

	rst_base = ioremap(PIC32_BASE_RESET, 0x10);
	if (!rst_base)
		return 0;

	v = readl(rst_base);

	writel(RESETCON_DMT_TIMEOUT, PIC32_CLR(rst_base));

	iounmap(rst_base);
	return v & RESETCON_DMT_TIMEOUT;
}

static int pic32_dmt_start(struct watchdog_device *wdd)
{
	struct pic32_dmt *dmt = watchdog_get_drvdata(wdd);

	dmt_enable(dmt);
	return dmt_keepalive(dmt);
}

Annotation

Implementation Notes