drivers/watchdog/st_lpc_wdt.c

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

File Facts

System
Linux kernel
Corpus path
drivers/watchdog/st_lpc_wdt.c
Extension
.c
Size
6837 bytes
Lines
296
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 st_wdog_syscfg {
	unsigned int reset_type_reg;
	unsigned int reset_type_mask;
	unsigned int enable_reg;
	unsigned int enable_mask;
};

struct st_wdog {
	void __iomem *base;
	struct device *dev;
	struct regmap *regmap;
	const struct st_wdog_syscfg *syscfg;
	struct clk *clk;
	unsigned long clkrate;
	bool warm_reset;
};

static struct st_wdog_syscfg stih407_syscfg = {
	.enable_reg		= 0x204,
	.enable_mask		= BIT(19),
};

static const struct of_device_id st_wdog_match[] = {
	{
		.compatible = "st,stih407-lpc",
		.data = &stih407_syscfg,
	},
	{},
};
MODULE_DEVICE_TABLE(of, st_wdog_match);

static void st_wdog_setup(struct st_wdog *st_wdog, bool enable)
{
	/* Type of watchdog reset - 0: Cold 1: Warm */
	if (st_wdog->syscfg->reset_type_reg)
		regmap_update_bits(st_wdog->regmap,
				   st_wdog->syscfg->reset_type_reg,
				   st_wdog->syscfg->reset_type_mask,
				   st_wdog->warm_reset);

	/* Mask/unmask watchdog reset */
	regmap_update_bits(st_wdog->regmap,
			   st_wdog->syscfg->enable_reg,
			   st_wdog->syscfg->enable_mask,
			   enable ? 0 : st_wdog->syscfg->enable_mask);
}

static void st_wdog_load_timer(struct st_wdog *st_wdog, unsigned int timeout)
{
	unsigned long clkrate = st_wdog->clkrate;

	writel_relaxed(timeout * clkrate, st_wdog->base + LPC_LPA_LSB_OFF);
	writel_relaxed(1, st_wdog->base + LPC_LPA_START_OFF);
}

static int st_wdog_start(struct watchdog_device *wdd)
{
	struct st_wdog *st_wdog = watchdog_get_drvdata(wdd);

	writel_relaxed(1, st_wdog->base + LPC_WDT_OFF);

	return 0;
}

static int st_wdog_stop(struct watchdog_device *wdd)
{
	struct st_wdog *st_wdog = watchdog_get_drvdata(wdd);

	writel_relaxed(0, st_wdog->base + LPC_WDT_OFF);

	return 0;
}

static int st_wdog_set_timeout(struct watchdog_device *wdd,
			       unsigned int timeout)
{
	struct st_wdog *st_wdog = watchdog_get_drvdata(wdd);

	wdd->timeout = timeout;
	st_wdog_load_timer(st_wdog, timeout);

	return 0;
}

static int st_wdog_keepalive(struct watchdog_device *wdd)
{
	struct st_wdog *st_wdog = watchdog_get_drvdata(wdd);

	st_wdog_load_timer(st_wdog, wdd->timeout);

Annotation

Implementation Notes