drivers/watchdog/rt2880_wdt.c

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

File Facts

System
Linux kernel
Corpus path
drivers/watchdog/rt2880_wdt.c
Extension
.c
Size
4989 bytes
Lines
204
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 rt2880_wdt_data {
	void __iomem *base;
	unsigned long freq;
	struct clk *clk;
	struct reset_control *rst;
	struct watchdog_device wdt;
};

static bool nowayout = WATCHDOG_NOWAYOUT;
module_param(nowayout, bool, 0);
MODULE_PARM_DESC(nowayout,
		"Watchdog cannot be stopped once started (default="
		__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");

static inline void rt_wdt_w32(void __iomem *base, unsigned int reg, u32 val)
{
	iowrite32(val, base + reg);
}

static inline u32 rt_wdt_r32(void __iomem *base, unsigned int reg)
{
	return ioread32(base + reg);
}

static int rt288x_wdt_ping(struct watchdog_device *w)
{
	struct rt2880_wdt_data *drvdata = watchdog_get_drvdata(w);

	rt_wdt_w32(drvdata->base, TIMER_REG_TMR1LOAD, w->timeout * drvdata->freq);

	return 0;
}

static int rt288x_wdt_start(struct watchdog_device *w)
{
	struct rt2880_wdt_data *drvdata = watchdog_get_drvdata(w);
	u32 t;

	t = rt_wdt_r32(drvdata->base, TIMER_REG_TMR1CTL);
	t &= ~(TMR1CTL_MODE_MASK << TMR1CTL_MODE_SHIFT |
		TMR1CTL_PRESCALE_MASK);
	t |= (TMR1CTL_MODE_WDT << TMR1CTL_MODE_SHIFT |
		TMR1CTL_PRESCALE_65536);
	rt_wdt_w32(drvdata->base, TIMER_REG_TMR1CTL, t);

	rt288x_wdt_ping(w);

	t = rt_wdt_r32(drvdata->base, TIMER_REG_TMR1CTL);
	t |= TMR1CTL_ENABLE;
	rt_wdt_w32(drvdata->base, TIMER_REG_TMR1CTL, t);

	return 0;
}

static int rt288x_wdt_stop(struct watchdog_device *w)
{
	struct rt2880_wdt_data *drvdata = watchdog_get_drvdata(w);
	u32 t;

	rt288x_wdt_ping(w);

	t = rt_wdt_r32(drvdata->base, TIMER_REG_TMR1CTL);
	t &= ~TMR1CTL_ENABLE;
	rt_wdt_w32(drvdata->base, TIMER_REG_TMR1CTL, t);

	return 0;
}

static int rt288x_wdt_set_timeout(struct watchdog_device *w, unsigned int t)
{
	w->timeout = t;
	rt288x_wdt_ping(w);

	return 0;
}

static int rt288x_wdt_bootcause(void)
{
	if (rt_sysc_r32(SYSC_RSTSTAT) & WDT_RST_CAUSE)
		return WDIOF_CARDRESET;

	return 0;
}

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

static const struct watchdog_ops rt288x_wdt_ops = {

Annotation

Implementation Notes