diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2020-10-14 12:46:52 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2020-10-14 12:46:52 +0200 |
commit | bee1da7fcc005edab18fde60fd2ce956d12c5e18 (patch) | |
tree | 77d02747d657192acb10500f979b83e20d0447a3 /arch/sandbox/board | |
parent | c29ce8d93f9403c3ce6ccc5e82fb7a7be41d6659 (diff) | |
parent | 765ecaf52b834278a2449fcb097754a3aae9aa96 (diff) | |
download | barebox-bee1da7fcc005edab18fde60fd2ce956d12c5e18.tar.gz barebox-bee1da7fcc005edab18fde60fd2ce956d12c5e18.tar.xz |
Merge branch 'for-next/sandbox' into master
Diffstat (limited to 'arch/sandbox/board')
-rw-r--r-- | arch/sandbox/board/Makefile | 3 | ||||
-rw-r--r-- | arch/sandbox/board/devices.c | 3 | ||||
-rw-r--r-- | arch/sandbox/board/dtb.c | 28 | ||||
-rw-r--r-- | arch/sandbox/board/env/init/state | 12 | ||||
-rw-r--r-- | arch/sandbox/board/hostfile.c | 94 | ||||
-rw-r--r-- | arch/sandbox/board/power.c | 82 | ||||
-rw-r--r-- | arch/sandbox/board/poweroff.c | 42 | ||||
-rw-r--r-- | arch/sandbox/board/watchdog.c | 84 |
8 files changed, 261 insertions, 87 deletions
diff --git a/arch/sandbox/board/Makefile b/arch/sandbox/board/Makefile index 26f6cb1922..c504c967de 100644 --- a/arch/sandbox/board/Makefile +++ b/arch/sandbox/board/Makefile @@ -4,7 +4,8 @@ obj-y += hostfile.o obj-y += console.o obj-y += devices.o obj-y += dtb.o -obj-y += poweroff.o +obj-y += power.o obj-y += dev-random.o +obj-y += watchdog.o extra-y += barebox.lds diff --git a/arch/sandbox/board/devices.c b/arch/sandbox/board/devices.c index 1fd1913ae6..26152a8b90 100644 --- a/arch/sandbox/board/devices.c +++ b/arch/sandbox/board/devices.c @@ -26,9 +26,6 @@ static int sandbox_device_init(void) { struct device_d *dev, *tmp; - barebox_set_model("barebox sandbox"); - barebox_set_hostname("barebox"); - list_for_each_entry_safe(dev, tmp, &sandbox_device_list, list) { /* reset the list_head before registering for real */ dev->list.prev = NULL; diff --git a/arch/sandbox/board/dtb.c b/arch/sandbox/board/dtb.c index d11bde0249..4a8cbfb26f 100644 --- a/arch/sandbox/board/dtb.c +++ b/arch/sandbox/board/dtb.c @@ -32,32 +32,14 @@ int barebox_register_dtb(const void *new_dtb) return 0; } +extern char __dtb_sandbox_start[]; + static int of_sandbox_init(void) { - struct device_node *root; - int ret; - - if (dtb) { - root = of_unflatten_dtb(dtb); - } else { - root = of_new_node(NULL, NULL); - - ret = of_property_write_u32(root, "#address-cells", 2); - if (ret) - return ret; - - ret = of_property_write_u32(root, "#size-cells", 2); - if (ret) - return ret; - } - - if (IS_ERR(root)) - return PTR_ERR(root); + if (!dtb) + dtb = __dtb_sandbox_start; - of_set_root_node(root); - of_fix_tree(root); - if (IS_ENABLED(CONFIG_OFDEVICE)) - of_probe(); + barebox_register_fdt(dtb); return 0; } diff --git a/arch/sandbox/board/env/init/state b/arch/sandbox/board/env/init/state new file mode 100644 index 0000000000..0b8e40409f --- /dev/null +++ b/arch/sandbox/board/env/init/state @@ -0,0 +1,12 @@ +if [ "x$state.dirty" != "x1" -o $global.system.reset != "POR" ]; then + exit +fi + +source /env/data/ansi-colors + +echo -e $CYAN +echo "******************************************************************" +echo "*** Inconsistent barebox state buckets detected on first boot ***" +echo "*** barebox will repair them on next shutdown ***" +echo "*****************************************************************" +echo -e -n $NC diff --git a/arch/sandbox/board/hostfile.c b/arch/sandbox/board/hostfile.c index 63530bd25e..e3e38b7119 100644 --- a/arch/sandbox/board/hostfile.c +++ b/arch/sandbox/board/hostfile.c @@ -124,9 +124,6 @@ static int hf_probe(struct device_d *dev) if (err) return err; - if (!priv->fd) - priv->fd = linux_open(priv->filename, true); - if (priv->fd < 0) return priv->fd; @@ -194,37 +191,98 @@ static int of_hostfile_fixup(struct device_node *root, void *ctx) { struct hf_info *hf = ctx; struct device_node *node; - uint32_t reg[] = { - hf->base >> 32, - hf->base, - hf->size >> 32, - hf->size - }; + bool name_only = false; int ret; - node = of_new_node(root, hf->devname); + node = of_get_child_by_name(root, hf->devname); + if (node) + name_only = true; + else + node = of_new_node(root, hf->devname); - ret = of_property_write_string(node, "compatible", hostfile_dt_ids->compatible); + ret = of_property_write_string(node, "barebox,filename", hf->filename); if (ret) return ret; - ret = of_property_write_u32_array(node, "reg", reg, ARRAY_SIZE(reg)); + if (name_only) + return 0; + + ret = of_property_write_string(node, "compatible", hostfile_dt_ids->compatible); if (ret) return ret; - ret = of_property_write_u32(node, "barebox,fd", hf->fd); + ret = of_property_write_bool(node, "barebox,blockdev", hf->is_blockdev); if (ret) return ret; - ret = of_property_write_string(node, "barebox,filename", hf->filename); - - if (hf->is_blockdev) - ret = of_property_write_bool(node, "barebox,blockdev", true); + ret = of_property_write_bool(node, "barebox,cdev", hf->is_cdev); + if (ret) + return ret; - return ret; + return of_property_write_bool(node, "barebox,read-only", hf->is_readonly); } int barebox_register_filedev(struct hf_info *hf) { return of_register_fixup(of_hostfile_fixup, hf); } + +static int of_hostfile_map_fixup(struct device_node *root, void *ctx) +{ + struct device_node *node; + int ret; + + for_each_compatible_node_from(node, root, NULL, hostfile_dt_ids->compatible) { + struct hf_info hf = {}; + uint64_t reg[2] = {}; + bool no_filename; + + hf.devname = node->name; + + ret = of_property_read_string(node, "barebox,filename", &hf.filename); + no_filename = ret; + + hf.is_blockdev = of_property_read_bool(node, "barebox,blockdev"); + hf.is_cdev = of_property_read_bool(node, "barebox,cdev"); + hf.is_readonly = of_property_read_bool(node, "barebox,read-only"); + + of_property_read_u64_array(node, "reg", reg, ARRAY_SIZE(reg)); + + hf.base = reg[0]; + hf.size = reg[1]; + + ret = linux_open_hostfile(&hf); + if (ret) + goto out; + + reg[0] = hf.base; + reg[1] = hf.size; + + ret = of_property_write_u64_array(node, "reg", reg, ARRAY_SIZE(reg)); + if (ret) + goto out; + + ret = of_property_write_bool(node, "barebox,blockdev", hf.is_blockdev); + if (ret) + goto out; + + if (no_filename) { + ret = of_property_write_string(node, "barebox,filename", hf.filename); + if (ret) + goto out; + } + + ret = of_property_write_u32(node, "barebox,fd", hf.fd); +out: + if (ret) + pr_err("error fixing up %s: %pe\n", hf.devname, ERR_PTR(ret)); + } + + return 0; +} + +static int barebox_fixup_filedevs(void) +{ + return of_register_fixup(of_hostfile_map_fixup, NULL); +} +pure_initcall(barebox_fixup_filedevs); diff --git a/arch/sandbox/board/power.c b/arch/sandbox/board/power.c new file mode 100644 index 0000000000..3cc9447958 --- /dev/null +++ b/arch/sandbox/board/power.c @@ -0,0 +1,82 @@ +#include <common.h> +#include <driver.h> +#include <poweroff.h> +#include <restart.h> +#include <mach/linux.h> +#include <reset_source.h> +#include <mfd/syscon.h> + +struct sandbox_power { + struct restart_handler rst_hang, rst_reexec; + struct regmap *src; + u32 src_offset; +}; + +static void sandbox_poweroff(struct poweroff_handler *poweroff) +{ + linux_exit(); +} + +static void sandbox_rst_hang(struct restart_handler *rst) +{ + linux_hang(); +} + +static void sandbox_rst_reexec(struct restart_handler *rst) +{ + struct sandbox_power *power = container_of(rst, struct sandbox_power, rst_reexec); + regmap_update_bits(power->src, power->src_offset, 0xff, RESET_RST); + linux_reexec(); +} + +static int sandbox_power_probe(struct device_d *dev) +{ + struct sandbox_power *power = xzalloc(sizeof(*power)); + unsigned int rst; + int ret; + + poweroff_handler_register_fn(sandbox_poweroff); + + power->rst_hang = (struct restart_handler) { + .name = "hang", + .restart = sandbox_rst_hang + }; + + power->rst_reexec = (struct restart_handler) { + .name = "reexec", .priority = 200, + .restart = sandbox_rst_reexec, + }; + + restart_handler_register(&power->rst_hang); + + if (IS_ENABLED(CONFIG_SANDBOX_REEXEC)) + restart_handler_register(&power->rst_reexec); + + power->src = syscon_regmap_lookup_by_phandle(dev->device_node, "barebox,reset-source"); + if (IS_ERR(power->src)) + return 0; + + ret = of_property_read_u32_index(dev->device_node, "barebox,reset-source", 1, + &power->src_offset); + if (ret) + return 0; + + ret = regmap_read(power->src, power->src_offset, &rst); + if (ret == 0 && rst == 0) + rst = RESET_POR; + + reset_source_set_prinst(rst, RESET_SOURCE_DEFAULT_PRIORITY, 0); + return 0; +} + +static __maybe_unused struct of_device_id sandbox_power_dt_ids[] = { + { .compatible = "barebox,sandbox-power" }, + { /* sentinel */ } +}; + +static struct driver_d sandbox_power_drv = { + .name = "sandbox-power", + .of_compatible = sandbox_power_dt_ids, + .probe = sandbox_power_probe, +}; +coredevice_platform_driver(sandbox_power_drv); diff --git a/arch/sandbox/board/poweroff.c b/arch/sandbox/board/poweroff.c deleted file mode 100644 index 8ce739af72..0000000000 --- a/arch/sandbox/board/poweroff.c +++ /dev/null @@ -1,42 +0,0 @@ -#include <common.h> -#include <init.h> -#include <poweroff.h> -#include <restart.h> -#include <mach/linux.h> - -static void sandbox_poweroff(struct poweroff_handler *poweroff) -{ - linux_exit(); -} - -static void sandbox_rst_hang(struct restart_handler *rst) -{ - linux_hang(); -} - -static struct restart_handler rst_hang = { - .name = "hang", - .restart = sandbox_rst_hang -}; - -static void sandbox_rst_reexec(struct restart_handler *rst) -{ - linux_reexec(); -} - -static struct restart_handler rst_reexec = { - .name = "reexec", .priority = 200, - .restart = sandbox_rst_reexec, -}; - -static int poweroff_register_feature(void) -{ - poweroff_handler_register_fn(sandbox_poweroff); - restart_handler_register(&rst_hang); - - if (IS_ENABLED(CONFIG_SANDBOX_REEXEC)) - restart_handler_register(&rst_reexec); - - return 0; -} -coredevice_initcall(poweroff_register_feature); diff --git a/arch/sandbox/board/watchdog.c b/arch/sandbox/board/watchdog.c new file mode 100644 index 0000000000..336451282f --- /dev/null +++ b/arch/sandbox/board/watchdog.c @@ -0,0 +1,84 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include <common.h> +#include <errno.h> +#include <driver.h> +#include <mach/linux.h> +#include <of.h> +#include <watchdog.h> +#include <mfd/syscon.h> +#include <reset_source.h> + +struct sandbox_watchdog { + struct watchdog wdd; + bool cant_disable :1; +}; + +static inline struct sandbox_watchdog *to_sandbox_watchdog(struct watchdog *wdd) +{ + return container_of(wdd, struct sandbox_watchdog, wdd); +} + +static int sandbox_watchdog_set_timeout(struct watchdog *wdd, unsigned int timeout) +{ + struct sandbox_watchdog *wd = to_sandbox_watchdog(wdd); + + if (!timeout && wd->cant_disable) + return -ENOSYS; + + if (timeout > wdd->timeout_max) + return -EINVAL; + + return linux_watchdog_set_timeout(timeout); +} + +static int sandbox_watchdog_probe(struct device_d *dev) +{ + struct device_node *np = dev->device_node; + struct sandbox_watchdog *wd; + struct watchdog *wdd; + struct regmap *src; + u32 src_offset; + int ret; + + wd = xzalloc(sizeof(*wd)); + + wdd = &wd->wdd; + wdd->hwdev = dev; + wdd->set_timeout = sandbox_watchdog_set_timeout; + wdd->timeout_max = 1000; + + wd->cant_disable = of_property_read_bool(np, "barebox,cant-disable"); + + ret = watchdog_register(wdd); + if (ret) { + dev_err(dev, "Failed to register watchdog device\n"); + return ret; + } + + src = syscon_regmap_lookup_by_phandle(np, "barebox,reset-source"); + if (IS_ERR(src)) + return 0; + + ret = of_property_read_u32_index(np, "barebox,reset-source", 1, &src_offset); + if (ret) + return 0; + + regmap_update_bits(src, src_offset, 0xff, RESET_WDG); + + dev_info(dev, "probed\n"); + return 0; +} + + +static __maybe_unused struct of_device_id sandbox_watchdog_dt_ids[] = { + { .compatible = "barebox,sandbox-watchdog" }, + { /* sentinel */ } +}; + +static struct driver_d sandbox_watchdog_drv = { + .name = "sandbox-watchdog", + .of_compatible = sandbox_watchdog_dt_ids, + .probe = sandbox_watchdog_probe, +}; +device_platform_driver(sandbox_watchdog_drv); |