111636258SStephen Warren /*
211636258SStephen Warren * Copyright (c) 2015 Google, Inc
311636258SStephen Warren * Written by Simon Glass <sjg@chromium.org>
411636258SStephen Warren *
511636258SStephen Warren * SPDX-License-Identifier: GPL-2.0+
611636258SStephen Warren */
711636258SStephen Warren
811636258SStephen Warren #ifndef __SYSRESET_H
911636258SStephen Warren #define __SYSRESET_H
1011636258SStephen Warren
1111636258SStephen Warren enum sysreset_t {
1211636258SStephen Warren SYSRESET_WARM, /* Reset CPU, keep GPIOs active */
1311636258SStephen Warren SYSRESET_COLD, /* Reset CPU and GPIOs */
1411636258SStephen Warren SYSRESET_POWER, /* Reset PMIC (remove and restore power) */
1511636258SStephen Warren
1611636258SStephen Warren SYSRESET_COUNT,
1711636258SStephen Warren };
1811636258SStephen Warren
1911636258SStephen Warren struct sysreset_ops {
2011636258SStephen Warren /**
2111636258SStephen Warren * request() - request a sysreset of the given type
2211636258SStephen Warren *
2311636258SStephen Warren * Note that this function may return before the reset takes effect.
2411636258SStephen Warren *
2511636258SStephen Warren * @type: Reset type to request
2611636258SStephen Warren * @return -EINPROGRESS if the reset has been started and
2711636258SStephen Warren * will complete soon, -EPROTONOSUPPORT if not supported
2811636258SStephen Warren * by this device, 0 if the reset has already happened
2911636258SStephen Warren * (in which case this method will not actually return)
3011636258SStephen Warren */
3111636258SStephen Warren int (*request)(struct udevice *dev, enum sysreset_t type);
32bcb84b5dSJoseph Chen
33bcb84b5dSJoseph Chen /**
34bcb84b5dSJoseph Chen * request_by_mode() - request a sysreset of the given mode
35bcb84b5dSJoseph Chen *
36bcb84b5dSJoseph Chen * Note that this function may return before the reset takes effect.
37bcb84b5dSJoseph Chen *
38bcb84b5dSJoseph Chen * @mode: mode to request
39bcb84b5dSJoseph Chen * @return -EINPROGRESS if the reset has been started and
40bcb84b5dSJoseph Chen * will complete soon, -EPROTONOSUPPORT if not supported
41bcb84b5dSJoseph Chen * by this device, 0 if the reset has already happened
42bcb84b5dSJoseph Chen * (in which case this method will not actually return)
43bcb84b5dSJoseph Chen */
44bcb84b5dSJoseph Chen int (*request_by_mode)(struct udevice *dev, const char *mode);
4511636258SStephen Warren };
4611636258SStephen Warren
4711636258SStephen Warren #define sysreset_get_ops(dev) ((struct sysreset_ops *)(dev)->driver->ops)
4811636258SStephen Warren
49*07a474c7SJoseph Chen #ifdef CONFIG_SYSRESET
5011636258SStephen Warren /**
5111636258SStephen Warren * sysreset_request() - request a sysreset
5211636258SStephen Warren *
5311636258SStephen Warren * @type: Reset type to request
5411636258SStephen Warren * @return 0 if OK, -EPROTONOSUPPORT if not supported by this device
5511636258SStephen Warren */
5611636258SStephen Warren int sysreset_request(struct udevice *dev, enum sysreset_t type);
5711636258SStephen Warren
5811636258SStephen Warren /**
5911636258SStephen Warren * sysreset_walk() - cause a system reset
6011636258SStephen Warren *
6111636258SStephen Warren * This works through the available sysreset devices until it finds one that can
6211636258SStephen Warren * perform a reset. If the provided sysreset type is not available, the next one
6311636258SStephen Warren * will be tried.
6411636258SStephen Warren *
6511636258SStephen Warren * If this function fails to reset, it will display a message and halt
6611636258SStephen Warren *
6711636258SStephen Warren * @type: Reset type to request
6811636258SStephen Warren * @return -EINPROGRESS if a reset is in progress, -ENOSYS if not available
6911636258SStephen Warren */
7011636258SStephen Warren int sysreset_walk(enum sysreset_t type);
7111636258SStephen Warren
7211636258SStephen Warren /**
7311636258SStephen Warren * sysreset_walk_halt() - try to reset, otherwise halt
7411636258SStephen Warren *
7511636258SStephen Warren * This calls sysreset_walk(). If it returns, indicating that reset is not
7611636258SStephen Warren * supported, it prints a message and halts.
7711636258SStephen Warren */
7811636258SStephen Warren void sysreset_walk_halt(enum sysreset_t type);
7911636258SStephen Warren
8011636258SStephen Warren /**
8111636258SStephen Warren * reset_cpu() - calls sysreset_walk(SYSRESET_WARM)
8211636258SStephen Warren */
8311636258SStephen Warren void reset_cpu(ulong addr);
8411636258SStephen Warren
85bcb84b5dSJoseph Chen /**
86bcb84b5dSJoseph Chen * reboot() - calls sysreset_walk(SYSRESET_WARM)
87bcb84b5dSJoseph Chen *
88bcb84b5dSJoseph Chen * Support the command like: reboot loader/bootloader/recovery, etc.
89bcb84b5dSJoseph Chen */
90bcb84b5dSJoseph Chen void reboot(const char *mode);
91bcb84b5dSJoseph Chen
92*07a474c7SJoseph Chen #else
93*07a474c7SJoseph Chen #include <asm/io.h>
94*07a474c7SJoseph Chen
reset_cpu(ulong addr)95*07a474c7SJoseph Chen inline void reset_cpu(ulong addr)
96*07a474c7SJoseph Chen {
97*07a474c7SJoseph Chen writel(CONFIG_SYSRESET_VAL, CONFIG_SYSRESET_REG);
98*07a474c7SJoseph Chen dsb();
99*07a474c7SJoseph Chen isb();
100*07a474c7SJoseph Chen
101*07a474c7SJoseph Chen while (1)
102*07a474c7SJoseph Chen ;
103*07a474c7SJoseph Chen }
104*07a474c7SJoseph Chen #endif
105*07a474c7SJoseph Chen
10611636258SStephen Warren #endif
107