drivers/watchdog/loongson1_wdt.c

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

File Facts

System
Linux kernel
Corpus path
drivers/watchdog/loongson1_wdt.c
Extension
.c
Size
5464 bytes
Lines
212
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 ls1x_wdt_pdata {
	u32 timer_offset;
	u32 set_offset;
	u32 wdt_en_bit;
};

static const struct ls1x_wdt_pdata ls1b_wdt_pdata = {
	.timer_offset = 0x4,
	.set_offset = 0x8,
	.wdt_en_bit = BIT(0),
};

static const struct ls1x_wdt_pdata ls2k0300_wdt_pdata = {
	.timer_offset = 0x8,
	.set_offset = 0x4,
	.wdt_en_bit = BIT(1),
};

struct ls1x_wdt_drvdata {
	void __iomem *base;
	struct clk *clk;
	unsigned long clk_rate;
	struct watchdog_device wdt;
	const struct ls1x_wdt_pdata *pdata;
};

static int ls1x_wdt_ping(struct watchdog_device *wdt_dev)
{
	struct ls1x_wdt_drvdata *drvdata = watchdog_get_drvdata(wdt_dev);

	writel(0x1, drvdata->base + drvdata->pdata->set_offset);

	return 0;
}

static int ls1x_wdt_set_timeout(struct watchdog_device *wdt_dev,
				unsigned int timeout)
{
	struct ls1x_wdt_drvdata *drvdata = watchdog_get_drvdata(wdt_dev);
	unsigned int max_hw_heartbeat = wdt_dev->max_hw_heartbeat_ms / 1000;
	unsigned int counts;

	wdt_dev->timeout = timeout;

	counts = drvdata->clk_rate * min(timeout, max_hw_heartbeat);
	writel(counts, drvdata->base + drvdata->pdata->timer_offset);

	return 0;
}

static int ls1x_wdt_start(struct watchdog_device *wdt_dev)
{
	struct ls1x_wdt_drvdata *drvdata = watchdog_get_drvdata(wdt_dev);

	writel(drvdata->pdata->wdt_en_bit, drvdata->base + WDT_EN);

	return 0;
}

static int ls1x_wdt_stop(struct watchdog_device *wdt_dev)
{
	struct ls1x_wdt_drvdata *drvdata = watchdog_get_drvdata(wdt_dev);
	u32 val = readl(drvdata->base + WDT_EN);

	val &= ~(drvdata->pdata->wdt_en_bit);
	writel(val, drvdata->base + WDT_EN);

	return 0;
}

static int ls1x_wdt_restart(struct watchdog_device *wdt_dev,
			    unsigned long action, void *data)
{
	struct ls1x_wdt_drvdata *drvdata = watchdog_get_drvdata(wdt_dev);

	writel(drvdata->pdata->wdt_en_bit, drvdata->base + WDT_EN);
	writel(0x1, drvdata->base + drvdata->pdata->timer_offset);
	writel(0x1, drvdata->base + drvdata->pdata->set_offset);

	return 0;
}

static const struct watchdog_info ls1x_wdt_info = {
	.options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
	.identity = "Loongson1 Watchdog",
};

static const struct watchdog_ops ls1x_wdt_ops = {
	.owner = THIS_MODULE,
	.start = ls1x_wdt_start,

Annotation

Implementation Notes