Hi Pohsun, kernel test robot noticed the following build warnings: [auto build test WARNING on tip/timers/core] [also build test WARNING on linus/master v6.7 next-20240119] [cannot apply to daniel-lezcano/clockevents/next] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Pohsun-Su/clocksource-drivers-timer-tegra186-add-WDIOC_GETTIMELEFT-support/20240116-200217 base: tip/timers/core patch link: https://lore.kernel.org/r/20240116115838.16544-3-pohsuns%40nvidia.com patch subject: [PATCH 2/2] clocksource/drivers/timer-tegra186: fix watchdog self-pinging. config: x86_64-allyesconfig (https://download.01.org/0day-ci/archive/20240121/202401212150.DUcfhGzx-lkp@xxxxxxxxx/config) compiler: ClangBuiltLinux clang version 17.0.6 (https://github.com/llvm/llvm-project 6009708b4367171ccdbf4b5905cb6a803753fe18) reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240121/202401212150.DUcfhGzx-lkp@xxxxxxxxx/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@xxxxxxxxx> | Closes: https://lore.kernel.org/oe-kbuild-all/202401212150.DUcfhGzx-lkp@xxxxxxxxx/ All warnings (new ones prefixed by >>): drivers/clocksource/timer-tegra186.c:264:15: error: call to undeclared function 'FIELD_GET'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration] 264 | expiration = FIELD_GET(WDTSR_CURRENT_EXPIRATION_COUNT, readl_relaxed(wdt->regs + WDTSR)); | ^ >> drivers/clocksource/timer-tegra186.c:414:15: warning: variable 'irq' set but not used [-Wunused-but-set-variable] 414 | unsigned int irq; | ^ 1 warning and 1 error generated. vim +/irq +414 drivers/clocksource/timer-tegra186.c 42cee19a9f839f Thierry Reding 2022-07-04 241 3d6bf45a82fb12 Pohsun Su 2024-01-16 242 static unsigned int tegra186_wdt_get_timeleft(struct watchdog_device *wdd) 3d6bf45a82fb12 Pohsun Su 2024-01-16 243 { 3d6bf45a82fb12 Pohsun Su 2024-01-16 244 struct tegra186_wdt *wdt = to_tegra186_wdt(wdd); 3d6bf45a82fb12 Pohsun Su 2024-01-16 245 u32 timeleft; 3d6bf45a82fb12 Pohsun Su 2024-01-16 246 u32 expiration; 3d6bf45a82fb12 Pohsun Su 2024-01-16 247 3d6bf45a82fb12 Pohsun Su 2024-01-16 248 if (!watchdog_active(&wdt->base)) { 3d6bf45a82fb12 Pohsun Su 2024-01-16 249 /* return zero if the watchdog timer is not activated. */ 3d6bf45a82fb12 Pohsun Su 2024-01-16 250 return 0; 3d6bf45a82fb12 Pohsun Su 2024-01-16 251 } 3d6bf45a82fb12 Pohsun Su 2024-01-16 252 3d6bf45a82fb12 Pohsun Su 2024-01-16 253 /* 3d6bf45a82fb12 Pohsun Su 2024-01-16 254 * System power-on reset occurs on the fifth expiration of the watchdog timer and so 3d6bf45a82fb12 Pohsun Su 2024-01-16 255 * when the watchdog timer is configured, the actual value programmed into the counter 3d6bf45a82fb12 Pohsun Su 2024-01-16 256 * is 1/5 of the timeout value. Once the counter reaches 0, expiration count will be 3d6bf45a82fb12 Pohsun Su 2024-01-16 257 * increased by 1 and the down counter restarts. 3d6bf45a82fb12 Pohsun Su 2024-01-16 258 * Hence to get the time left before system reset we must combine 2 parts: 3d6bf45a82fb12 Pohsun Su 2024-01-16 259 * 1. value of the current down counter 3d6bf45a82fb12 Pohsun Su 2024-01-16 260 * 2. (number of counter expirations remaining) * (timeout/5) 3d6bf45a82fb12 Pohsun Su 2024-01-16 261 */ 3d6bf45a82fb12 Pohsun Su 2024-01-16 262 3d6bf45a82fb12 Pohsun Su 2024-01-16 263 /* Get the current number of counter expirations. Should be a value between 0 and 4. */ 3d6bf45a82fb12 Pohsun Su 2024-01-16 @264 expiration = FIELD_GET(WDTSR_CURRENT_EXPIRATION_COUNT, readl_relaxed(wdt->regs + WDTSR)); 3d6bf45a82fb12 Pohsun Su 2024-01-16 265 3d6bf45a82fb12 Pohsun Su 2024-01-16 266 /* Convert the current counter value to seconds, rounding up to the nearest second. */ 3d6bf45a82fb12 Pohsun Su 2024-01-16 267 timeleft = FIELD_GET(TMRSR_PCV, readl_relaxed(wdt->tmr->regs + TMRSR)); 3d6bf45a82fb12 Pohsun Su 2024-01-16 268 timeleft = (timeleft + USEC_PER_SEC / 2) / USEC_PER_SEC; 3d6bf45a82fb12 Pohsun Su 2024-01-16 269 3d6bf45a82fb12 Pohsun Su 2024-01-16 270 /* 3d6bf45a82fb12 Pohsun Su 2024-01-16 271 * Calculate the time remaining by adding the time for the counter value 3d6bf45a82fb12 Pohsun Su 2024-01-16 272 * to the time of the counter expirations that remain. 3d6bf45a82fb12 Pohsun Su 2024-01-16 273 */ 3d6bf45a82fb12 Pohsun Su 2024-01-16 274 timeleft += wdt->base.timeout * (4 - expiration) / 5; 3d6bf45a82fb12 Pohsun Su 2024-01-16 275 return timeleft; 3d6bf45a82fb12 Pohsun Su 2024-01-16 276 } 3d6bf45a82fb12 Pohsun Su 2024-01-16 277 42cee19a9f839f Thierry Reding 2022-07-04 278 static const struct watchdog_ops tegra186_wdt_ops = { 42cee19a9f839f Thierry Reding 2022-07-04 279 .owner = THIS_MODULE, 42cee19a9f839f Thierry Reding 2022-07-04 280 .start = tegra186_wdt_start, 42cee19a9f839f Thierry Reding 2022-07-04 281 .stop = tegra186_wdt_stop, 42cee19a9f839f Thierry Reding 2022-07-04 282 .ping = tegra186_wdt_ping, 42cee19a9f839f Thierry Reding 2022-07-04 283 .set_timeout = tegra186_wdt_set_timeout, 3d6bf45a82fb12 Pohsun Su 2024-01-16 284 .get_timeleft = tegra186_wdt_get_timeleft, 42cee19a9f839f Thierry Reding 2022-07-04 285 }; 42cee19a9f839f Thierry Reding 2022-07-04 286 42cee19a9f839f Thierry Reding 2022-07-04 287 static struct tegra186_wdt *tegra186_wdt_create(struct tegra186_timer *tegra, 42cee19a9f839f Thierry Reding 2022-07-04 288 unsigned int index) 42cee19a9f839f Thierry Reding 2022-07-04 289 { 42cee19a9f839f Thierry Reding 2022-07-04 290 unsigned int offset = 0x10000, source; 42cee19a9f839f Thierry Reding 2022-07-04 291 struct tegra186_wdt *wdt; 42cee19a9f839f Thierry Reding 2022-07-04 292 u32 value; 42cee19a9f839f Thierry Reding 2022-07-04 293 int err; 42cee19a9f839f Thierry Reding 2022-07-04 294 42cee19a9f839f Thierry Reding 2022-07-04 295 offset += tegra->soc->num_timers * 0x10000 + index * 0x10000; 42cee19a9f839f Thierry Reding 2022-07-04 296 42cee19a9f839f Thierry Reding 2022-07-04 297 wdt = devm_kzalloc(tegra->dev, sizeof(*wdt), GFP_KERNEL); 42cee19a9f839f Thierry Reding 2022-07-04 298 if (!wdt) 42cee19a9f839f Thierry Reding 2022-07-04 299 return ERR_PTR(-ENOMEM); 42cee19a9f839f Thierry Reding 2022-07-04 300 42cee19a9f839f Thierry Reding 2022-07-04 301 wdt->regs = tegra->regs + offset; 42cee19a9f839f Thierry Reding 2022-07-04 302 wdt->index = index; 42cee19a9f839f Thierry Reding 2022-07-04 303 42cee19a9f839f Thierry Reding 2022-07-04 304 /* read the watchdog configuration since it might be locked down */ 42cee19a9f839f Thierry Reding 2022-07-04 305 value = wdt_readl(wdt, WDTCR); 42cee19a9f839f Thierry Reding 2022-07-04 306 42cee19a9f839f Thierry Reding 2022-07-04 307 if (value & WDTCR_LOCAL_INT_ENABLE) 42cee19a9f839f Thierry Reding 2022-07-04 308 wdt->locked = true; 42cee19a9f839f Thierry Reding 2022-07-04 309 42cee19a9f839f Thierry Reding 2022-07-04 310 source = value & WDTCR_TIMER_SOURCE_MASK; 42cee19a9f839f Thierry Reding 2022-07-04 311 42cee19a9f839f Thierry Reding 2022-07-04 312 wdt->tmr = tegra186_tmr_create(tegra, source); 42cee19a9f839f Thierry Reding 2022-07-04 313 if (IS_ERR(wdt->tmr)) 42cee19a9f839f Thierry Reding 2022-07-04 314 return ERR_CAST(wdt->tmr); 42cee19a9f839f Thierry Reding 2022-07-04 315 42cee19a9f839f Thierry Reding 2022-07-04 316 wdt->base.info = &tegra186_wdt_info; 42cee19a9f839f Thierry Reding 2022-07-04 317 wdt->base.ops = &tegra186_wdt_ops; 42cee19a9f839f Thierry Reding 2022-07-04 318 wdt->base.min_timeout = 1; 42cee19a9f839f Thierry Reding 2022-07-04 319 wdt->base.max_timeout = 255; 42cee19a9f839f Thierry Reding 2022-07-04 320 wdt->base.parent = tegra->dev; 42cee19a9f839f Thierry Reding 2022-07-04 321 42cee19a9f839f Thierry Reding 2022-07-04 322 err = watchdog_init_timeout(&wdt->base, 5, tegra->dev); 42cee19a9f839f Thierry Reding 2022-07-04 323 if (err < 0) { 42cee19a9f839f Thierry Reding 2022-07-04 324 dev_err(tegra->dev, "failed to initialize timeout: %d\n", err); 42cee19a9f839f Thierry Reding 2022-07-04 325 return ERR_PTR(err); 42cee19a9f839f Thierry Reding 2022-07-04 326 } 42cee19a9f839f Thierry Reding 2022-07-04 327 42cee19a9f839f Thierry Reding 2022-07-04 328 err = devm_watchdog_register_device(tegra->dev, &wdt->base); 42cee19a9f839f Thierry Reding 2022-07-04 329 if (err < 0) { 42cee19a9f839f Thierry Reding 2022-07-04 330 dev_err(tegra->dev, "failed to register WDT: %d\n", err); 42cee19a9f839f Thierry Reding 2022-07-04 331 return ERR_PTR(err); 42cee19a9f839f Thierry Reding 2022-07-04 332 } 42cee19a9f839f Thierry Reding 2022-07-04 333 42cee19a9f839f Thierry Reding 2022-07-04 334 return wdt; 42cee19a9f839f Thierry Reding 2022-07-04 335 } 42cee19a9f839f Thierry Reding 2022-07-04 336 42cee19a9f839f Thierry Reding 2022-07-04 337 static u64 tegra186_timer_tsc_read(struct clocksource *cs) 42cee19a9f839f Thierry Reding 2022-07-04 338 { 42cee19a9f839f Thierry Reding 2022-07-04 339 struct tegra186_timer *tegra = container_of(cs, struct tegra186_timer, 42cee19a9f839f Thierry Reding 2022-07-04 340 tsc); 42cee19a9f839f Thierry Reding 2022-07-04 341 u32 hi, lo, ss; 42cee19a9f839f Thierry Reding 2022-07-04 342 42cee19a9f839f Thierry Reding 2022-07-04 343 hi = readl_relaxed(tegra->regs + TKETSC1); 42cee19a9f839f Thierry Reding 2022-07-04 344 42cee19a9f839f Thierry Reding 2022-07-04 345 /* 42cee19a9f839f Thierry Reding 2022-07-04 346 * The 56-bit value of the TSC is spread across two registers that are 42cee19a9f839f Thierry Reding 2022-07-04 347 * not synchronized. In order to read them atomically, ensure that the 42cee19a9f839f Thierry Reding 2022-07-04 348 * high 24 bits match before and after reading the low 32 bits. 42cee19a9f839f Thierry Reding 2022-07-04 349 */ 42cee19a9f839f Thierry Reding 2022-07-04 350 do { 42cee19a9f839f Thierry Reding 2022-07-04 351 /* snapshot the high 24 bits */ 42cee19a9f839f Thierry Reding 2022-07-04 352 ss = hi; 42cee19a9f839f Thierry Reding 2022-07-04 353 42cee19a9f839f Thierry Reding 2022-07-04 354 lo = readl_relaxed(tegra->regs + TKETSC0); 42cee19a9f839f Thierry Reding 2022-07-04 355 hi = readl_relaxed(tegra->regs + TKETSC1); 42cee19a9f839f Thierry Reding 2022-07-04 356 } while (hi != ss); 42cee19a9f839f Thierry Reding 2022-07-04 357 42cee19a9f839f Thierry Reding 2022-07-04 358 return (u64)hi << 32 | lo; 42cee19a9f839f Thierry Reding 2022-07-04 359 } 42cee19a9f839f Thierry Reding 2022-07-04 360 42cee19a9f839f Thierry Reding 2022-07-04 361 static int tegra186_timer_tsc_init(struct tegra186_timer *tegra) 42cee19a9f839f Thierry Reding 2022-07-04 362 { 42cee19a9f839f Thierry Reding 2022-07-04 363 tegra->tsc.name = "tsc"; 42cee19a9f839f Thierry Reding 2022-07-04 364 tegra->tsc.rating = 300; 42cee19a9f839f Thierry Reding 2022-07-04 365 tegra->tsc.read = tegra186_timer_tsc_read; 42cee19a9f839f Thierry Reding 2022-07-04 366 tegra->tsc.mask = CLOCKSOURCE_MASK(56); 42cee19a9f839f Thierry Reding 2022-07-04 367 tegra->tsc.flags = CLOCK_SOURCE_IS_CONTINUOUS; 42cee19a9f839f Thierry Reding 2022-07-04 368 42cee19a9f839f Thierry Reding 2022-07-04 369 return clocksource_register_hz(&tegra->tsc, 31250000); 42cee19a9f839f Thierry Reding 2022-07-04 370 } 42cee19a9f839f Thierry Reding 2022-07-04 371 42cee19a9f839f Thierry Reding 2022-07-04 372 static u64 tegra186_timer_osc_read(struct clocksource *cs) 42cee19a9f839f Thierry Reding 2022-07-04 373 { 42cee19a9f839f Thierry Reding 2022-07-04 374 struct tegra186_timer *tegra = container_of(cs, struct tegra186_timer, 42cee19a9f839f Thierry Reding 2022-07-04 375 osc); 42cee19a9f839f Thierry Reding 2022-07-04 376 42cee19a9f839f Thierry Reding 2022-07-04 377 return readl_relaxed(tegra->regs + TKEOSC); 42cee19a9f839f Thierry Reding 2022-07-04 378 } 42cee19a9f839f Thierry Reding 2022-07-04 379 42cee19a9f839f Thierry Reding 2022-07-04 380 static int tegra186_timer_osc_init(struct tegra186_timer *tegra) 42cee19a9f839f Thierry Reding 2022-07-04 381 { 42cee19a9f839f Thierry Reding 2022-07-04 382 tegra->osc.name = "osc"; 42cee19a9f839f Thierry Reding 2022-07-04 383 tegra->osc.rating = 300; 42cee19a9f839f Thierry Reding 2022-07-04 384 tegra->osc.read = tegra186_timer_osc_read; 42cee19a9f839f Thierry Reding 2022-07-04 385 tegra->osc.mask = CLOCKSOURCE_MASK(32); 42cee19a9f839f Thierry Reding 2022-07-04 386 tegra->osc.flags = CLOCK_SOURCE_IS_CONTINUOUS; 42cee19a9f839f Thierry Reding 2022-07-04 387 42cee19a9f839f Thierry Reding 2022-07-04 388 return clocksource_register_hz(&tegra->osc, 38400000); 42cee19a9f839f Thierry Reding 2022-07-04 389 } 42cee19a9f839f Thierry Reding 2022-07-04 390 42cee19a9f839f Thierry Reding 2022-07-04 391 static u64 tegra186_timer_usec_read(struct clocksource *cs) 42cee19a9f839f Thierry Reding 2022-07-04 392 { 42cee19a9f839f Thierry Reding 2022-07-04 393 struct tegra186_timer *tegra = container_of(cs, struct tegra186_timer, 42cee19a9f839f Thierry Reding 2022-07-04 394 usec); 42cee19a9f839f Thierry Reding 2022-07-04 395 42cee19a9f839f Thierry Reding 2022-07-04 396 return readl_relaxed(tegra->regs + TKEUSEC); 42cee19a9f839f Thierry Reding 2022-07-04 397 } 42cee19a9f839f Thierry Reding 2022-07-04 398 42cee19a9f839f Thierry Reding 2022-07-04 399 static int tegra186_timer_usec_init(struct tegra186_timer *tegra) 42cee19a9f839f Thierry Reding 2022-07-04 400 { 42cee19a9f839f Thierry Reding 2022-07-04 401 tegra->usec.name = "usec"; 42cee19a9f839f Thierry Reding 2022-07-04 402 tegra->usec.rating = 300; 42cee19a9f839f Thierry Reding 2022-07-04 403 tegra->usec.read = tegra186_timer_usec_read; 42cee19a9f839f Thierry Reding 2022-07-04 404 tegra->usec.mask = CLOCKSOURCE_MASK(32); 42cee19a9f839f Thierry Reding 2022-07-04 405 tegra->usec.flags = CLOCK_SOURCE_IS_CONTINUOUS; 42cee19a9f839f Thierry Reding 2022-07-04 406 42cee19a9f839f Thierry Reding 2022-07-04 407 return clocksource_register_hz(&tegra->usec, USEC_PER_SEC); 42cee19a9f839f Thierry Reding 2022-07-04 408 } 42cee19a9f839f Thierry Reding 2022-07-04 409 42cee19a9f839f Thierry Reding 2022-07-04 410 static int tegra186_timer_probe(struct platform_device *pdev) 42cee19a9f839f Thierry Reding 2022-07-04 411 { 42cee19a9f839f Thierry Reding 2022-07-04 412 struct device *dev = &pdev->dev; 42cee19a9f839f Thierry Reding 2022-07-04 413 struct tegra186_timer *tegra; 42cee19a9f839f Thierry Reding 2022-07-04 @414 unsigned int irq; 42cee19a9f839f Thierry Reding 2022-07-04 415 int err; 42cee19a9f839f Thierry Reding 2022-07-04 416 42cee19a9f839f Thierry Reding 2022-07-04 417 tegra = devm_kzalloc(dev, sizeof(*tegra), GFP_KERNEL); 42cee19a9f839f Thierry Reding 2022-07-04 418 if (!tegra) 42cee19a9f839f Thierry Reding 2022-07-04 419 return -ENOMEM; 42cee19a9f839f Thierry Reding 2022-07-04 420 42cee19a9f839f Thierry Reding 2022-07-04 421 tegra->soc = of_device_get_match_data(dev); 42cee19a9f839f Thierry Reding 2022-07-04 422 dev_set_drvdata(dev, tegra); 42cee19a9f839f Thierry Reding 2022-07-04 423 tegra->dev = dev; 42cee19a9f839f Thierry Reding 2022-07-04 424 42cee19a9f839f Thierry Reding 2022-07-04 425 tegra->regs = devm_platform_ioremap_resource(pdev, 0); 42cee19a9f839f Thierry Reding 2022-07-04 426 if (IS_ERR(tegra->regs)) 42cee19a9f839f Thierry Reding 2022-07-04 427 return PTR_ERR(tegra->regs); 42cee19a9f839f Thierry Reding 2022-07-04 428 42cee19a9f839f Thierry Reding 2022-07-04 429 err = platform_get_irq(pdev, 0); 42cee19a9f839f Thierry Reding 2022-07-04 430 if (err < 0) 42cee19a9f839f Thierry Reding 2022-07-04 431 return err; 42cee19a9f839f Thierry Reding 2022-07-04 432 42cee19a9f839f Thierry Reding 2022-07-04 433 irq = err; 42cee19a9f839f Thierry Reding 2022-07-04 434 42cee19a9f839f Thierry Reding 2022-07-04 435 /* create a watchdog using a preconfigured timer */ 42cee19a9f839f Thierry Reding 2022-07-04 436 tegra->wdt = tegra186_wdt_create(tegra, 0); 42cee19a9f839f Thierry Reding 2022-07-04 437 if (IS_ERR(tegra->wdt)) { 42cee19a9f839f Thierry Reding 2022-07-04 438 err = PTR_ERR(tegra->wdt); 42cee19a9f839f Thierry Reding 2022-07-04 439 dev_err(dev, "failed to create WDT: %d\n", err); 42cee19a9f839f Thierry Reding 2022-07-04 440 return err; 42cee19a9f839f Thierry Reding 2022-07-04 441 } 42cee19a9f839f Thierry Reding 2022-07-04 442 42cee19a9f839f Thierry Reding 2022-07-04 443 err = tegra186_timer_tsc_init(tegra); 42cee19a9f839f Thierry Reding 2022-07-04 444 if (err < 0) { 42cee19a9f839f Thierry Reding 2022-07-04 445 dev_err(dev, "failed to register TSC counter: %d\n", err); 42cee19a9f839f Thierry Reding 2022-07-04 446 return err; 42cee19a9f839f Thierry Reding 2022-07-04 447 } 42cee19a9f839f Thierry Reding 2022-07-04 448 42cee19a9f839f Thierry Reding 2022-07-04 449 err = tegra186_timer_osc_init(tegra); 42cee19a9f839f Thierry Reding 2022-07-04 450 if (err < 0) { 42cee19a9f839f Thierry Reding 2022-07-04 451 dev_err(dev, "failed to register OSC counter: %d\n", err); 42cee19a9f839f Thierry Reding 2022-07-04 452 goto unregister_tsc; 42cee19a9f839f Thierry Reding 2022-07-04 453 } 42cee19a9f839f Thierry Reding 2022-07-04 454 42cee19a9f839f Thierry Reding 2022-07-04 455 err = tegra186_timer_usec_init(tegra); 42cee19a9f839f Thierry Reding 2022-07-04 456 if (err < 0) { 42cee19a9f839f Thierry Reding 2022-07-04 457 dev_err(dev, "failed to register USEC counter: %d\n", err); 42cee19a9f839f Thierry Reding 2022-07-04 458 goto unregister_osc; 42cee19a9f839f Thierry Reding 2022-07-04 459 } 42cee19a9f839f Thierry Reding 2022-07-04 460 42cee19a9f839f Thierry Reding 2022-07-04 461 return 0; 42cee19a9f839f Thierry Reding 2022-07-04 462 42cee19a9f839f Thierry Reding 2022-07-04 463 unregister_osc: 42cee19a9f839f Thierry Reding 2022-07-04 464 clocksource_unregister(&tegra->osc); 42cee19a9f839f Thierry Reding 2022-07-04 465 unregister_tsc: 42cee19a9f839f Thierry Reding 2022-07-04 466 clocksource_unregister(&tegra->tsc); 42cee19a9f839f Thierry Reding 2022-07-04 467 return err; 42cee19a9f839f Thierry Reding 2022-07-04 468 } 42cee19a9f839f Thierry Reding 2022-07-04 469 -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki