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 return SYSRESET_COLD; 88 } 89 90 static struct sysreset_ops sandbox_sysreset_ops = { 91 .request = sandbox_sysreset_request, 92 .get_status = sandbox_sysreset_get_status, 93 .get_last = sandbox_sysreset_get_last, 94 }; 95 96 static const struct udevice_id sandbox_sysreset_ids[] = { 97 { .compatible = "sandbox,reset" }, 98 { } 99 }; 100 101 U_BOOT_DRIVER(sysreset_sandbox) = { 102 .name = "sysreset_sandbox", 103 .id = UCLASS_SYSRESET, 104 .of_match = sandbox_sysreset_ids, 105 .ops = &sandbox_sysreset_ops, 106 }; 107 108 static struct sysreset_ops sandbox_warm_sysreset_ops = { 109 .request = sandbox_warm_sysreset_request, 110 .get_status = sandbox_warm_sysreset_get_status, 111 .get_last = sandbox_warm_sysreset_get_last, 112 }; 113 114 static const struct udevice_id sandbox_warm_sysreset_ids[] = { 115 { .compatible = "sandbox,warm-reset" }, 116 { } 117 }; 118 119 U_BOOT_DRIVER(warm_sysreset_sandbox) = { 120 .name = "warm_sysreset_sandbox", 121 .id = UCLASS_SYSRESET, 122 .of_match = sandbox_warm_sysreset_ids, 123 .ops = &sandbox_warm_sysreset_ops, 124 }; 125 126 /* This is here in case we don't have a device tree */ 127 U_BOOT_DEVICE(sysreset_sandbox_non_fdt) = { 128 .name = "sysreset_sandbox", 129 }; 130