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