drivers/watchdog/rzv2h_wdt.c

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

File Facts

System
Linux kernel
Corpus path
drivers/watchdog/rzv2h_wdt.c
Extension
.c
Size
9736 bytes
Lines
382
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 rzv2h_of_data {
	u8 cks_min;
	u8 cks_max;
	u16 cks_div;
	u8 tops;
	u16 timeout_cycles;
	enum rzv2h_wdt_count_source count_source;
	bool wdtdcr;
};

struct rzv2h_wdt_priv {
	void __iomem *base;
	void __iomem *wdtdcr;
	struct clk *pclk;
	struct clk *oscclk;
	struct reset_control *rstc;
	struct watchdog_device wdev;
	const struct rzv2h_of_data *of_data;
};

static int rzv2h_wdt_ping(struct watchdog_device *wdev)
{
	struct rzv2h_wdt_priv *priv = watchdog_get_drvdata(wdev);

	/*
	 * The down-counter is refreshed and starts counting operation on
	 * a write of the values 00h and FFh to the WDTRR register.
	 */
	writeb(0x0, priv->base + WDTRR);
	writeb(0xFF, priv->base + WDTRR);

	return 0;
}

static void rzt2h_wdt_wdtdcr_count_stop(struct rzv2h_wdt_priv *priv)
{
	u32 reg = readl(priv->wdtdcr + WDTDCR);

	writel(reg | WDTDCR_WDTSTOPCTRL, priv->wdtdcr + WDTDCR);
}

static void rzt2h_wdt_wdtdcr_count_start(struct rzv2h_wdt_priv *priv)
{
	u32 reg = readl(priv->wdtdcr + WDTDCR);

	writel(reg & ~WDTDCR_WDTSTOPCTRL, priv->wdtdcr + WDTDCR);
}

static void rzv2h_wdt_setup(struct watchdog_device *wdev, u16 wdtcr)
{
	struct rzv2h_wdt_priv *priv = watchdog_get_drvdata(wdev);

	/* Configure the timeout, clock division ratio, and window start and end positions. */
	writew(wdtcr, priv->base + WDTCR);

	/* Enable interrupt output to the ICU. */
	writeb(0, priv->base + WDTRCR);

	/* Clear underflow flag and refresh error flag. */
	writew(0, priv->base + WDTSR);
}

static int rzv2h_wdt_start(struct watchdog_device *wdev)
{
	struct rzv2h_wdt_priv *priv = watchdog_get_drvdata(wdev);
	const struct rzv2h_of_data *of_data = priv->of_data;
	int ret;

	ret = pm_runtime_resume_and_get(wdev->parent);
	if (ret)
		return ret;

	ret = reset_control_deassert(priv->rstc);
	if (ret) {
		pm_runtime_put(wdev->parent);
		return ret;
	}

	/* delay to handle clock halt after de-assert operation */
	udelay(3);

	/*
	 * WDTCR
	 * - CKS[7:4] - Clock Division Ratio Select
	 *     - 0101b: oscclk/256 for RZ/V2H(P)
	 *     - 1000b: pclkl/8192 for RZ/T2H
	 * - RPSS[13:12] - Window Start Position Select - 11b: 100%
	 * - RPES[9:8] - Window End Position Select - 11b: 0%
	 * - TOPS[1:0] - Timeout Period Select
	 *     - 11b: 16384 cycles (3FFFh) for RZ/V2H(P)

Annotation

Implementation Notes