1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) 2018 Xilinx, Inc. - Michal Simek
4  */
5 
6 #include <common.h>
7 #include <dm.h>
8 #include <errno.h>
9 #include <log.h>
10 #include <sysreset.h>
11 #include <asm/gpio.h>
12 
13 struct gpio_reboot_priv {
14 	struct gpio_desc gpio;
15 };
16 
gpio_reboot_request(struct udevice * dev,enum sysreset_t type)17 static int gpio_reboot_request(struct udevice *dev, enum sysreset_t type)
18 {
19 	struct gpio_reboot_priv *priv = dev_get_priv(dev);
20 	int ret;
21 
22 	/*
23 	 * When debug log is enabled please make sure that chars won't end up
24 	 * in output fifo. Or you can append udelay(); to get enough time
25 	 * to HW to emit output fifo.
26 	 */
27 	debug("GPIO reset\n");
28 
29 	/* Writing 1 respects polarity (active high/low) based on gpio->flags */
30 	ret = dm_gpio_set_value(&priv->gpio, 1);
31 	if (ret < 0)
32 		return ret;
33 
34 	return -EINPROGRESS;
35 }
36 
37 static struct sysreset_ops gpio_reboot_ops = {
38 	.request = gpio_reboot_request,
39 };
40 
gpio_reboot_probe(struct udevice * dev)41 static int gpio_reboot_probe(struct udevice *dev)
42 {
43 	struct gpio_reboot_priv *priv = dev_get_priv(dev);
44 
45 	/*
46 	 * Linux kernel DT binding contain others optional properties
47 	 * which are not supported now
48 	 */
49 
50 	return gpio_request_by_name(dev, "gpios", 0, &priv->gpio, GPIOD_IS_OUT);
51 }
52 
53 static const struct udevice_id led_gpio_ids[] = {
54 	{ .compatible = "gpio-restart" },
55 	{ }
56 };
57 
58 U_BOOT_DRIVER(gpio_reboot) = {
59 	.id = UCLASS_SYSRESET,
60 	.name = "gpio_restart",
61 	.of_match = led_gpio_ids,
62 	.ops = &gpio_reboot_ops,
63 	.priv_auto	= sizeof(struct gpio_reboot_priv),
64 	.probe = gpio_reboot_probe,
65 };
66