117a0c141SÁlvaro Fernández Rojas /*
217a0c141SÁlvaro Fernández Rojas * Copyright (C) 2017 Álvaro Fernández Rojas <noltari@gmail.com>
317a0c141SÁlvaro Fernández Rojas *
417a0c141SÁlvaro Fernández Rojas * SPDX-License-Identifier: GPL-2.0+
517a0c141SÁlvaro Fernández Rojas */
617a0c141SÁlvaro Fernández Rojas
717a0c141SÁlvaro Fernández Rojas #include <common.h>
817a0c141SÁlvaro Fernández Rojas #include <dm.h>
917a0c141SÁlvaro Fernández Rojas #include <errno.h>
1017a0c141SÁlvaro Fernández Rojas #include <sysreset.h>
1117a0c141SÁlvaro Fernández Rojas #include <wdt.h>
1217a0c141SÁlvaro Fernández Rojas
1317a0c141SÁlvaro Fernández Rojas struct wdt_reboot_priv {
1417a0c141SÁlvaro Fernández Rojas struct udevice *wdt;
1517a0c141SÁlvaro Fernández Rojas };
1617a0c141SÁlvaro Fernández Rojas
wdt_reboot_request(struct udevice * dev,enum sysreset_t type)1717a0c141SÁlvaro Fernández Rojas static int wdt_reboot_request(struct udevice *dev, enum sysreset_t type)
1817a0c141SÁlvaro Fernández Rojas {
1917a0c141SÁlvaro Fernández Rojas struct wdt_reboot_priv *priv = dev_get_priv(dev);
2017a0c141SÁlvaro Fernández Rojas int ret;
2117a0c141SÁlvaro Fernández Rojas
2217a0c141SÁlvaro Fernández Rojas ret = wdt_expire_now(priv->wdt, 0);
2317a0c141SÁlvaro Fernández Rojas if (ret)
2417a0c141SÁlvaro Fernández Rojas return ret;
2517a0c141SÁlvaro Fernández Rojas
2617a0c141SÁlvaro Fernández Rojas return -EINPROGRESS;
2717a0c141SÁlvaro Fernández Rojas }
2817a0c141SÁlvaro Fernández Rojas
2917a0c141SÁlvaro Fernández Rojas static struct sysreset_ops wdt_reboot_ops = {
3017a0c141SÁlvaro Fernández Rojas .request = wdt_reboot_request,
3117a0c141SÁlvaro Fernández Rojas };
3217a0c141SÁlvaro Fernández Rojas
wdt_reboot_probe(struct udevice * dev)3317a0c141SÁlvaro Fernández Rojas int wdt_reboot_probe(struct udevice *dev)
3417a0c141SÁlvaro Fernández Rojas {
3517a0c141SÁlvaro Fernández Rojas struct wdt_reboot_priv *priv = dev_get_priv(dev);
3617a0c141SÁlvaro Fernández Rojas int err;
3717a0c141SÁlvaro Fernández Rojas
3817a0c141SÁlvaro Fernández Rojas err = uclass_get_device_by_phandle(UCLASS_WDT, dev,
3917a0c141SÁlvaro Fernández Rojas "wdt", &priv->wdt);
4017a0c141SÁlvaro Fernández Rojas if (err) {
41*90aa625cSMasahiro Yamada pr_err("unable to find wdt device\n");
4217a0c141SÁlvaro Fernández Rojas return err;
4317a0c141SÁlvaro Fernández Rojas }
4417a0c141SÁlvaro Fernández Rojas
4517a0c141SÁlvaro Fernández Rojas return 0;
4617a0c141SÁlvaro Fernández Rojas }
4717a0c141SÁlvaro Fernández Rojas
4817a0c141SÁlvaro Fernández Rojas static const struct udevice_id wdt_reboot_ids[] = {
4917a0c141SÁlvaro Fernández Rojas { .compatible = "wdt-reboot" },
5017a0c141SÁlvaro Fernández Rojas { /* sentinel */ }
5117a0c141SÁlvaro Fernández Rojas };
5217a0c141SÁlvaro Fernández Rojas
5317a0c141SÁlvaro Fernández Rojas U_BOOT_DRIVER(wdt_reboot) = {
5417a0c141SÁlvaro Fernández Rojas .name = "wdt_reboot",
5517a0c141SÁlvaro Fernández Rojas .id = UCLASS_SYSRESET,
5617a0c141SÁlvaro Fernández Rojas .of_match = wdt_reboot_ids,
5717a0c141SÁlvaro Fernández Rojas .ops = &wdt_reboot_ops,
5817a0c141SÁlvaro Fernández Rojas .priv_auto_alloc_size = sizeof(struct wdt_reboot_priv),
5917a0c141SÁlvaro Fernández Rojas .probe = wdt_reboot_probe,
6017a0c141SÁlvaro Fernández Rojas };
61