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