drivers/watchdog/bd96801_wdt.c

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

File Facts

System
Linux kernel
Corpus path
drivers/watchdog/bd96801_wdt.c
Extension
.c
Size
10243 bytes
Lines
418
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 wdtbd96801 {
	struct device		*dev;
	struct regmap		*regmap;
	struct watchdog_device	wdt;
};

static int bd96801_wdt_ping(struct watchdog_device *wdt)
{
	struct wdtbd96801 *w = watchdog_get_drvdata(wdt);

	return regmap_update_bits(w->regmap, BD96801_REG_WD_FEED,
				  BD96801_WD_FEED_MASK, BD96801_WD_FEED);
}

static int bd96801_wdt_start(struct watchdog_device *wdt)
{
	struct wdtbd96801 *w = watchdog_get_drvdata(wdt);

	return regmap_update_bits(w->regmap, BD96801_REG_WD_CONF,
				  BD96801_WD_EN_MASK, BD96801_WD_IF_EN);
}

static int bd96801_wdt_stop(struct watchdog_device *wdt)
{
	struct wdtbd96801 *w = watchdog_get_drvdata(wdt);

	return regmap_update_bits(w->regmap, BD96801_REG_WD_CONF,
				  BD96801_WD_EN_MASK, BD96801_WD_DISABLE);
}

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

static const struct watchdog_ops bd96801_wdt_ops = {
	.start		= bd96801_wdt_start,
	.stop		= bd96801_wdt_stop,
	.ping		= bd96801_wdt_ping,
};

static int find_closest_fast(unsigned int target, int *sel, unsigned int *val)
{
	unsigned int window = FASTNG_MIN;
	int i;

	for (i = 0; i < 8 && window < target; i++)
		window <<= 1;

	if (i == 8)
		return -EINVAL;

	*val = window;
	*sel = i;

	return 0;
}

static int find_closest_slow_by_fast(unsigned int fast_val, unsigned int *target,
				     int *slowsel)
{
	static const int multipliers[] = {2, 4, 8, 16};
	int sel;

	for (sel = 0; sel < ARRAY_SIZE(multipliers) &&
	     multipliers[sel] * fast_val < *target; sel++)
		;

	if (sel == ARRAY_SIZE(multipliers))
		return -EINVAL;

	*slowsel = sel;
	*target = multipliers[sel] * fast_val;

	return 0;
}

static int find_closest_slow(unsigned int *target, int *slow_sel, int *fast_sel)
{
	static const int multipliers[] = {2, 4, 8, 16};
	unsigned int window = FASTNG_MIN;
	unsigned int val = 0;
	int i, j;

	for (i = 0; i < 8; i++) {
		for (j = 0; j < ARRAY_SIZE(multipliers); j++) {
			unsigned int slow;

			slow = window * multipliers[j];

Annotation

Implementation Notes