drivers/watchdog/ftwdt010_wdt.c

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

File Facts

System
Linux kernel
Corpus path
drivers/watchdog/ftwdt010_wdt.c
Extension
.c
Size
5706 bytes
Lines
243
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 ftwdt010_wdt {
	struct watchdog_device	wdd;
	struct device		*dev;
	void __iomem		*base;
	bool			has_irq;
};

static inline
struct ftwdt010_wdt *to_ftwdt010_wdt(struct watchdog_device *wdd)
{
	return container_of(wdd, struct ftwdt010_wdt, wdd);
}

static void ftwdt010_enable(struct ftwdt010_wdt *gwdt,
			    unsigned int timeout,
			    bool need_irq)
{
	u32 enable;

	writel(timeout * WDT_CLOCK, gwdt->base + FTWDT010_WDLOAD);
	writel(WDRESTART_MAGIC, gwdt->base + FTWDT010_WDRESTART);
	/* set clock before enabling */
	enable = WDCR_CLOCK_5MHZ | WDCR_SYS_RST;
	writel(enable, gwdt->base + FTWDT010_WDCR);
	if (need_irq)
		enable |= WDCR_WDINTR;
	enable |= WDCR_ENABLE;
	writel(enable, gwdt->base + FTWDT010_WDCR);
}

static int ftwdt010_wdt_start(struct watchdog_device *wdd)
{
	struct ftwdt010_wdt *gwdt = to_ftwdt010_wdt(wdd);

	ftwdt010_enable(gwdt, wdd->timeout, gwdt->has_irq);
	return 0;
}

static int ftwdt010_wdt_stop(struct watchdog_device *wdd)
{
	struct ftwdt010_wdt *gwdt = to_ftwdt010_wdt(wdd);

	writel(0, gwdt->base + FTWDT010_WDCR);

	return 0;
}

static int ftwdt010_wdt_ping(struct watchdog_device *wdd)
{
	struct ftwdt010_wdt *gwdt = to_ftwdt010_wdt(wdd);

	writel(WDRESTART_MAGIC, gwdt->base + FTWDT010_WDRESTART);

	return 0;
}

static int ftwdt010_wdt_set_timeout(struct watchdog_device *wdd,
				  unsigned int timeout)
{
	wdd->timeout = timeout;
	if (watchdog_active(wdd))
		ftwdt010_wdt_start(wdd);

	return 0;
}

static int ftwdt010_wdt_restart(struct watchdog_device *wdd,
				unsigned long action, void *data)
{
	ftwdt010_enable(to_ftwdt010_wdt(wdd), 0, false);
	return 0;
}

static irqreturn_t ftwdt010_wdt_interrupt(int irq, void *data)
{
	struct ftwdt010_wdt *gwdt = data;

	watchdog_notify_pretimeout(&gwdt->wdd);

	return IRQ_HANDLED;
}

static const struct watchdog_ops ftwdt010_wdt_ops = {
	.start		= ftwdt010_wdt_start,
	.stop		= ftwdt010_wdt_stop,
	.ping		= ftwdt010_wdt_ping,
	.set_timeout	= ftwdt010_wdt_set_timeout,
	.restart	= ftwdt010_wdt_restart,
	.owner		= THIS_MODULE,
};

Annotation

Implementation Notes