xref: /rk3399_rockchip-uboot/drivers/sysreset/sysreset_watchdog.c (revision 90aa625c9a9e1fb7a2f001fd8e50099bacaf92b8)
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