1 /* SPDX-License-Identifier: BSD-2-Clause */ 2 /* 3 * Copyright 2019 Broadcom. 4 */ 5 6 #ifndef DRIVERS_WDT_H 7 #define DRIVERS_WDT_H 8 9 #include <assert.h> 10 #include <kernel/interrupt.h> 11 #include <kernel/thread.h> 12 #include <sm/sm.h> 13 #include <tee_api_types.h> 14 15 struct wdt_chip { 16 const struct wdt_ops *ops; 17 struct itr_handler *wdt_itr; 18 }; 19 20 /* 21 * struct wdt_ops - The watchdog device operations 22 * 23 * @init: The routine to initialized the watchdog resources. 24 * @start: The routine for starting the watchdog device. 25 * @stop: The routine for stopping the watchdog device. 26 * @ping: The routine that sends a keepalive ping to the watchdog device. 27 * @set_timeout:The routine that finds the load value that will reset system in 28 * required timeout (in seconds). 29 * 30 * The wdt_ops structure contains a list of low-level operations 31 * that control a watchdog device. 32 */ 33 struct wdt_ops { 34 TEE_Result (*init)(struct wdt_chip *chip, unsigned long *min_timeout, 35 unsigned long *max_timeout); 36 void (*start)(struct wdt_chip *chip); 37 void (*stop)(struct wdt_chip *chip); 38 void (*ping)(struct wdt_chip *chip); 39 TEE_Result (*set_timeout)(struct wdt_chip *chip, unsigned long timeout); 40 }; 41 42 #ifdef CFG_WDT 43 extern struct wdt_chip *wdt_chip; 44 45 /* Register a watchdog as the system watchdog */ 46 TEE_Result watchdog_register(struct wdt_chip *chip); 47 48 static inline 49 TEE_Result watchdog_init(unsigned long *min_timeout, unsigned long *max_timeout) 50 { 51 if (!wdt_chip) 52 return TEE_ERROR_NOT_SUPPORTED; 53 54 if (!wdt_chip->ops->init) 55 return TEE_SUCCESS; 56 57 return wdt_chip->ops->init(wdt_chip, min_timeout, max_timeout); 58 } 59 60 static inline void watchdog_start(void) 61 { 62 if (wdt_chip) 63 wdt_chip->ops->start(wdt_chip); 64 } 65 66 static inline void watchdog_stop(void) 67 { 68 if (wdt_chip && wdt_chip->ops->stop) 69 wdt_chip->ops->stop(wdt_chip); 70 } 71 72 static inline void watchdog_ping(void) 73 { 74 if (wdt_chip) 75 wdt_chip->ops->ping(wdt_chip); 76 } 77 78 static inline void watchdog_settimeout(unsigned long timeout) 79 { 80 if (wdt_chip) 81 wdt_chip->ops->set_timeout(wdt_chip, timeout); 82 } 83 #else 84 static inline TEE_Result watchdog_register(struct wdt_chip *chip __unused) 85 { 86 return TEE_ERROR_NOT_SUPPORTED; 87 } 88 89 static inline TEE_Result watchdog_init(unsigned long *min_timeout __unused, 90 unsigned long *max_timeout __unused) 91 { 92 return TEE_ERROR_NOT_SUPPORTED; 93 } 94 95 static inline void watchdog_start(void) {} 96 static inline void watchdog_stop(void) {} 97 static inline void watchdog_ping(void) {} 98 static inline void watchdog_settimeout(unsigned long timeout __unused) {} 99 #endif 100 101 #ifdef CFG_WDT_SM_HANDLER 102 enum sm_handler_ret __wdt_sm_handler(struct thread_smc_args *args); 103 104 static inline 105 enum sm_handler_ret wdt_sm_handler(struct thread_smc_args *args) 106 { 107 if (args->a0 != CFG_WDT_SM_HANDLER_ID) 108 return SM_HANDLER_PENDING_SMC; 109 110 return __wdt_sm_handler(args); 111 } 112 #else 113 static inline 114 enum sm_handler_ret wdt_sm_handler(struct thread_smc_args *args __unused) 115 { 116 return SM_HANDLER_PENDING_SMC; 117 } 118 #endif 119 120 #endif /* DRIVERS_WDT_H */ 121