xref: /optee_os/core/drivers/wdt/watchdog_sm.c (revision 731185b11620a6de1f824278ab3c166c7853ef66)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright 2022 Microchip
4  */
5 
6 #include <drivers/wdt.h>
7 #include <kernel/spinlock.h>
8 #include <sm/optee_smc.h>
9 #include <sm/psci.h>
10 #include <sm/watchdog_smc.h>
11 
12 static unsigned long wdt_min_timeout;
13 static unsigned long wdt_max_timeout;
14 /* Lock for timeout variables */
15 static unsigned int wdt_lock = SPINLOCK_UNLOCK;
16 
17 enum sm_handler_ret __wdt_sm_handler(struct thread_smc_args *args)
18 {
19 	TEE_Result res = TEE_ERROR_GENERIC;
20 	uint32_t exceptions = 0;
21 	unsigned long min_timeout = 0;
22 	unsigned long max_timeout = 0;
23 
24 	switch (args->a1) {
25 	case SMCWD_INIT:
26 		exceptions = cpu_spin_lock_xsave(&wdt_lock);
27 		res = watchdog_init(&wdt_min_timeout, &wdt_max_timeout);
28 		cpu_spin_unlock_xrestore(&wdt_lock, exceptions);
29 
30 		if (res) {
31 			args->a0 = PSCI_RET_INTERNAL_FAILURE;
32 		} else {
33 			args->a0 = PSCI_RET_SUCCESS;
34 			args->a1 = wdt_min_timeout;
35 			args->a2 = wdt_max_timeout;
36 		}
37 		break;
38 	case SMCWD_SET_TIMEOUT:
39 		exceptions = cpu_spin_lock_xsave(&wdt_lock);
40 		min_timeout = wdt_min_timeout;
41 		max_timeout = wdt_max_timeout;
42 		cpu_spin_unlock_xrestore(&wdt_lock, exceptions);
43 
44 		if (args->a2 < min_timeout || args->a2 > max_timeout) {
45 			args->a0 = PSCI_RET_INVALID_PARAMETERS;
46 			break;
47 		}
48 
49 		watchdog_settimeout(args->a2);
50 		args->a0 = PSCI_RET_SUCCESS;
51 		break;
52 	case SMCWD_ENABLE:
53 		if (args->a2 == 0) {
54 			watchdog_stop();
55 			args->a0 = PSCI_RET_SUCCESS;
56 		} else if (args->a2 == 1) {
57 			watchdog_start();
58 			args->a0 = PSCI_RET_SUCCESS;
59 		} else {
60 			args->a0 = PSCI_RET_INVALID_PARAMETERS;
61 		}
62 		break;
63 	case SMCWD_PET:
64 		watchdog_ping();
65 		args->a0 = PSCI_RET_SUCCESS;
66 		break;
67 	/* SMCWD_GET_TIMELEFT is optional */
68 	case SMCWD_GET_TIMELEFT:
69 	default:
70 		args->a0 = PSCI_RET_NOT_SUPPORTED;
71 	}
72 
73 	return SM_HANDLER_SMC_HANDLED;
74 }
75