drivers/watchdog/bd9576_wdt.c

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

File Facts

System
Linux kernel
Corpus path
drivers/watchdog/bd9576_wdt.c
Extension
.c
Size
6746 bytes
Lines
293
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 bd9576_wdt_priv {
	struct gpio_desc	*gpiod_ping;
	struct gpio_desc	*gpiod_en;
	struct device		*dev;
	struct regmap		*regmap;
	struct watchdog_device	wdd;
};

static void bd9576_wdt_disable(struct bd9576_wdt_priv *priv)
{
	gpiod_set_value_cansleep(priv->gpiod_en, 0);
}

static int bd9576_wdt_ping(struct watchdog_device *wdd)
{
	struct bd9576_wdt_priv *priv = watchdog_get_drvdata(wdd);

	/* Pulse */
	gpiod_set_value_cansleep(priv->gpiod_ping, 1);
	gpiod_set_value_cansleep(priv->gpiod_ping, 0);

	return 0;
}

static int bd9576_wdt_start(struct watchdog_device *wdd)
{
	struct bd9576_wdt_priv *priv = watchdog_get_drvdata(wdd);

	gpiod_set_value_cansleep(priv->gpiod_en, 1);

	return bd9576_wdt_ping(wdd);
}

static int bd9576_wdt_stop(struct watchdog_device *wdd)
{
	struct bd9576_wdt_priv *priv = watchdog_get_drvdata(wdd);

	bd9576_wdt_disable(priv);

	return 0;
}

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

static const struct watchdog_ops bd957x_wdt_ops = {
	.owner		= THIS_MODULE,
	.start		= bd9576_wdt_start,
	.stop		= bd9576_wdt_stop,
	.ping		= bd9576_wdt_ping,
};

/* Unit is hundreds of uS */
#define FASTNG_MIN 23

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

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

	*val = window;
	*sel = i;

	if (i == 8)
		return -EINVAL;

	return 0;

}

static int find_closest_slow_by_fast(int fast_val, int target, int *slowsel)
{
	int sel;
	static const int multipliers[] = {2, 3, 7, 15};

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

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

	*slowsel = sel;

Annotation

Implementation Notes