drivers/watchdog/sunplus_wdt.c

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

File Facts

System
Linux kernel
Corpus path
drivers/watchdog/sunplus_wdt.c
Extension
.c
Size
5138 bytes
Lines
208
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 sp_wdt_priv {
	struct watchdog_device wdev;
	void __iomem *base;
	struct clk *clk;
	struct reset_control *rstc;
};

static int sp_wdt_restart(struct watchdog_device *wdev,
			  unsigned long action, void *data)
{
	struct sp_wdt_priv *priv = watchdog_get_drvdata(wdev);
	void __iomem *base = priv->base;

	writel(WDT_STOP, base + WDT_CTRL);
	writel(WDT_UNLOCK, base + WDT_CTRL);
	writel(0x0001, base + WDT_CNT);
	writel(WDT_LOCK, base + WDT_CTRL);
	writel(WDT_RESUME, base + WDT_CTRL);

	return 0;
}

static int sp_wdt_ping(struct watchdog_device *wdev)
{
	struct sp_wdt_priv *priv = watchdog_get_drvdata(wdev);
	void __iomem *base = priv->base;
	u32 count;

	if (wdev->timeout > SP_WDT_MAX_TIMEOUT) {
		/* WDT_CONMAX sets the count to the maximum (down-counting). */
		writel(WDT_CONMAX, base + WDT_CTRL);
	} else {
		writel(WDT_UNLOCK, base + WDT_CTRL);
		/*
		 * Watchdog timer is a 20-bit down-counting based on STC_CLK.
		 * This register bits[16:0] is from bit[19:4] of the watchdog
		 * timer counter.
		 */
		count = (wdev->timeout * STC_CLK) >> 4;
		writel(count, base + WDT_CNT);
		writel(WDT_LOCK, base + WDT_CTRL);
	}

	return 0;
}

static int sp_wdt_stop(struct watchdog_device *wdev)
{
	struct sp_wdt_priv *priv = watchdog_get_drvdata(wdev);
	void __iomem *base = priv->base;

	writel(WDT_STOP, base + WDT_CTRL);

	return 0;
}

static int sp_wdt_start(struct watchdog_device *wdev)
{
	struct sp_wdt_priv *priv = watchdog_get_drvdata(wdev);
	void __iomem *base = priv->base;

	writel(WDT_RESUME, base + WDT_CTRL);

	return 0;
}

static unsigned int sp_wdt_get_timeleft(struct watchdog_device *wdev)
{
	struct sp_wdt_priv *priv = watchdog_get_drvdata(wdev);
	void __iomem *base = priv->base;
	u32 val;

	val = readl(base + WDT_CNT);
	val &= 0xffff;
	val = val << 4;

	return val;
}

static const struct watchdog_info sp_wdt_info = {
	.identity	= DEVICE_NAME,
	.options	= WDIOF_SETTIMEOUT |
			  WDIOF_MAGICCLOSE |
			  WDIOF_KEEPALIVEPING,
};

static const struct watchdog_ops sp_wdt_ops = {
	.owner		= THIS_MODULE,
	.start		= sp_wdt_start,
	.stop		= sp_wdt_stop,

Annotation

Implementation Notes