1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (c) 2015 Google, Inc 4 * Written by Simon Glass <sjg@chromium.org> 5 */ 6 7 #include <common.h> 8 #include <dm.h> 9 #include <errno.h> 10 #include <sysreset.h> 11 #include <asm/state.h> 12 #include <asm/test.h> 13 14 static int sandbox_warm_sysreset_request(struct udevice *dev, 15 enum sysreset_t type) 16 { 17 struct sandbox_state *state = state_get_current(); 18 19 switch (type) { 20 case SYSRESET_WARM: 21 state->last_sysreset = type; 22 break; 23 default: 24 return -ENOSYS; 25 } 26 if (!state->sysreset_allowed[type]) 27 return -EACCES; 28 29 return -EINPROGRESS; 30 } 31 32 int sandbox_warm_sysreset_get_status(struct udevice *dev, char *buf, int size) 33 { 34 strlcpy(buf, "Reset Status: WARM", size); 35 36 return 0; 37 } 38 39 int sandbox_warm_sysreset_get_last(struct udevice *dev) 40 { 41 return SYSRESET_WARM; 42 } 43 44 static int sandbox_sysreset_request(struct udevice *dev, enum sysreset_t type) 45 { 46 struct sandbox_state *state = state_get_current(); 47 48 /* 49 * If we have a device tree, the device we created from platform data 50 * (see the U_BOOT_DEVICE() declaration below) should not do anything. 51 * If we are that device, return an error. 52 */ 53 if (state->fdt_fname && !dev_of_valid(dev)) 54 return -ENODEV; 55 56 switch (type) { 57 case SYSRESET_COLD: 58 state->last_sysreset = type; 59 break; 60 case SYSRESET_POWER: 61 state->last_sysreset = type; 62 if (!state->sysreset_allowed[type]) 63 return -EACCES; 64 sandbox_exit(); 65 break; 66 case SYSRESET_POWER_OFF: 67 if (!state->sysreset_allowed[type]) 68 return -EACCES; 69 default: 70 return -ENOSYS; 71 } 72 if (!state->sysreset_allowed[type]) 73 return -EACCES; 74 75 return -EINPROGRESS; 76 } 77 78 int sandbox_sysreset_get_status(struct udevice *dev, char *buf, int size) 79 { 80 strlcpy(buf, "Reset Status: COLD", size); 81 82 return 0; 83 } 84 85 int sandbox_sysreset_get_last(struct udevice *dev) 86 { 87 struct sandbox_state *state = state_get_current(); 88 89 /* 90 * The first phase is a power reset, after that we assume we don't 91 * know. 92 */ 93 return state->jumped_fname ? SYSRESET_WARM : SYSRESET_POWER; 94 } 95 96 static struct sysreset_ops sandbox_sysreset_ops = { 97 .request = sandbox_sysreset_request, 98 .get_status = sandbox_sysreset_get_status, 99 .get_last = sandbox_sysreset_get_last, 100 }; 101 102 static const struct udevice_id sandbox_sysreset_ids[] = { 103 { .compatible = "sandbox,reset" }, 104 { } 105 }; 106 107 U_BOOT_DRIVER(sysreset_sandbox) = { 108 .name = "sysreset_sandbox", 109 .id = UCLASS_SYSRESET, 110 .of_match = sandbox_sysreset_ids, 111 .ops = &sandbox_sysreset_ops, 112 }; 113 114 static struct sysreset_ops sandbox_warm_sysreset_ops = { 115 .request = sandbox_warm_sysreset_request, 116 .get_status = sandbox_warm_sysreset_get_status, 117 .get_last = sandbox_warm_sysreset_get_last, 118 }; 119 120 static const struct udevice_id sandbox_warm_sysreset_ids[] = { 121 { .compatible = "sandbox,warm-reset" }, 122 { } 123 }; 124 125 U_BOOT_DRIVER(warm_sysreset_sandbox) = { 126 .name = "warm_sysreset_sandbox", 127 .id = UCLASS_SYSRESET, 128 .of_match = sandbox_warm_sysreset_ids, 129 .ops = &sandbox_warm_sysreset_ops, 130 }; 131 132 /* This is here in case we don't have a device tree */ 133 U_BOOT_DEVICE(sysreset_sandbox_non_fdt) = { 134 .name = "sysreset_sandbox", 135 }; 136