blob: a0ab12851d4c5d1942c363afcb73f660547d3d6a [file] [log] [blame]
maxims@google.com4697abe2017-01-18 13:44:55 -08001/*
2 * (C) Copyright 2016 Google, Inc
3 *
4 * SPDX-License-Identifier: GPL-2.0
5 */
6
7#include <common.h>
8#include <dm.h>
9#include <errno.h>
10#include <sysreset.h>
11#include <asm/io.h>
12#include <asm/arch/wdt.h>
13#include <linux/err.h>
14
15/* Number of Watchdog Timer ticks before reset */
16#define AST_WDT_RESET_TIMEOUT 10
17#define AST_WDT_FOR_RESET 0
18
19static int ast_sysreset_request(struct udevice *dev, enum sysreset_t type)
20{
21 struct ast_wdt *wdt = ast_get_wdt(AST_WDT_FOR_RESET);
22 u32 reset_mode = 0;
23
24 if (IS_ERR(wdt))
25 return PTR_ERR(wdt);
26
27 switch (type) {
28 case SYSRESET_WARM:
29 reset_mode = WDT_CTRL_RESET_CPU;
30 break;
31 case SYSRESET_COLD:
32 reset_mode = WDT_CTRL_RESET_CHIP;
33 break;
34 default:
35 return -EPROTONOSUPPORT;
36 }
37
38 /* Clear reset mode bits */
39 clrsetbits_le32(&wdt->ctrl,
40 (WDT_CTRL_RESET_MODE_MASK << WDT_CTRL_RESET_MODE_SHIFT),
41 (reset_mode << WDT_CTRL_RESET_MODE_SHIFT));
42 wdt_start(wdt, AST_WDT_RESET_TIMEOUT);
43
44 return -EINPROGRESS;
45}
46
47static struct sysreset_ops ast_sysreset = {
48 .request = ast_sysreset_request,
49};
50
51U_BOOT_DRIVER(sysreset_ast) = {
52 .name = "ast_sysreset",
53 .id = UCLASS_SYSRESET,
54 .ops = &ast_sysreset,
55};