This change removes watchdog self-pinging behavior.
The timer irq handler is triggered due to the 1st expiration,
the handler disables and enables watchdog but also implicitly
clears the expiration count so the count can only be 0 or 1.
Since this watchdog supports opened, configured, or pinged by
systemd, We remove this behavior or the watchdog may not bark
when systemd crashes since the 5th expiration never comes.
Signed-off-by: Pohsun Su <[email protected]>
---
drivers/clocksource/timer-tegra186.c | 24 ++----------------------
1 file changed, 2 insertions(+), 22 deletions(-)
diff --git a/drivers/clocksource/timer-tegra186.c b/drivers/clocksource/timer-tegra186.c
index 685c6689a2da..963c12c81f4d 100644
--- a/drivers/clocksource/timer-tegra186.c
+++ b/drivers/clocksource/timer-tegra186.c
@@ -174,7 +174,8 @@ static void tegra186_wdt_enable(struct tegra186_wdt *wdt)
value |= WDTCR_PERIOD(1);
/* enable local interrupt for WDT petting */
- value |= WDTCR_LOCAL_INT_ENABLE;
+ if (0)
+ value |= WDTCR_LOCAL_INT_ENABLE;
/* enable local FIQ and remote interrupt for debug dump */
if (0)
@@ -406,18 +407,6 @@ static int tegra186_timer_usec_init(struct tegra186_timer *tegra)
return clocksource_register_hz(&tegra->usec, USEC_PER_SEC);
}
-static irqreturn_t tegra186_timer_irq(int irq, void *data)
-{
- struct tegra186_timer *tegra = data;
-
- if (watchdog_active(&tegra->wdt->base)) {
- tegra186_wdt_disable(tegra->wdt);
- tegra186_wdt_enable(tegra->wdt);
- }
-
- return IRQ_HANDLED;
-}
-
static int tegra186_timer_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@@ -469,17 +458,8 @@ static int tegra186_timer_probe(struct platform_device *pdev)
goto unregister_osc;
}
- err = devm_request_irq(dev, irq, tegra186_timer_irq, 0,
- "tegra186-timer", tegra);
- if (err < 0) {
- dev_err(dev, "failed to request IRQ#%u: %d\n", irq, err);
- goto unregister_usec;
- }
-
return 0;
-unregister_usec:
- clocksource_unregister(&tegra->usec);
unregister_osc:
clocksource_unregister(&tegra->osc);
unregister_tsc:
--
2.17.1
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/[email protected]/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/[email protected]/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 <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/
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