Ahmad Fatoum (7): sandbox: power: set $global.system.reset=POR on poweroff sandbox: fix probe order dependency between watchdog and power of: partition: implement of_partition_ensure_probed state: support deep probe nvmem: support deep probe sandbox: turn into deep probe platform Revert "sandbox: hostfile: move initcall to earlier postcore level" arch/sandbox/board/board.c | 16 ++++++++++++++-- arch/sandbox/board/hostfile.c | 2 +- arch/sandbox/board/power.c | 14 +++++++++++--- arch/sandbox/board/watchdog.c | 14 ++++++-------- common/state/state.c | 4 ++++ drivers/nvmem/core.c | 13 +++++++++++++ drivers/of/partition.c | 11 +++++++++++ include/of.h | 6 ++++++ 8 files changed, 66 insertions(+), 14 deletions(-) -- 2.30.2 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox
Now that the stickypage is a regular hostfile, it survives poweroff. This $global.system.reset will only be POR on first boot. For subsequent boots, the power driver must itself take care to write POR to the nvmem cell. While at it remove two minor issues: - src_offset is unused - len is used to store a length into. Its original value is unused Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de> --- arch/sandbox/board/power.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/arch/sandbox/board/power.c b/arch/sandbox/board/power.c index 3112c80348e7..aa778792c155 100644 --- a/arch/sandbox/board/power.c +++ b/arch/sandbox/board/power.c @@ -8,12 +8,15 @@ struct sandbox_power { struct restart_handler rst_hang, rst_reexec; + struct poweroff_handler poweroff; struct nvmem_cell *reset_source_cell; - u32 src_offset; }; static void sandbox_poweroff(struct poweroff_handler *poweroff) { + struct sandbox_power *power = container_of(poweroff, struct sandbox_power, poweroff); + + nvmem_cell_write(power->reset_source_cell, &(u8) { RESET_POR }, 1); linux_exit(); } @@ -36,10 +39,15 @@ static void sandbox_rst_reexec(struct restart_handler *rst) static int sandbox_power_probe(struct device_d *dev) { struct sandbox_power *power = xzalloc(sizeof(*power)); - size_t len = 1; + size_t len; u8 *rst; - poweroff_handler_register_fn(sandbox_poweroff); + power->poweroff = (struct poweroff_handler) { + .name = "exit", + .poweroff = sandbox_poweroff + }; + + poweroff_handler_register(&power->poweroff); power->rst_hang = (struct restart_handler) { .name = "hang", -- 2.30.2 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox
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> --- arch/sandbox/board/watchdog.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/arch/sandbox/board/watchdog.c b/arch/sandbox/board/watchdog.c index ff26a2019fac..daaf549642e3 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; -- 2.30.2 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox
The device tree nodes for both barebox environment and state can have phandles that reference partitions. Environment runs at late_initcall level, so deep probe will have populated the device by the time the probe is called. barebox-state however is probed at device_initcall level and thus must take care itself to ensure the partition provider is probed. Add a new of_partition_ensure_probed that does this. It can handle both legacy and new style (fixed) partitions. Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de> --- drivers/of/partition.c | 11 +++++++++++ include/of.h | 6 ++++++ 2 files changed, 17 insertions(+) diff --git a/drivers/of/partition.c b/drivers/of/partition.c index b6d0523fd960..10081363deee 100644 --- a/drivers/of/partition.c +++ b/drivers/of/partition.c @@ -118,6 +118,17 @@ int of_parse_partitions(struct cdev *cdev, struct device_node *node) return 0; } +int of_partition_ensure_probed(struct device_node *np) +{ + np = of_get_parent(np); + + if (of_device_is_compatible(np, "fixed-partitions")) + np = of_get_parent(np); + + return np ? of_device_ensure_probed(np) : -EINVAL; +} +EXPORT_SYMBOL_GPL(of_partition_ensure_probed); + static void delete_subnodes(struct device_node *np) { struct device_node *part, *tmp; diff --git a/include/of.h b/include/of.h index 677f48d0aba1..4042d8dee8d4 100644 --- a/include/of.h +++ b/include/of.h @@ -283,6 +283,7 @@ extern int of_device_ensure_probed(struct device_node *np); extern int of_device_ensure_probed_by_alias(const char *alias); extern int of_devices_ensure_probed_by_property(const char *property_name); extern int of_devices_ensure_probed_by_dev_id(const struct of_device_id *ids); +extern int of_partition_ensure_probed(struct device_node *np); struct cdev *of_parse_partition(struct cdev *cdev, struct device_node *node); int of_parse_partitions(struct cdev *cdev, struct device_node *node); @@ -398,6 +399,11 @@ of_devices_ensure_probed_by_dev_id(const struct of_device_id *ids) return 0; } +static inline int of_partition_ensure_probed(struct device_node *np) +{ + return 0; +} + static inline int of_bus_n_addr_cells(struct device_node *np) { return 0; -- 2.30.2 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox
With deep probe, drivers registered before of_populate_initcall must themselves take care to ensure their dependencies had a chance to probe. For barebox-state, this means the backend partition provider must be probed. Do so by calling of_partition_ensure_probed on it. Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de> --- common/state/state.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/common/state/state.c b/common/state/state.c index 9d04eab312eb..469ee62d4012 100644 --- a/common/state/state.c +++ b/common/state/state.c @@ -615,6 +615,10 @@ struct state *state_new_from_node(struct device_node *node, bool readonly) } #ifdef __BAREBOX__ + ret = of_partition_ensure_probed(partition_node); + if (ret) + goto out_release_state; + ret = of_find_path_by_node(partition_node, &state->backend_path, 0); #else ret = of_get_devicepath(partition_node, &state->backend_path, &offset, &size); -- 2.30.2 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox
With deep probe, drivers referencing nvmem-cells should make sure their providing nvmem device is already probed. The nvmem cell already takes care to find out the device node providing the cell. The real provider that should be probed is then either: - If the node is in a nvmem-cells partition, the provider is the parent node (skipping a possible fixed-partitions node in-between) - Otherwise, the provider is the parent node of the cell Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de> --- drivers/nvmem/core.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c index 980304a8078b..6af30fc5bae7 100644 --- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c @@ -246,13 +246,26 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config) } EXPORT_SYMBOL_GPL(nvmem_register); +static int of_nvmem_device_ensure_probed(struct device_node *np) +{ + if (of_device_is_compatible(np, "nvmem-cells")) + return of_partition_ensure_probed(np); + + return of_device_ensure_probed(np); +} + static struct nvmem_device *__nvmem_device_get(struct device_node *np, struct nvmem_cell **cellp, const char *cell_id) { struct nvmem_device *nvmem = NULL; + int ret; if (np) { + ret = of_nvmem_device_ensure_probed(np); + if (ret) + return ERR_PTR(ret); + nvmem = of_nvmem_find(np); if (!nvmem) return ERR_PTR(-EPROBE_DEFER); -- 2.30.2 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox
With previous commits sorting out the few remaining issues holding sandbox back from using deep probe, we can now enable it. Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de> --- arch/sandbox/board/board.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/arch/sandbox/board/board.c b/arch/sandbox/board/board.c index 45b7c7deff5e..43e355afe89c 100644 --- a/arch/sandbox/board/board.c +++ b/arch/sandbox/board/board.c @@ -20,6 +20,7 @@ #include <mach/linux.h> #include <init.h> #include <errno.h> +#include <deep-probe.h> #include <fb.h> struct fb_videomode mode = { @@ -44,7 +45,7 @@ static struct device_d devrandom_device = { .name = "devrandom", }; -static int devices_init(void) +static int devices_init(struct device_d *dev) { platform_device_register(&tap_device); @@ -61,4 +62,15 @@ static int devices_init(void) return 0; } -device_initcall(devices_init); +static struct of_device_id sandbox_dt_ids[] = { + { .compatible = "barebox,sandbox" }, + { /* sentinel */ } +}; +BAREBOX_DEEP_PROBE_ENABLE(sandbox_dt_ids); + +static struct driver_d sandbox_board_drv = { + .name = "sandbox-board", + .of_compatible = sandbox_dt_ids, + .probe = devices_init, +}; +device_platform_driver(sandbox_board_drv); -- 2.30.2 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox
The hostfile driver provides nvmem cells, which are consumed optionally by power and watchdog driver. Without deep probe there was no way to differentiate between a nvmem cell that has no provider at all and one with a provider that wasn't yet probed. The workaround is to move hostfile driver probe to an earlier initcall level. Now with deep probe support, this is no longer needed, thus revert commit 33be33ea617514df622a2a468b426e8a628c87e8. Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de> --- arch/sandbox/board/hostfile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/sandbox/board/hostfile.c b/arch/sandbox/board/hostfile.c index f11062197934..7df69f8cfcdc 100644 --- a/arch/sandbox/board/hostfile.c +++ b/arch/sandbox/board/hostfile.c @@ -182,7 +182,7 @@ static struct driver_d hf_drv = { .of_compatible = DRV_OF_COMPAT(hostfile_dt_ids), .probe = hf_probe, }; -postcore_platform_driver(hf_drv); +device_platform_driver(hf_drv); static int of_hostfile_fixup(struct device_node *root, void *ctx) { -- 2.30.2 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox
On Mon, Jun 28, 2021 at 08:45:10AM +0200, Ahmad Fatoum wrote: > Ahmad Fatoum (7): > sandbox: power: set $global.system.reset=POR on poweroff > sandbox: fix probe order dependency between watchdog and power > of: partition: implement of_partition_ensure_probed > state: support deep probe > nvmem: support deep probe > sandbox: turn into deep probe platform > Revert "sandbox: hostfile: move initcall to earlier postcore level" Applied, thanks Sascha -- Pengutronix e.K. | | Steuerwalder Str. 21 | http://www.pengutronix.de/ | 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox