Skip to content

Commit e7c54a4

Browse files
stephan-ghWim Van Sebroeck
authored andcommitted
watchdog: pm8916_wdt: Report reboot reason
The PM8916 PMIC provides "power-off reason" (POFF_REASON) registers to allow detecting why the board was powered off or rebooted. This can be used to expose if a reset happened due to a watchdog timeout. The watchdog API also provides status bits for overtemperature and undervoltage which happen to be reported in the same PMIC register. Make this information available as part of the watchdog device so userspace can decide to handle the situation accordingly. Signed-off-by: Stephan Gerhold <[email protected]> Reviewed-by: Loic Poulain <[email protected]> Reviewed-by: Guenter Roeck <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Guenter Roeck <[email protected]> Signed-off-by: Wim Van Sebroeck <[email protected]>
1 parent 4e5b406 commit e7c54a4

File tree

1 file changed

+25
-1
lines changed

1 file changed

+25
-1
lines changed

drivers/watchdog/pm8916_wdt.c

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@
99
#include <linux/regmap.h>
1010
#include <linux/watchdog.h>
1111

12+
#define PON_POFF_REASON1 0x0c
13+
#define PON_POFF_REASON1_PMIC_WD BIT(2)
14+
#define PON_POFF_REASON2 0x0d
15+
#define PON_POFF_REASON2_UVLO BIT(5)
16+
#define PON_POFF_REASON2_OTST3 BIT(6)
17+
1218
#define PON_INT_RT_STS 0x10
1319
#define PMIC_WD_BARK_STS_BIT BIT(6)
1420

@@ -110,12 +116,14 @@ static irqreturn_t pm8916_wdt_isr(int irq, void *arg)
110116
}
111117

112118
static const struct watchdog_info pm8916_wdt_ident = {
113-
.options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
119+
.options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE |
120+
WDIOF_OVERHEAT | WDIOF_CARDRESET | WDIOF_POWERUNDER,
114121
.identity = "QCOM PM8916 PON WDT",
115122
};
116123

117124
static const struct watchdog_info pm8916_wdt_pt_ident = {
118125
.options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE |
126+
WDIOF_OVERHEAT | WDIOF_CARDRESET | WDIOF_POWERUNDER |
119127
WDIOF_PRETIMEOUT,
120128
.identity = "QCOM PM8916 PON WDT",
121129
};
@@ -135,6 +143,7 @@ static int pm8916_wdt_probe(struct platform_device *pdev)
135143
struct pm8916_wdt *wdt;
136144
struct device *parent;
137145
int err, irq;
146+
u8 poff[2];
138147

139148
wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL);
140149
if (!wdt)
@@ -175,6 +184,21 @@ static int pm8916_wdt_probe(struct platform_device *pdev)
175184
wdt->wdev.info = &pm8916_wdt_ident;
176185
}
177186

187+
err = regmap_bulk_read(wdt->regmap, wdt->baseaddr + PON_POFF_REASON1,
188+
&poff, ARRAY_SIZE(poff));
189+
if (err) {
190+
dev_err(dev, "failed to read POFF reason: %d\n", err);
191+
return err;
192+
}
193+
194+
dev_dbg(dev, "POFF reason: %#x %#x\n", poff[0], poff[1]);
195+
if (poff[0] & PON_POFF_REASON1_PMIC_WD)
196+
wdt->wdev.bootstatus |= WDIOF_CARDRESET;
197+
if (poff[1] & PON_POFF_REASON2_UVLO)
198+
wdt->wdev.bootstatus |= WDIOF_POWERUNDER;
199+
if (poff[1] & PON_POFF_REASON2_OTST3)
200+
wdt->wdev.bootstatus |= WDIOF_OVERHEAT;
201+
178202
/* Configure watchdog to hard-reset mode */
179203
err = regmap_write(wdt->regmap,
180204
wdt->baseaddr + PON_PMIC_WD_RESET_S2_CTL,

0 commit comments

Comments
 (0)