1*b25732c2SMax Filippov /* 2*b25732c2SMax Filippov * Copyright (c) 2015 Google, Inc 3*b25732c2SMax Filippov * Written by Simon Glass <sjg@chromium.org> 4*b25732c2SMax Filippov * 5*b25732c2SMax Filippov * SPDX-License-Identifier: GPL-2.0+ 6*b25732c2SMax Filippov */ 7*b25732c2SMax Filippov 8*b25732c2SMax Filippov #include <common.h> 9*b25732c2SMax Filippov #include <dm.h> 10*b25732c2SMax Filippov #include <errno.h> 11*b25732c2SMax Filippov #include <sysreset.h> 12*b25732c2SMax Filippov #include <asm/state.h> 13*b25732c2SMax Filippov #include <asm/test.h> 14*b25732c2SMax Filippov 15*b25732c2SMax Filippov DECLARE_GLOBAL_DATA_PTR; 16*b25732c2SMax Filippov 17*b25732c2SMax Filippov static int sandbox_warm_sysreset_request(struct udevice *dev, 18*b25732c2SMax Filippov enum sysreset_t type) 19*b25732c2SMax Filippov { 20*b25732c2SMax Filippov struct sandbox_state *state = state_get_current(); 21*b25732c2SMax Filippov 22*b25732c2SMax Filippov switch (type) { 23*b25732c2SMax Filippov case SYSRESET_WARM: 24*b25732c2SMax Filippov state->last_sysreset = type; 25*b25732c2SMax Filippov break; 26*b25732c2SMax Filippov default: 27*b25732c2SMax Filippov return -ENOSYS; 28*b25732c2SMax Filippov } 29*b25732c2SMax Filippov if (!state->sysreset_allowed[type]) 30*b25732c2SMax Filippov return -EACCES; 31*b25732c2SMax Filippov 32*b25732c2SMax Filippov return -EINPROGRESS; 33*b25732c2SMax Filippov } 34*b25732c2SMax Filippov 35*b25732c2SMax Filippov static int sandbox_sysreset_request(struct udevice *dev, enum sysreset_t type) 36*b25732c2SMax Filippov { 37*b25732c2SMax Filippov struct sandbox_state *state = state_get_current(); 38*b25732c2SMax Filippov 39*b25732c2SMax Filippov /* 40*b25732c2SMax Filippov * If we have a device tree, the device we created from platform data 41*b25732c2SMax Filippov * (see the U_BOOT_DEVICE() declaration below) should not do anything. 42*b25732c2SMax Filippov * If we are that device, return an error. 43*b25732c2SMax Filippov */ 44*b25732c2SMax Filippov if (state->fdt_fname && dev->of_offset == -1) 45*b25732c2SMax Filippov return -ENODEV; 46*b25732c2SMax Filippov 47*b25732c2SMax Filippov switch (type) { 48*b25732c2SMax Filippov case SYSRESET_COLD: 49*b25732c2SMax Filippov state->last_sysreset = type; 50*b25732c2SMax Filippov break; 51*b25732c2SMax Filippov case SYSRESET_POWER: 52*b25732c2SMax Filippov state->last_sysreset = type; 53*b25732c2SMax Filippov if (!state->sysreset_allowed[type]) 54*b25732c2SMax Filippov return -EACCES; 55*b25732c2SMax Filippov sandbox_exit(); 56*b25732c2SMax Filippov break; 57*b25732c2SMax Filippov default: 58*b25732c2SMax Filippov return -ENOSYS; 59*b25732c2SMax Filippov } 60*b25732c2SMax Filippov if (!state->sysreset_allowed[type]) 61*b25732c2SMax Filippov return -EACCES; 62*b25732c2SMax Filippov 63*b25732c2SMax Filippov return -EINPROGRESS; 64*b25732c2SMax Filippov } 65*b25732c2SMax Filippov 66*b25732c2SMax Filippov static struct sysreset_ops sandbox_sysreset_ops = { 67*b25732c2SMax Filippov .request = sandbox_sysreset_request, 68*b25732c2SMax Filippov }; 69*b25732c2SMax Filippov 70*b25732c2SMax Filippov static const struct udevice_id sandbox_sysreset_ids[] = { 71*b25732c2SMax Filippov { .compatible = "sandbox,reset" }, 72*b25732c2SMax Filippov { } 73*b25732c2SMax Filippov }; 74*b25732c2SMax Filippov 75*b25732c2SMax Filippov U_BOOT_DRIVER(sysreset_sandbox) = { 76*b25732c2SMax Filippov .name = "sysreset_sandbox", 77*b25732c2SMax Filippov .id = UCLASS_SYSRESET, 78*b25732c2SMax Filippov .of_match = sandbox_sysreset_ids, 79*b25732c2SMax Filippov .ops = &sandbox_sysreset_ops, 80*b25732c2SMax Filippov }; 81*b25732c2SMax Filippov 82*b25732c2SMax Filippov static struct sysreset_ops sandbox_warm_sysreset_ops = { 83*b25732c2SMax Filippov .request = sandbox_warm_sysreset_request, 84*b25732c2SMax Filippov }; 85*b25732c2SMax Filippov 86*b25732c2SMax Filippov static const struct udevice_id sandbox_warm_sysreset_ids[] = { 87*b25732c2SMax Filippov { .compatible = "sandbox,warm-reset" }, 88*b25732c2SMax Filippov { } 89*b25732c2SMax Filippov }; 90*b25732c2SMax Filippov 91*b25732c2SMax Filippov U_BOOT_DRIVER(warm_sysreset_sandbox) = { 92*b25732c2SMax Filippov .name = "warm_sysreset_sandbox", 93*b25732c2SMax Filippov .id = UCLASS_SYSRESET, 94*b25732c2SMax Filippov .of_match = sandbox_warm_sysreset_ids, 95*b25732c2SMax Filippov .ops = &sandbox_warm_sysreset_ops, 96*b25732c2SMax Filippov }; 97*b25732c2SMax Filippov 98*b25732c2SMax Filippov /* This is here in case we don't have a device tree */ 99*b25732c2SMax Filippov U_BOOT_DEVICE(sysreset_sandbox_non_fdt) = { 100*b25732c2SMax Filippov .name = "sysreset_sandbox", 101*b25732c2SMax Filippov }; 102