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