drivers/watchdog/stpmic1_wdt.c

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

File Facts

System
Linux kernel
Corpus path
drivers/watchdog/stpmic1_wdt.c
Extension
.c
Size
3593 bytes
Lines
141
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 stpmic1_wdt {
	struct stpmic1 *pmic;
	struct watchdog_device wdtdev;
};

static int pmic_wdt_start(struct watchdog_device *wdd)
{
	struct stpmic1_wdt *wdt = watchdog_get_drvdata(wdd);

	return regmap_update_bits(wdt->pmic->regmap,
				  WCHDG_CR, WDT_START_MASK, WDT_START);
}

static int pmic_wdt_stop(struct watchdog_device *wdd)
{
	struct stpmic1_wdt *wdt = watchdog_get_drvdata(wdd);

	return regmap_update_bits(wdt->pmic->regmap,
				  WCHDG_CR, WDT_START_MASK, WDT_STOP);
}

static int pmic_wdt_ping(struct watchdog_device *wdd)
{
	struct stpmic1_wdt *wdt = watchdog_get_drvdata(wdd);

	return regmap_update_bits(wdt->pmic->regmap,
				  WCHDG_CR, WDT_PING_MASK, WDT_PING);
}

static int pmic_wdt_set_timeout(struct watchdog_device *wdd,
				unsigned int timeout)
{
	struct stpmic1_wdt *wdt = watchdog_get_drvdata(wdd);

	wdd->timeout = timeout;
	/* timeout is equal to register value + 1 */
	return regmap_write(wdt->pmic->regmap, WCHDG_TIMER_CR, timeout - 1);
}

static const struct watchdog_info pmic_watchdog_info = {
	.options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
	.identity = "STPMIC1 PMIC Watchdog",
};

static const struct watchdog_ops pmic_watchdog_ops = {
	.owner = THIS_MODULE,
	.start = pmic_wdt_start,
	.stop = pmic_wdt_stop,
	.ping = pmic_wdt_ping,
	.set_timeout = pmic_wdt_set_timeout,
};

static int pmic_wdt_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	int ret;
	struct stpmic1 *pmic;
	struct stpmic1_wdt *wdt;

	if (!dev->parent)
		return -EINVAL;

	pmic = dev_get_drvdata(dev->parent);
	if (!pmic)
		return -EINVAL;

	wdt = devm_kzalloc(dev, sizeof(struct stpmic1_wdt), GFP_KERNEL);
	if (!wdt)
		return -ENOMEM;

	wdt->pmic = pmic;

	wdt->wdtdev.info = &pmic_watchdog_info;
	wdt->wdtdev.ops = &pmic_watchdog_ops;
	wdt->wdtdev.min_timeout = PMIC_WDT_MIN_TIMEOUT;
	wdt->wdtdev.max_timeout = PMIC_WDT_MAX_TIMEOUT;
	wdt->wdtdev.parent = dev;

	wdt->wdtdev.timeout = PMIC_WDT_DEFAULT_TIMEOUT;
	watchdog_init_timeout(&wdt->wdtdev, 0, dev);

	watchdog_set_nowayout(&wdt->wdtdev, nowayout);
	watchdog_set_drvdata(&wdt->wdtdev, wdt);

	ret = devm_watchdog_register_device(dev, &wdt->wdtdev);
	if (ret)
		return ret;

	dev_dbg(wdt->pmic->dev, "PMIC Watchdog driver probed\n");
	return 0;

Annotation

Implementation Notes