/* SPDX-License-Identifier: BSD-2-Clause */ /* * Copyright 2019 Broadcom. */ #ifndef DRIVERS_WDT_H #define DRIVERS_WDT_H #include #include #include #include #include struct wdt_chip { const struct wdt_ops *ops; struct itr_handler *wdt_itr; }; /* * struct wdt_ops - The watchdog device operations * * @init: The routine to initialized the watchdog resources. * @start: The routine for starting the watchdog device. * @stop: The routine for stopping the watchdog device. * @ping: The routine that sends a keepalive ping to the watchdog device. * @set_timeout:The routine that finds the load value that will reset system in * required timeout (in seconds). * * The wdt_ops structure contains a list of low-level operations * that control a watchdog device. */ struct wdt_ops { TEE_Result (*init)(struct wdt_chip *chip, unsigned long *min_timeout, unsigned long *max_timeout); void (*start)(struct wdt_chip *chip); void (*stop)(struct wdt_chip *chip); void (*ping)(struct wdt_chip *chip); TEE_Result (*set_timeout)(struct wdt_chip *chip, unsigned long timeout); }; #ifdef CFG_WDT extern struct wdt_chip *wdt_chip; /* Register a watchdog as the system watchdog */ TEE_Result watchdog_register(struct wdt_chip *chip); static inline TEE_Result watchdog_init(unsigned long *min_timeout, unsigned long *max_timeout) { if (!wdt_chip) return TEE_ERROR_NOT_SUPPORTED; if (!wdt_chip->ops->init) return TEE_SUCCESS; return wdt_chip->ops->init(wdt_chip, min_timeout, max_timeout); } static inline void watchdog_start(void) { if (wdt_chip) wdt_chip->ops->start(wdt_chip); } static inline void watchdog_stop(void) { if (wdt_chip && wdt_chip->ops->stop) wdt_chip->ops->stop(wdt_chip); } static inline void watchdog_ping(void) { if (wdt_chip) wdt_chip->ops->ping(wdt_chip); } static inline void watchdog_settimeout(unsigned long timeout) { if (wdt_chip) wdt_chip->ops->set_timeout(wdt_chip, timeout); } #else static inline TEE_Result watchdog_register(struct wdt_chip *chip __unused) { return TEE_ERROR_NOT_SUPPORTED; } static inline TEE_Result watchdog_init(unsigned long *min_timeout __unused, unsigned long *max_timeout __unused) { return TEE_ERROR_NOT_SUPPORTED; } static inline void watchdog_start(void) {} static inline void watchdog_stop(void) {} static inline void watchdog_ping(void) {} static inline void watchdog_settimeout(unsigned long timeout __unused) {} #endif #ifdef CFG_WDT_SM_HANDLER enum sm_handler_ret __wdt_sm_handler(struct thread_smc_args *args); static inline enum sm_handler_ret wdt_sm_handler(struct thread_smc_args *args) { if (args->a0 != CFG_WDT_SM_HANDLER_ID) return SM_HANDLER_PENDING_SMC; return __wdt_sm_handler(args); } #else static inline enum sm_handler_ret wdt_sm_handler(struct thread_smc_args *args __unused) { return SM_HANDLER_PENDING_SMC; } #endif #endif /* DRIVERS_WDT_H */