diff options
author | Patrice Chotard <patrice.chotard@st.com> | 2017-02-21 13:37:06 +0100 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2017-03-14 20:40:19 -0400 |
commit | 413788cef5a793b581afb0e4feb2f6e76309d6e6 (patch) | |
tree | 9bef66310069a72450aba605ad78fbab04563c99 /drivers/sysreset/sysreset_sti.c | |
parent | 347cb2edf96d1fcb10b0b98167533ee9e62c0c8e (diff) |
STiH410: Add STi sysreset driver
Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'drivers/sysreset/sysreset_sti.c')
-rw-r--r-- | drivers/sysreset/sysreset_sti.c | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/drivers/sysreset/sysreset_sti.c b/drivers/sysreset/sysreset_sti.c new file mode 100644 index 0000000000..9b58aa8e97 --- /dev/null +++ b/drivers/sysreset/sysreset_sti.c @@ -0,0 +1,82 @@ +/* + * (C) Copyright 2017 Patrice Chotard <patrice.chotard@st.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dm.h> +#include <regmap.h> +#include <syscon.h> +#include <sysreset.h> +#include <asm/io.h> + +DECLARE_GLOBAL_DATA_PTR; + +struct sti_sysreset_priv { + phys_addr_t base; +}; + +static int sti_sysreset_request(struct udevice *dev, enum sysreset_t type) +{ + struct sti_sysreset_priv *priv = dev_get_priv(dev); + + generic_clear_bit(0, (void __iomem *)priv->base); + + return -EINPROGRESS; +} + +static int sti_sysreset_probe(struct udevice *dev) +{ + struct sti_sysreset_priv *priv = dev_get_priv(dev); + struct udevice *syscon; + struct regmap *regmap; + struct fdtdec_phandle_args syscfg_phandle; + int ret; + + /* get corresponding syscon phandle */ + ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev_of_offset(dev), + "st,syscfg", NULL, 0, 0, + &syscfg_phandle); + if (ret < 0) { + error("Can't get syscfg phandle: %d\n", ret); + return ret; + } + + ret = uclass_get_device_by_of_offset(UCLASS_SYSCON, + syscfg_phandle.node, + &syscon); + if (ret) { + error("%s: uclass_get_device_by_of_offset failed: %d\n", + __func__, ret); + return ret; + } + + regmap = syscon_get_regmap(syscon); + if (!regmap) { + error("unable to get regmap for %s\n", syscon->name); + return -ENODEV; + } + + priv->base = regmap->base; + + return 0; +} + +static struct sysreset_ops sti_sysreset = { + .request = sti_sysreset_request, +}; + +static const struct udevice_id sti_sysreset_ids[] = { + { .compatible = "st,stih407-restart" }, + { } +}; + +U_BOOT_DRIVER(sysreset_sti) = { + .name = "sysreset_sti", + .id = UCLASS_SYSRESET, + .ops = &sti_sysreset, + .probe = sti_sysreset_probe, + .of_match = sti_sysreset_ids, + .priv_auto_alloc_size = sizeof(struct sti_sysreset_priv), +}; |