drivers/watchdog/pm8916_wdt.c

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

File Facts

System
Linux kernel
Corpus path
drivers/watchdog/pm8916_wdt.c
Extension
.c
Size
7168 bytes
Lines
278
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 pm8916_wdt {
	struct regmap *regmap;
	struct watchdog_device wdev;
	u32 baseaddr;
};

static int pm8916_wdt_start(struct watchdog_device *wdev)
{
	struct pm8916_wdt *wdt = watchdog_get_drvdata(wdev);

	return regmap_update_bits(wdt->regmap,
				  wdt->baseaddr + PON_PMIC_WD_RESET_S2_CTL2,
				  S2_RESET_EN_BIT, S2_RESET_EN_BIT);
}

static int pm8916_wdt_stop(struct watchdog_device *wdev)
{
	struct pm8916_wdt *wdt = watchdog_get_drvdata(wdev);

	return regmap_update_bits(wdt->regmap,
				  wdt->baseaddr + PON_PMIC_WD_RESET_S2_CTL2,
				  S2_RESET_EN_BIT, 0);
}

static int pm8916_wdt_ping(struct watchdog_device *wdev)
{
	struct pm8916_wdt *wdt = watchdog_get_drvdata(wdev);

	return regmap_write(wdt->regmap, wdt->baseaddr + PON_PMIC_WD_RESET_PET,
			    WATCHDOG_PET_BIT);
}

static int pm8916_wdt_configure_timers(struct watchdog_device *wdev)
{
	struct pm8916_wdt *wdt = watchdog_get_drvdata(wdev);
	int err;

	err = regmap_write(wdt->regmap,
			   wdt->baseaddr + PON_PMIC_WD_RESET_S1_TIMER,
			   wdev->timeout - wdev->pretimeout);
	if (err)
		return err;

	return regmap_write(wdt->regmap,
			    wdt->baseaddr + PON_PMIC_WD_RESET_S2_TIMER,
			    wdev->pretimeout);
}

static int pm8916_wdt_set_timeout(struct watchdog_device *wdev,
				  unsigned int timeout)
{
	wdev->timeout = timeout;

	return pm8916_wdt_configure_timers(wdev);
}

static int pm8916_wdt_set_pretimeout(struct watchdog_device *wdev,
				     unsigned int pretimeout)
{
	wdev->pretimeout = pretimeout;

	return pm8916_wdt_configure_timers(wdev);
}

static irqreturn_t pm8916_wdt_isr(int irq, void *arg)
{
	struct pm8916_wdt *wdt = arg;
	int err, sts;

	err = regmap_read(wdt->regmap, wdt->baseaddr + PON_INT_RT_STS, &sts);
	if (err)
		return IRQ_HANDLED;

	if (sts & PMIC_WD_BARK_STS_BIT)
		watchdog_notify_pretimeout(&wdt->wdev);

	return IRQ_HANDLED;
}

static const struct watchdog_info pm8916_wdt_ident = {
	.options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE |
		   WDIOF_OVERHEAT | WDIOF_CARDRESET | WDIOF_POWERUNDER,
	.identity = "QCOM PM8916 PON WDT",
};

static const struct watchdog_info pm8916_wdt_pt_ident = {
	.options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE |
		   WDIOF_OVERHEAT | WDIOF_CARDRESET | WDIOF_POWERUNDER |
		   WDIOF_PRETIMEOUT,
	.identity = "QCOM PM8916 PON WDT",

Annotation

Implementation Notes