Hi, On 27/04/2018 14:53, Mario Six wrote: > Some reset lines are implemented by toggling the line via a GPIO. > > Add a driver to properly drive such reset lines.
You are defining a "gpio-reset" binding which has always been rejected under Linux, so I'm not sure it's a good idea to add it in U-Boot only... Neil > > Signed-off-by: Mario Six <mario....@gdsys.cc> > --- > > v1 -> v2: > No changes > > --- > drivers/reset/Kconfig | 7 ++++ > drivers/reset/Makefile | 1 + > drivers/reset/gpio-reset.c | 100 > +++++++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 108 insertions(+) > create mode 100644 drivers/reset/gpio-reset.c > > diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig > index 33c39b7fb6..b6e1da009c 100644 > --- a/drivers/reset/Kconfig > +++ b/drivers/reset/Kconfig > @@ -98,4 +98,11 @@ config RESET_SOCFPGA > help > Support for reset controller on SoCFPGA platform. > > +config GPIO_RESET > + bool "Reset driver for GPIO-based reset lines" > + depends on DM_RESET > + help > + Support a generic reset controller that encapsulates a number of > + GPIOs of which each controls a single reset line. > + > endmenu > diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile > index ad08be4c8c..4a9d4006a3 100644 > --- a/drivers/reset/Makefile > +++ b/drivers/reset/Makefile > @@ -15,3 +15,4 @@ obj-$(CONFIG_AST2500_RESET) += ast2500-reset.o > obj-$(CONFIG_RESET_ROCKCHIP) += reset-rockchip.o > obj-$(CONFIG_RESET_MESON) += reset-meson.o > obj-$(CONFIG_RESET_SOCFPGA) += reset-socfpga.o > +obj-$(CONFIG_GPIO_RESET) += gpio-reset.o > diff --git a/drivers/reset/gpio-reset.c b/drivers/reset/gpio-reset.c > new file mode 100644 > index 0000000000..52dd47df60 > --- /dev/null > +++ b/drivers/reset/gpio-reset.c > @@ -0,0 +1,100 @@ > +/* > + * (C) Copyright 2017 > + * Mario Six, Guntermann & Drunck GmbH, mario....@gdsys.cc > + * > + * SPDX-License-Identifier: GPL-2.0+ > + */ > + > +#include <common.h> > +#include <dm.h> > +#include <reset-uclass.h> > +#include <asm/gpio.h> > + > +struct gpio_reset_priv { > + struct gpio_desc gpios[16]; > + uint gpio_num; > +}; > + > +static int gpio_reset_request(struct reset_ctl *reset_ctl) > +{ > + struct gpio_reset_priv *priv = dev_get_priv(reset_ctl->dev); > + > + debug("%s(reset_ctl=%p) (dev=%p, id=%lu)\n", __func__, reset_ctl, > + reset_ctl->dev, reset_ctl->id); > + > + /* Reset ID = number of GPIO in list */ > + if (reset_ctl->id >= priv->gpio_num) > + return -EINVAL; > + > + return 0; > +} > + > +static int gpio_reset_free(struct reset_ctl *reset_ctl) > +{ > + debug("%s(reset_ctl=%p) (dev=%p, id=%lu)\n", __func__, reset_ctl, > + reset_ctl->dev, reset_ctl->id); > + > + return 0; > +} > + > +static int gpio_reset_assert(struct reset_ctl *reset_ctl) > +{ > + struct gpio_reset_priv *priv = dev_get_priv(reset_ctl->dev); > + > + debug("%s(reset_ctl=%p) (dev=%p, id=%lu)\n", __func__, reset_ctl, > + reset_ctl->dev, reset_ctl->id); > + > + dm_gpio_set_value(&priv->gpios[reset_ctl->id], 1); > + > + return 0; > +} > + > +static int gpio_reset_deassert(struct reset_ctl *reset_ctl) > +{ > + struct gpio_reset_priv *priv = dev_get_priv(reset_ctl->dev); > + > + debug("%s(reset_ctl=%p) (dev=%p, id=%lu)\n", __func__, reset_ctl, > + reset_ctl->dev, reset_ctl->id); > + > + dm_gpio_set_value(&priv->gpios[reset_ctl->id], 0); > + > + return 0; > +} > + > +struct reset_ops gpio_reset_ops = { > + .request = gpio_reset_request, > + .free = gpio_reset_free, > + .rst_assert = gpio_reset_assert, > + .rst_deassert = gpio_reset_deassert, > +}; > + > +static int gpio_reset_probe(struct udevice *dev) > +{ > + struct gpio_reset_priv *priv = dev_get_priv(dev); > + int ret; > + > + debug("%s(dev=%p)\n", __func__, dev); > + > + ret = gpio_request_list_by_name(dev, "gpios", priv->gpios, > + ARRAY_SIZE(priv->gpios), GPIOD_IS_OUT); > + if (ret <= 0) > + return ret; > + > + priv->gpio_num = ret; > + > + return 0; > +} > + > +static const struct udevice_id gpio_reset[] = { > + { .compatible = "gpio-reset", }, > + { /* sentinel */ } > +}; > + > +U_BOOT_DRIVER(gpio_reset) = { > + .name = "gpio_reset", > + .id = UCLASS_RESET, > + .of_match = gpio_reset, > + .probe = gpio_reset_probe, > + .ops = &gpio_reset_ops, > + .priv_auto_alloc_size = sizeof(struct gpio_reset_priv), > +}; > -- > 2.16.1 > _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot