"Das U-Boot" Source Tree

Merge branch 'next' of https://source.denx.de/u-boot/custodians/u-boot-watchdog into next

- misc cyclic infrastructure improvements (Rasmus)
- watchdog_reset cleanup (Rasmus)

CI: https://dev.azure.com/sr0718/u-boot/_build/results?buildId=369&view=results

Tom Rini e242cd95 d8c213c9

+102 -321
-108
arch/m68k/cpu/mcf52x2/cpu.c
··· 108 108 return 0; 109 109 }; 110 110 111 - #if defined(CONFIG_WATCHDOG) 112 - void watchdog_reset(void) 113 - { 114 - mbar_writeShort(MCF_WTM_WSR, 0x5555); 115 - mbar_writeShort(MCF_WTM_WSR, 0xAAAA); 116 - } 117 - 118 - int watchdog_disable(void) 119 - { 120 - mbar_writeShort(MCF_WTM_WCR, 0); 121 - return (0); 122 - } 123 - 124 - int watchdog_init(void) 125 - { 126 - mbar_writeShort(MCF_WTM_WCR, MCF_WTM_WCR_EN); 127 - return (0); 128 - } 129 - #endif /* #ifdef CONFIG_WATCHDOG */ 130 - 131 111 #endif 132 112 133 113 #ifdef CONFIG_M5272 ··· 174 154 }; 175 155 #endif /* CONFIG_DISPLAY_CPUINFO */ 176 156 177 - #if defined(CONFIG_WATCHDOG) 178 - /* Called by macro WATCHDOG_RESET */ 179 - void watchdog_reset(void) 180 - { 181 - wdog_t *wdt = (wdog_t *)(MMAP_WDOG); 182 - 183 - out_be16(&wdt->wdog_wcr, 0); 184 - } 185 - 186 - int watchdog_disable(void) 187 - { 188 - wdog_t *wdt = (wdog_t *)(MMAP_WDOG); 189 - 190 - /* reset watchdog counter */ 191 - out_be16(&wdt->wdog_wcr, 0); 192 - /* disable watchdog interrupt */ 193 - out_be16(&wdt->wdog_wirr, 0); 194 - /* disable watchdog timer */ 195 - out_be16(&wdt->wdog_wrrr, 0); 196 - 197 - puts("WATCHDOG:disabled\n"); 198 - return (0); 199 - } 200 - 201 - int watchdog_init(void) 202 - { 203 - wdog_t *wdt = (wdog_t *)(MMAP_WDOG); 204 - 205 - /* disable watchdog interrupt */ 206 - out_be16(&wdt->wdog_wirr, 0); 207 - 208 - /* set timeout and enable watchdog */ 209 - out_be16(&wdt->wdog_wrrr, 210 - (CONFIG_WATCHDOG_TIMEOUT_MSECS * CONFIG_SYS_HZ) / (32768 * 1000) - 1); 211 - 212 - /* reset watchdog counter */ 213 - out_be16(&wdt->wdog_wcr, 0); 214 - 215 - puts("WATCHDOG:enabled\n"); 216 - return (0); 217 - } 218 - #endif /* #ifdef CONFIG_WATCHDOG */ 219 - 220 157 #endif /* #ifdef CONFIG_M5272 */ 221 158 222 159 #ifdef CONFIG_M5275 ··· 242 179 return 0; 243 180 }; 244 181 #endif /* CONFIG_DISPLAY_CPUINFO */ 245 - 246 - #if defined(CONFIG_WATCHDOG) 247 - /* Called by macro WATCHDOG_RESET */ 248 - void watchdog_reset(void) 249 - { 250 - wdog_t *wdt = (wdog_t *)(MMAP_WDOG); 251 - 252 - out_be16(&wdt->wsr, 0x5555); 253 - out_be16(&wdt->wsr, 0xaaaa); 254 - } 255 - 256 - int watchdog_disable(void) 257 - { 258 - wdog_t *wdt = (wdog_t *)(MMAP_WDOG); 259 - 260 - /* reset watchdog counter */ 261 - out_be16(&wdt->wsr, 0x5555); 262 - out_be16(&wdt->wsr, 0xaaaa); 263 - 264 - /* disable watchdog timer */ 265 - out_be16(&wdt->wcr, 0); 266 - 267 - puts("WATCHDOG:disabled\n"); 268 - return (0); 269 - } 270 - 271 - int watchdog_init(void) 272 - { 273 - wdog_t *wdt = (wdog_t *)(MMAP_WDOG); 274 - 275 - /* disable watchdog */ 276 - out_be16(&wdt->wcr, 0); 277 - 278 - /* set timeout and enable watchdog */ 279 - out_be16(&wdt->wmr, 280 - (CONFIG_WATCHDOG_TIMEOUT_MSECS * CONFIG_SYS_HZ) / (32768 * 1000) - 1); 281 - 282 - /* reset watchdog counter */ 283 - out_be16(&wdt->wsr, 0x5555); 284 - out_be16(&wdt->wsr, 0xaaaa); 285 - 286 - puts("WATCHDOG:enabled\n"); 287 - return (0); 288 - } 289 - #endif /* #ifdef CONFIG_WATCHDOG */ 290 182 291 183 #endif /* #ifdef CONFIG_M5275 */ 292 184
-15
arch/powerpc/cpu/mpc83xx/cpu.c
··· 164 164 } 165 165 #endif 166 166 167 - #if defined(CONFIG_WATCHDOG) && !defined(CONFIG_WDT) 168 - void watchdog_reset (void) 169 - { 170 - int re_enable = disable_interrupts(); 171 - 172 - /* Reset the 83xx watchdog */ 173 - volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR; 174 - immr->wdt.swsrr = 0x556c; 175 - immr->wdt.swsrr = 0xaa39; 176 - 177 - if (re_enable) 178 - enable_interrupts(); 179 - } 180 - #endif 181 - 182 167 /* 183 168 * Initializes on-chip MMC controllers. 184 169 * to override, implement board_mmc_init()
-31
arch/powerpc/cpu/mpc85xx/cpu.c
··· 349 349 } 350 350 351 351 352 - #ifndef CONFIG_WDT 353 - #if defined(CONFIG_WATCHDOG) 354 - #define WATCHDOG_MASK (TCR_WP(63) | TCR_WRC(3) | TCR_WIE) 355 - void 356 - init_85xx_watchdog(void) 357 - { 358 - mtspr(SPRN_TCR, (mfspr(SPRN_TCR) & ~WATCHDOG_MASK) | 359 - TCR_WP(CFG_WATCHDOG_PRESC) | TCR_WRC(CFG_WATCHDOG_RC)); 360 - } 361 - 362 - void 363 - reset_85xx_watchdog(void) 364 - { 365 - /* 366 - * Clear TSR(WIS) bit by writing 1 367 - */ 368 - mtspr(SPRN_TSR, TSR_WIS); 369 - } 370 - 371 - void 372 - watchdog_reset(void) 373 - { 374 - int re_enable = disable_interrupts(); 375 - 376 - reset_85xx_watchdog(); 377 - if (re_enable) 378 - enable_interrupts(); 379 - } 380 - #endif /* CONFIG_WATCHDOG */ 381 - #endif 382 - 383 352 /* 384 353 * Initializes on-chip MMC controllers. 385 354 * to override, implement board_mmc_init()
+1 -1
arch/sh/cpu/sh4/Makefile
··· 6 6 # (C) Copyright 2007 7 7 # Nobuhiro Iwamatsu <iwamatsu@nigauri.org> 8 8 9 - obj-y = cpu.o interrupts.o watchdog.o cache.o 9 + obj-y = cpu.o interrupts.o cache.o
+10
arch/sh/cpu/sh4/cpu.c
··· 10 10 #include <net.h> 11 11 #include <netdev.h> 12 12 #include <asm/processor.h> 13 + #include <asm/system.h> 14 + 15 + void reset_cpu(void) 16 + { 17 + /* Address error with SR.BL=1 first. */ 18 + trigger_address_error(); 19 + 20 + while (1) 21 + ; 22 + } 13 23 14 24 int checkcpu(void) 15 25 {
-60
arch/sh/cpu/sh4/watchdog.c
··· 1 - // SPDX-License-Identifier: GPL-2.0+ 2 - 3 - #include <cpu_func.h> 4 - #include <asm/processor.h> 5 - #include <asm/system.h> 6 - #include <asm/io.h> 7 - 8 - #define WDT_BASE WTCNT 9 - 10 - #define WDT_WD (1 << 6) 11 - #define WDT_RST_P (0) 12 - #define WDT_RST_M (1 << 5) 13 - #define WDT_ENABLE (1 << 7) 14 - 15 - #if defined(CONFIG_WATCHDOG) 16 - static unsigned char csr_read(void) 17 - { 18 - return inb(WDT_BASE + 0x04); 19 - } 20 - 21 - static void cnt_write(unsigned char value) 22 - { 23 - outl((unsigned short)value | 0x5A00, WDT_BASE + 0x00); 24 - } 25 - 26 - static void csr_write(unsigned char value) 27 - { 28 - outl((unsigned short)value | 0xA500, WDT_BASE + 0x04); 29 - } 30 - 31 - void watchdog_reset(void) 32 - { 33 - outl(0x55000000, WDT_BASE + 0x08); 34 - } 35 - 36 - int watchdog_init(void) 37 - { 38 - /* Set overflow time*/ 39 - cnt_write(0); 40 - /* Power on reset */ 41 - csr_write(WDT_WD|WDT_RST_P|WDT_ENABLE); 42 - 43 - return 0; 44 - } 45 - 46 - int watchdog_disable(void) 47 - { 48 - csr_write(csr_read() & ~WDT_ENABLE); 49 - return 0; 50 - } 51 - #endif 52 - 53 - void reset_cpu(void) 54 - { 55 - /* Address error with SR.BL=1 first. */ 56 - trigger_address_error(); 57 - 58 - while (1) 59 - ; 60 - }
+7 -4
board/Marvell/octeon_nic23/board.c
··· 249 249 * read the incorrect device ID 0x9700 (reset value) instead of 0x9702 250 250 * (restored value). 251 251 */ 252 - static void octeon_board_restore_pf(void *ctx) 252 + static void octeon_board_restore_pf(struct cyclic_info *c) 253 253 { 254 254 union cvmx_spemx_flr_pf_stopreq stopreq; 255 255 static bool start_initialized[2] = {false, false}; ··· 357 357 board_configure_qlms(); 358 358 359 359 /* Register cyclic function for PCIe FLR fixup */ 360 - cyclic = cyclic_register(octeon_board_restore_pf, 100, 361 - "pcie_flr_fix", NULL); 362 - if (!cyclic) 360 + cyclic = calloc(1, sizeof(*cyclic)); 361 + if (cyclic) { 362 + cyclic_register(cyclic, octeon_board_restore_pf, 100, 363 + "pcie_flr_fix"); 364 + } else { 363 365 printf("Registering of cyclic function failed\n"); 366 + } 364 367 365 368 return 0; 366 369 }
+5 -7
cmd/cyclic.c
··· 15 15 #include <time.h> 16 16 #include <vsprintf.h> 17 17 #include <linux/delay.h> 18 + #include <linux/kernel.h> 18 19 19 20 struct cyclic_demo_info { 21 + struct cyclic_info cyclic; 20 22 uint delay_us; 21 23 }; 22 24 23 - static void cyclic_demo(void *ctx) 25 + static void cyclic_demo(struct cyclic_info *c) 24 26 { 25 - struct cyclic_demo_info *info = ctx; 27 + struct cyclic_demo_info *info = container_of(c, struct cyclic_demo_info, cyclic); 26 28 27 29 /* Just a small dummy delay here */ 28 30 udelay(info->delay_us); ··· 32 34 char *const argv[]) 33 35 { 34 36 struct cyclic_demo_info *info; 35 - struct cyclic_info *cyclic; 36 37 uint time_ms; 37 38 38 39 if (argc < 3) ··· 48 49 info->delay_us = simple_strtoul(argv[2], NULL, 0); 49 50 50 51 /* Register demo cyclic function */ 51 - cyclic = cyclic_register(cyclic_demo, time_ms * 1000, "cyclic_demo", 52 - info); 53 - if (!cyclic) 54 - printf("Registering of cyclic_demo failed\n"); 52 + cyclic_register(&info->cyclic, cyclic_demo, time_ms * 1000, "cyclic_demo"); 55 53 56 54 printf("Registered function \"%s\" to be executed all %dms\n", 57 55 "cyclic_demo", time_ms);
+6 -18
common/cyclic.c
··· 26 26 return (struct hlist_head *)&gd->cyclic_list; 27 27 } 28 28 29 - struct cyclic_info *cyclic_register(cyclic_func_t func, uint64_t delay_us, 30 - const char *name, void *ctx) 29 + void cyclic_register(struct cyclic_info *cyclic, cyclic_func_t func, 30 + uint64_t delay_us, const char *name) 31 31 { 32 - struct cyclic_info *cyclic; 33 - 34 - cyclic = calloc(1, sizeof(struct cyclic_info)); 35 - if (!cyclic) { 36 - pr_debug("Memory allocation error\n"); 37 - return NULL; 38 - } 32 + memset(cyclic, 0, sizeof(*cyclic)); 39 33 40 34 /* Store values in struct */ 41 35 cyclic->func = func; 42 - cyclic->ctx = ctx; 43 - cyclic->name = strdup(name); 36 + cyclic->name = name; 44 37 cyclic->delay_us = delay_us; 45 38 cyclic->start_time_us = timer_get_us(); 46 39 hlist_add_head(&cyclic->list, cyclic_get_list()); 47 - 48 - return cyclic; 49 40 } 50 41 51 - int cyclic_unregister(struct cyclic_info *cyclic) 42 + void cyclic_unregister(struct cyclic_info *cyclic) 52 43 { 53 44 hlist_del(&cyclic->list); 54 - free(cyclic); 55 - 56 - return 0; 57 45 } 58 46 59 47 void cyclic_run(void) ··· 76 64 if (time_after_eq64(now, cyclic->next_call)) { 77 65 /* Call cyclic function and account it's cpu-time */ 78 66 cyclic->next_call = now + cyclic->delay_us; 79 - cyclic->func(cyclic->ctx); 67 + cyclic->func(cyclic); 80 68 cyclic->run_cnt++; 81 69 cpu_time = timer_get_us() - now; 82 70 cyclic->cpu_time_us += cpu_time;
+16 -10
doc/develop/cyclic.rst
··· 19 19 20 20 To register a cyclic function, use something like this:: 21 21 22 - static void cyclic_demo(void *ctx) 22 + struct donkey { 23 + struct cyclic_info cyclic; 24 + void (*say)(const char *s); 25 + }; 26 + 27 + static void cyclic_demo(struct cyclic_info *c) 23 28 { 24 - /* Just a small dummy delay here */ 25 - udelay(10); 29 + struct donkey *donkey = container_of(c, struct donkey, cyclic); 30 + 31 + donkey->say("Are we there yet?"); 26 32 } 27 - 28 - int board_init(void) 33 + 34 + int donkey_init(void) 29 35 { 30 - struct cyclic_info *cyclic; 31 - 36 + struct donkey *donkey; 37 + 38 + /* Initialize donkey ... */ 39 + 32 40 /* Register demo cyclic function */ 33 - cyclic = cyclic_register(cyclic_demo, 10 * 1000, "cyclic_demo", NULL); 34 - if (!cyclic) 35 - printf("Registering of cyclic_demo failed\n"); 41 + cyclic_register(&donkey->cyclic, cyclic_demo, 10 * 1000, "cyclic_demo"); 36 42 37 43 return 0; 38 44 }
+4 -4
drivers/serial/ns16550.c
··· 291 291 serial_out(c, &com_port->thr); 292 292 293 293 /* 294 - * Call watchdog_reset() upon newline. This is done here in putc 294 + * Call schedule() upon newline. This is done here in putc 295 295 * since the environment code uses a single puts() to print the complete 296 - * environment upon "printenv". So we can't put this watchdog call 296 + * environment upon "printenv". So we can't put this schedule call 297 297 * in puts(). 298 298 */ 299 299 if (c == '\n') ··· 390 390 serial_out(ch, &com_port->thr); 391 391 392 392 /* 393 - * Call watchdog_reset() upon newline. This is done here in putc 393 + * Call schedule() upon newline. This is done here in putc 394 394 * since the environment code uses a single puts() to print the complete 395 - * environment upon "printenv". So we can't put this watchdog call 395 + * environment upon "printenv". So we can't put this schedule call 396 396 * in puts(). 397 397 */ 398 398 if (ch == '\n')
+22 -35
drivers/watchdog/wdt-uclass.c
··· 17 17 #include <asm/global_data.h> 18 18 #include <dm/device-internal.h> 19 19 #include <dm/lists.h> 20 + #include <linux/kernel.h> 20 21 21 22 DECLARE_GLOBAL_DATA_PTR; 22 23 23 24 #define WATCHDOG_TIMEOUT_SECS (CONFIG_WATCHDOG_TIMEOUT_MSECS / 1000) 24 25 25 26 struct wdt_priv { 27 + /* The udevice owning this wdt_priv. */ 28 + struct udevice *dev; 26 29 /* Timeout, in seconds, to configure this device to. */ 27 30 u32 timeout; 28 31 /* 29 32 * Time, in milliseconds, between calling the device's ->reset() 30 - * method from watchdog_reset(). 33 + * method from schedule(). 31 34 */ 32 35 ulong reset_period; 33 36 /* ··· 40 43 /* autostart */ 41 44 bool autostart; 42 45 43 - struct cyclic_info *cyclic; 46 + struct cyclic_info cyclic; 44 47 }; 45 48 46 - static void wdt_cyclic(void *ctx) 49 + static void wdt_cyclic(struct cyclic_info *c) 47 50 { 48 - struct udevice *dev = ctx; 49 - struct wdt_priv *priv; 51 + struct wdt_priv *priv = container_of(c, struct wdt_priv, cyclic); 52 + struct udevice *dev = priv->dev; 50 53 51 54 if (!device_active(dev)) 52 55 return; 53 56 54 - priv = dev_get_uclass_priv(dev); 55 57 if (!priv->running) 56 58 return; 57 59 ··· 121 123 struct wdt_priv *priv = dev_get_uclass_priv(dev); 122 124 char str[16]; 123 125 124 - priv->running = true; 125 - 126 126 memset(str, 0, 16); 127 127 if (IS_ENABLED(CONFIG_WATCHDOG)) { 128 + if (priv->running) 129 + cyclic_unregister(&priv->cyclic); 130 + 128 131 /* Register the watchdog driver as a cyclic function */ 129 - priv->cyclic = cyclic_register(wdt_cyclic, 130 - priv->reset_period * 1000, 131 - dev->name, dev); 132 - if (!priv->cyclic) { 133 - printf("cyclic_register for %s failed\n", 134 - dev->name); 135 - return -ENODEV; 136 - } else { 137 - snprintf(str, 16, "every %ldms", 138 - priv->reset_period); 139 - } 132 + cyclic_register(&priv->cyclic, wdt_cyclic, 133 + priv->reset_period * 1000, 134 + dev->name); 135 + 136 + snprintf(str, 16, "every %ldms", priv->reset_period); 140 137 } 141 138 139 + priv->running = true; 142 140 printf("WDT: Started %s with%s servicing %s (%ds timeout)\n", 143 141 dev->name, IS_ENABLED(CONFIG_WATCHDOG) ? "" : "out", 144 142 str, (u32)lldiv(timeout_ms, 1000)); ··· 158 156 ret = ops->stop(dev); 159 157 if (ret == 0) { 160 158 struct wdt_priv *priv = dev_get_uclass_priv(dev); 159 + 160 + if (IS_ENABLED(CONFIG_WATCHDOG) && priv->running) 161 + cyclic_unregister(&priv->cyclic); 161 162 162 163 priv->running = false; 163 164 } ··· 221 222 return ret; 222 223 } 223 224 224 - #if defined(CONFIG_WATCHDOG) 225 - /* 226 - * Called by macro WATCHDOG_RESET. This function be called *very* early, 227 - * so we need to make sure, that the watchdog driver is ready before using 228 - * it in this function. 229 - */ 230 - void watchdog_reset(void) 231 - { 232 - /* 233 - * Empty function for now. The actual WDT handling is now done in 234 - * the cyclic function instead. 235 - */ 236 - } 237 - #endif 238 - 239 225 static int wdt_pre_probe(struct udevice *dev) 240 226 { 241 227 u32 timeout = WATCHDOG_TIMEOUT_SECS; ··· 257 243 autostart = true; 258 244 } 259 245 priv = dev_get_uclass_priv(dev); 246 + priv->dev = dev; 260 247 priv->timeout = timeout; 261 248 priv->reset_period = reset_period; 262 249 priv->autostart = autostart; 263 250 /* 264 251 * Pretend this device was last reset "long" ago so the first 265 - * watchdog_reset will actually call its ->reset method. 252 + * schedule() will actually call its ->reset method. 266 253 */ 267 254 priv->next_reset = get_timer(0); 268 255
+19 -18
include/cyclic.h
··· 18 18 * struct cyclic_info - Information about cyclic execution function 19 19 * 20 20 * @func: Function to call periodically 21 - * @ctx: Context pointer to get passed to this function 22 21 * @name: Name of the cyclic function, e.g. shown in the commands 23 22 * @delay_ns: Delay is ns after which this function shall get executed 24 23 * @start_time_us: Start time in us, when this function started its execution ··· 27 26 * @next_call: Next time in us, when the function shall be executed again 28 27 * @list: List node 29 28 * @already_warned: Flag that we've warned about exceeding CPU time usage 29 + * 30 + * When !CONFIG_CYCLIC, this struct is empty. 30 31 */ 31 32 struct cyclic_info { 32 - void (*func)(void *ctx); 33 - void *ctx; 34 - char *name; 33 + #if defined(CONFIG_CYCLIC) 34 + void (*func)(struct cyclic_info *c); 35 + const char *name; 35 36 uint64_t delay_us; 36 37 uint64_t start_time_us; 37 38 uint64_t cpu_time_us; ··· 39 40 uint64_t next_call; 40 41 struct hlist_node list; 41 42 bool already_warned; 43 + #endif 42 44 }; 43 45 44 46 /** Function type for cyclic functions */ 45 - typedef void (*cyclic_func_t)(void *ctx); 47 + typedef void (*cyclic_func_t)(struct cyclic_info *c); 46 48 47 49 #if defined(CONFIG_CYCLIC) 48 50 /** 49 51 * cyclic_register - Register a new cyclic function 50 52 * 53 + * @cyclic: Cyclic info structure 51 54 * @func: Function to call periodically 52 55 * @delay_us: Delay is us after which this function shall get executed 53 56 * @name: Cyclic function name/id 54 - * @ctx: Context to pass to the function 55 - * @return: pointer to cyclic_struct if OK, NULL on error 57 + * 58 + * The function @func will be called with @cyclic as its 59 + * argument. @cyclic will usually be embedded in some device-specific 60 + * structure, which the callback can retrieve using container_of(). 56 61 */ 57 - struct cyclic_info *cyclic_register(cyclic_func_t func, uint64_t delay_us, 58 - const char *name, void *ctx); 62 + void cyclic_register(struct cyclic_info *cyclic, cyclic_func_t func, 63 + uint64_t delay_us, const char *name); 59 64 60 65 /** 61 66 * cyclic_unregister - Unregister a cyclic function 62 67 * 63 68 * @cyclic: Pointer to cyclic_struct of the function that shall be removed 64 - * @return: 0 if OK, -ve on error 65 69 */ 66 - int cyclic_unregister(struct cyclic_info *cyclic); 70 + void cyclic_unregister(struct cyclic_info *cyclic); 67 71 68 72 /** 69 73 * cyclic_unregister_all() - Clean up cyclic functions ··· 97 101 */ 98 102 void schedule(void); 99 103 #else 100 - static inline struct cyclic_info *cyclic_register(cyclic_func_t func, 101 - uint64_t delay_us, 102 - const char *name, 103 - void *ctx) 104 + 105 + static inline void cyclic_register(struct cyclic_info *cyclic, cyclic_func_t func, 106 + uint64_t delay_us, const char *name) 104 107 { 105 - return NULL; 106 108 } 107 109 108 - static inline int cyclic_unregister(struct cyclic_info *cyclic) 110 + static inline void cyclic_unregister(struct cyclic_info *cyclic) 109 111 { 110 - return 0; 111 112 } 112 113 113 114 static inline void cyclic_run(void)
-3
include/watchdog.h
··· 40 40 void hw_watchdog_init(void); 41 41 #endif 42 42 43 - #if defined(CONFIG_MPC85xx) 44 - void init_85xx_watchdog(void); 45 - #endif 46 43 #endif /* _WATCHDOG_H_ */
+12 -7
test/common/cyclic.c
··· 12 12 #include <linux/delay.h> 13 13 14 14 /* Test that cyclic function is called */ 15 - static bool cyclic_active = false; 15 + static struct cyclic_test { 16 + struct cyclic_info cyclic; 17 + bool called; 18 + } cyclic_test; 16 19 17 - static void cyclic_test(void *ctx) 20 + static void test_cb(struct cyclic_info *c) 18 21 { 19 - cyclic_active = true; 22 + struct cyclic_test *t = container_of(c, struct cyclic_test, cyclic); 23 + t->called = true; 20 24 } 21 25 22 26 static int dm_test_cyclic_running(struct unit_test_state *uts) 23 27 { 24 - cyclic_active = false; 25 - ut_assertnonnull(cyclic_register(cyclic_test, 10 * 1000, "cyclic_demo", 26 - NULL)); 28 + cyclic_test.called = false; 29 + cyclic_register(&cyclic_test.cyclic, test_cb, 10 * 1000, "cyclic_test"); 27 30 28 31 /* Execute all registered cyclic functions */ 29 32 schedule(); 30 - ut_asserteq(true, cyclic_active); 33 + ut_asserteq(true, cyclic_test.called); 34 + 35 + cyclic_unregister(&cyclic_test.cyclic); 31 36 32 37 return 0; 33 38 }