summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAhmad Fatoum <a.fatoum@pengutronix.de>2021-06-28 08:45:12 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2021-07-18 07:14:12 +0200
commit44a012366d01a4cbbe1628998a203724cbf57aee (patch)
treebab724df13d852dc67c821f4d7352e933075116e
parentf8cc882812259f763f785ec41e8efae45aee05d8 (diff)
downloadbarebox-44a012366d01a4cbbe1628998a203724cbf57aee.tar.gz
barebox-44a012366d01a4cbbe1628998a203724cbf57aee.tar.xz
sandbox: fix probe order dependency between watchdog and power
With incoming changes to enable deep probe for sandbox, watchdog driver may be probed before power driver, which so far didn't happen. Because the watchdog driver writes the same NVMEM cell read by the power driver, the original value of the nvmem cell (used for $global.system.reset) will be lost. Work around this by writing the WDG reset reason only at first watchdog enable which is guaranteed to happen after power driver probe. We don't need to reset the nvmem cell on watchdog disable, because all other reset methods will already overwrite the cell with the correct value. Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de> Link: https://lore.barebox.org/20210628064517.28636-3-a.fatoum@pengutronix.de Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
-rw-r--r--arch/sandbox/board/watchdog.c14
1 files changed, 6 insertions, 8 deletions
diff --git a/arch/sandbox/board/watchdog.c b/arch/sandbox/board/watchdog.c
index ff26a2019f..daaf549642 100644
--- a/arch/sandbox/board/watchdog.c
+++ b/arch/sandbox/board/watchdog.c
@@ -12,6 +12,7 @@
struct sandbox_watchdog {
struct watchdog wdd;
bool cant_disable :1;
+ struct nvmem_cell *reset_source_cell;
};
static inline struct sandbox_watchdog *to_sandbox_watchdog(struct watchdog *wdd)
@@ -29,6 +30,8 @@ static int sandbox_watchdog_set_timeout(struct watchdog *wdd, unsigned int timeo
if (timeout > wdd->timeout_max)
return -EINVAL;
+ nvmem_cell_write(wd->reset_source_cell, &(u8) { RESET_WDG }, 1);
+
linux_watchdog_set_timeout(timeout);
return 0;
}
@@ -36,7 +39,6 @@ static int sandbox_watchdog_set_timeout(struct watchdog *wdd, unsigned int timeo
static int sandbox_watchdog_probe(struct device_d *dev)
{
struct device_node *np = dev->device_node;
- struct nvmem_cell *reset_source_cell;
struct sandbox_watchdog *wd;
struct watchdog *wdd;
int ret;
@@ -56,16 +58,12 @@ static int sandbox_watchdog_probe(struct device_d *dev)
return ret;
}
- reset_source_cell = of_nvmem_cell_get(dev->device_node, "reset-source");
- if (IS_ERR(reset_source_cell)) {
- dev_warn(dev, "No reset source info available: %pe\n", reset_source_cell);
+ wd->reset_source_cell = of_nvmem_cell_get(dev->device_node, "reset-source");
+ if (IS_ERR(wd->reset_source_cell)) {
+ dev_warn(dev, "No reset source info available: %pe\n", wd->reset_source_cell);
goto out;
}
- nvmem_cell_write(reset_source_cell, &(u8) { RESET_WDG }, 1);
-
- nvmem_cell_put(reset_source_cell);
-
out:
dev_info(dev, "probed\n");
return 0;