diff options
Diffstat (limited to 'drivers/sysreset')
-rw-r--r-- | drivers/sysreset/Kconfig | 14 | ||||
-rw-r--r-- | drivers/sysreset/Makefile | 2 | ||||
-rw-r--r-- | drivers/sysreset/sysreset-uclass.c | 16 | ||||
-rw-r--r-- | drivers/sysreset/sysreset_gpio.c | 59 | ||||
-rw-r--r-- | drivers/sysreset/sysreset_microblaze.c | 30 |
5 files changed, 121 insertions, 0 deletions
diff --git a/drivers/sysreset/Kconfig b/drivers/sysreset/Kconfig index a6d48e8a66..f2524c18b7 100644 --- a/drivers/sysreset/Kconfig +++ b/drivers/sysreset/Kconfig @@ -15,6 +15,20 @@ 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_MICROBLAZE + bool "Enable support for Microblaze soft reset" + depends on MICROBLAZE + help + This is soft reset on Microblaze which does jump to 0x0 address. + 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..223a0716f0 100644 --- a/drivers/sysreset/Makefile +++ b/drivers/sysreset/Makefile @@ -3,6 +3,8 @@ # (C) Copyright 2016 Cadence Design Systems Inc. obj-$(CONFIG_SYSRESET) += sysreset-uclass.o +obj-$(CONFIG_SYSRESET_GPIO) += sysreset_gpio.o +obj-$(CONFIG_SYSRESET_MICROBLAZE) += sysreset_microblaze.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-uclass.c b/drivers/sysreset/sysreset-uclass.c index 7e06c3c90a..840eab6b57 100644 --- a/drivers/sysreset/sysreset-uclass.c +++ b/drivers/sysreset/sysreset-uclass.c @@ -74,7 +74,23 @@ int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) return 0; } +static int sysreset_post_bind(struct udevice *dev) +{ +#if defined(CONFIG_NEEDS_MANUAL_RELOC) + struct sysreset_ops *ops = sysreset_get_ops(dev); + static int reloc_done; + + if (!reloc_done) { + if (ops->request) + ops->request += gd->reloc_off; + reloc_done++; + } +#endif + return 0; +} + UCLASS_DRIVER(sysreset) = { .id = UCLASS_SYSRESET, .name = "sysreset", + .post_bind = sysreset_post_bind, }; 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, +}; diff --git a/drivers/sysreset/sysreset_microblaze.c b/drivers/sysreset/sysreset_microblaze.c new file mode 100644 index 0000000000..514c95817f --- /dev/null +++ b/drivers/sysreset/sysreset_microblaze.c @@ -0,0 +1,30 @@ +// 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 <linux/err.h> + +static int microblaze_sysreset_request(struct udevice *dev, + enum sysreset_t type) +{ + puts("Microblaze soft reset sysreset\n"); + __asm__ __volatile__ (" mts rmsr, r0;" \ + "bra r0"); + + return -EINPROGRESS; +} + +static struct sysreset_ops microblaze_sysreset = { + .request = microblaze_sysreset_request, +}; + +U_BOOT_DRIVER(sysreset_microblaze) = { + .id = UCLASS_SYSRESET, + .name = "mb_soft_reset", + .ops = µblaze_sysreset, +}; |