1 /* 2 * Copyright (C) 2017, STMicroelectronics - All Rights Reserved 3 * Author(s): Patrice Chotard, <patrice.chotard@st.com> for STMicroelectronics. 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 8 #include <common.h> 9 #include <dm.h> 10 #include <regmap.h> 11 #include <syscon.h> 12 #include <sysreset.h> 13 #include <asm/io.h> 14 15 DECLARE_GLOBAL_DATA_PTR; 16 17 struct sti_sysreset_priv { 18 phys_addr_t base; 19 }; 20 21 static int sti_sysreset_request(struct udevice *dev, enum sysreset_t type) 22 { 23 struct sti_sysreset_priv *priv = dev_get_priv(dev); 24 25 generic_clear_bit(0, (void __iomem *)priv->base); 26 27 return -EINPROGRESS; 28 } 29 30 static int sti_sysreset_probe(struct udevice *dev) 31 { 32 struct sti_sysreset_priv *priv = dev_get_priv(dev); 33 struct udevice *syscon; 34 struct regmap *regmap; 35 struct fdtdec_phandle_args syscfg_phandle; 36 int ret; 37 38 /* get corresponding syscon phandle */ 39 ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev_of_offset(dev), 40 "st,syscfg", NULL, 0, 0, 41 &syscfg_phandle); 42 if (ret < 0) { 43 pr_err("Can't get syscfg phandle: %d\n", ret); 44 return ret; 45 } 46 47 ret = uclass_get_device_by_of_offset(UCLASS_SYSCON, 48 syscfg_phandle.node, 49 &syscon); 50 if (ret) { 51 pr_err("%s: uclass_get_device_by_of_offset failed: %d\n", 52 __func__, ret); 53 return ret; 54 } 55 56 regmap = syscon_get_regmap(syscon); 57 if (!regmap) { 58 pr_err("unable to get regmap for %s\n", syscon->name); 59 return -ENODEV; 60 } 61 62 priv->base = regmap->base; 63 64 return 0; 65 } 66 67 static struct sysreset_ops sti_sysreset = { 68 .request = sti_sysreset_request, 69 }; 70 71 static const struct udevice_id sti_sysreset_ids[] = { 72 { .compatible = "st,stih407-restart" }, 73 { } 74 }; 75 76 U_BOOT_DRIVER(sysreset_sti) = { 77 .name = "sysreset_sti", 78 .id = UCLASS_SYSRESET, 79 .ops = &sti_sysreset, 80 .probe = sti_sysreset_probe, 81 .of_match = sti_sysreset_ids, 82 .priv_auto_alloc_size = sizeof(struct sti_sysreset_priv), 83 }; 84