drivers/watchdog/uniphier_wdt.c

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

File Facts

System
Linux kernel
Corpus path
drivers/watchdog/uniphier_wdt.c
Extension
.c
Size
6435 bytes
Lines
258
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 uniphier_wdt_dev {
	struct watchdog_device wdt_dev;
	struct regmap	*regmap;
};

/*
 * UniPhier Watchdog operations
 */
static int uniphier_watchdog_ping(struct watchdog_device *w)
{
	struct uniphier_wdt_dev *wdev = watchdog_get_drvdata(w);
	unsigned int val;
	int ret;

	/* Clear counter */
	ret = regmap_write_bits(wdev->regmap, WDTCTRL,
				WDTCTRL_CLEAR, WDTCTRL_CLEAR);
	if (!ret)
		/*
		 * As SoC specification, after clear counter,
		 * it needs to wait until counter status is 1.
		 */
		ret = regmap_read_poll_timeout(wdev->regmap, WDTCTRL, val,
					       (val & WDTCTRL_STATUS),
					       0, WDTST_TIMEOUT);

	return ret;
}

static int __uniphier_watchdog_start(struct regmap *regmap, unsigned int sec)
{
	unsigned int val;
	int ret;

	ret = regmap_read_poll_timeout(regmap, WDTCTRL, val,
				       !(val & WDTCTRL_STATUS),
				       0, WDTST_TIMEOUT);
	if (ret)
		return ret;

	/* Setup period */
	ret = regmap_write(regmap, WDTTIMSET,
			   SEC_TO_WDTTIMSET_PRD(sec));
	if (ret)
		return ret;

	/* Enable and clear watchdog */
	ret = regmap_write(regmap, WDTCTRL, WDTCTRL_ENABLE | WDTCTRL_CLEAR);
	if (!ret)
		/*
		 * As SoC specification, after clear counter,
		 * it needs to wait until counter status is 1.
		 */
		ret = regmap_read_poll_timeout(regmap, WDTCTRL, val,
					       (val & WDTCTRL_STATUS),
					       0, WDTST_TIMEOUT);

	return ret;
}

static int __uniphier_watchdog_stop(struct regmap *regmap)
{
	/* Disable and stop watchdog */
	return regmap_write_bits(regmap, WDTCTRL, WDTCTRL_ENABLE, 0);
}

static int __uniphier_watchdog_restart(struct regmap *regmap, unsigned int sec)
{
	int ret;

	ret = __uniphier_watchdog_stop(regmap);
	if (ret)
		return ret;

	return __uniphier_watchdog_start(regmap, sec);
}

static int uniphier_watchdog_start(struct watchdog_device *w)
{
	struct uniphier_wdt_dev *wdev = watchdog_get_drvdata(w);
	unsigned int tmp_timeout;

	tmp_timeout = roundup_pow_of_two(w->timeout);

	return __uniphier_watchdog_start(wdev->regmap, tmp_timeout);
}

static int uniphier_watchdog_stop(struct watchdog_device *w)
{
	struct uniphier_wdt_dev *wdev = watchdog_get_drvdata(w);

Annotation

Implementation Notes