summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS1
-rw-r--r--drivers/sysreset/Kconfig8
-rw-r--r--drivers/sysreset/Makefile1
-rw-r--r--drivers/sysreset/sysreset_gpio.c59
4 files changed, 69 insertions, 0 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 570bc6d1a5..91e4ad7c75 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -419,6 +419,7 @@ F: drivers/net/xilinx_axi_emac.c
F: drivers/net/xilinx_emaclite.c
F: drivers/serial/serial_xuartlite.c
F: drivers/spi/xilinx_spi.c
+F: drivers/sysreset/sysreset_gpio.c
F: drivers/watchdog/xilinx_tb_wdt.c
N: xilinx
diff --git a/drivers/sysreset/Kconfig b/drivers/sysreset/Kconfig
index a6d48e8a66..cec612ed50 100644
--- a/drivers/sysreset/Kconfig
+++ b/drivers/sysreset/Kconfig
@@ -15,6 +15,14 @@ config SYSRESET
if SYSRESET
+config SYSRESET_GPIO
+ bool "Enable support for GPIO reset driver"
+ select GPIO
+ help
+ Reset support via GPIO pin connected reset logic. This is used for
+ example on Microblaze where reset logic can be controlled via GPIO
+ pin which triggers cpu reset.
+
config SYSRESET_PSCI
bool "Enable support for PSCI System Reset"
depends on ARM_PSCI_FW
diff --git a/drivers/sysreset/Makefile b/drivers/sysreset/Makefile
index 0da58a1cf6..ca533cfefa 100644
--- a/drivers/sysreset/Makefile
+++ b/drivers/sysreset/Makefile
@@ -3,6 +3,7 @@
# (C) Copyright 2016 Cadence Design Systems Inc.
obj-$(CONFIG_SYSRESET) += sysreset-uclass.o
+obj-$(CONFIG_SYSRESET_GPIO) += sysreset_gpio.o
obj-$(CONFIG_SYSRESET_PSCI) += sysreset_psci.o
obj-$(CONFIG_SYSRESET_SYSCON) += sysreset_syscon.o
obj-$(CONFIG_SYSRESET_WATCHDOG) += sysreset_watchdog.o
diff --git a/drivers/sysreset/sysreset_gpio.c b/drivers/sysreset/sysreset_gpio.c
new file mode 100644
index 0000000000..ed9a49ad08
--- /dev/null
+++ b/drivers/sysreset/sysreset_gpio.c
@@ -0,0 +1,59 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018 Xilinx, Inc. - Michal Simek
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <sysreset.h>
+#include <asm/gpio.h>
+
+struct gpio_reboot_priv {
+ struct gpio_desc gpio;
+};
+
+static int gpio_reboot_request(struct udevice *dev, enum sysreset_t type)
+{
+ struct gpio_reboot_priv *priv = dev_get_priv(dev);
+
+ /*
+ * When debug log is enabled please make sure that chars won't end up
+ * in output fifo. Or you can append udelay(); to get enough time
+ * to HW to emit output fifo.
+ */
+ debug("GPIO reset\n");
+
+ /* Writing 1 respects polarity (active high/low) based on gpio->flags */
+ return dm_gpio_set_value(&priv->gpio, 1);
+}
+
+static struct sysreset_ops gpio_reboot_ops = {
+ .request = gpio_reboot_request,
+};
+
+int gpio_reboot_probe(struct udevice *dev)
+{
+ struct gpio_reboot_priv *priv = dev_get_priv(dev);
+
+ /*
+ * Linux kernel DT binding contain others optional properties
+ * which are not supported now
+ */
+
+ return gpio_request_by_name(dev, "gpios", 0, &priv->gpio, GPIOD_IS_OUT);
+}
+
+static const struct udevice_id led_gpio_ids[] = {
+ { .compatible = "gpio-restart" },
+ { }
+};
+
+U_BOOT_DRIVER(gpio_reboot) = {
+ .id = UCLASS_SYSRESET,
+ .name = "gpio_restart",
+ .of_match = led_gpio_ids,
+ .ops = &gpio_reboot_ops,
+ .priv_auto_alloc_size = sizeof(struct gpio_reboot_priv),
+ .probe = gpio_reboot_probe,
+};