Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'timers-urgent-2020-07-25' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip into master

Pull timer fix from Ingo Molnar:
"Fix a suspend/resume regression (crash) on TI AM3/AM4 SoC's"

* tag 'timers-urgent-2020-07-25' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
clocksource/drivers/timer-ti-dm: Fix suspend and resume for am3 and am4

+58 -10
+22
drivers/bus/ti-sysc.c
··· 2865 2865 return error; 2866 2866 } 2867 2867 2868 + /* 2869 + * Ignore timers tagged with no-reset and no-idle. These are likely in use, 2870 + * for example by drivers/clocksource/timer-ti-dm-systimer.c. If more checks 2871 + * are needed, we could also look at the timer register configuration. 2872 + */ 2873 + static int sysc_check_active_timer(struct sysc *ddata) 2874 + { 2875 + if (ddata->cap->type != TI_SYSC_OMAP2_TIMER && 2876 + ddata->cap->type != TI_SYSC_OMAP4_TIMER) 2877 + return 0; 2878 + 2879 + if ((ddata->cfg.quirks & SYSC_QUIRK_NO_RESET_ON_INIT) && 2880 + (ddata->cfg.quirks & SYSC_QUIRK_NO_IDLE)) 2881 + return -EBUSY; 2882 + 2883 + return 0; 2884 + } 2885 + 2868 2886 static const struct of_device_id sysc_match_table[] = { 2869 2887 { .compatible = "simple-bus", }, 2870 2888 { /* sentinel */ }, ··· 2936 2918 sysc_init_early_quirks(ddata); 2937 2919 2938 2920 error = sysc_check_disabled_devices(ddata); 2921 + if (error) 2922 + return error; 2923 + 2924 + error = sysc_check_active_timer(ddata); 2939 2925 if (error) 2940 2926 return error; 2941 2927
+36 -10
drivers/clocksource/timer-ti-dm-systimer.c
··· 19 19 /* For type1, set SYSC_OMAP2_CLOCKACTIVITY for fck off on idle, l4 clock on */ 20 20 #define DMTIMER_TYPE1_ENABLE ((1 << 9) | (SYSC_IDLE_SMART << 3) | \ 21 21 SYSC_OMAP2_ENAWAKEUP | SYSC_OMAP2_AUTOIDLE) 22 - 22 + #define DMTIMER_TYPE1_DISABLE (SYSC_OMAP2_SOFTRESET | SYSC_OMAP2_AUTOIDLE) 23 23 #define DMTIMER_TYPE2_ENABLE (SYSC_IDLE_SMART_WKUP << 2) 24 24 #define DMTIMER_RESET_WAIT 100000 25 25 ··· 44 44 u8 ctrl; 45 45 u8 wakeup; 46 46 u8 ifctrl; 47 + struct clk *fck; 48 + struct clk *ick; 47 49 unsigned long rate; 48 50 }; 49 51 ··· 300 298 } 301 299 302 300 /* Interface clocks are only available on some SoCs variants */ 303 - static int __init dmtimer_systimer_init_clock(struct device_node *np, 301 + static int __init dmtimer_systimer_init_clock(struct dmtimer_systimer *t, 302 + struct device_node *np, 304 303 const char *name, 305 304 unsigned long *rate) 306 305 { 307 306 struct clk *clock; 308 307 unsigned long r; 308 + bool is_ick = false; 309 309 int error; 310 310 311 + is_ick = !strncmp(name, "ick", 3); 312 + 311 313 clock = of_clk_get_by_name(np, name); 312 - if ((PTR_ERR(clock) == -EINVAL) && !strncmp(name, "ick", 3)) 314 + if ((PTR_ERR(clock) == -EINVAL) && is_ick) 313 315 return 0; 314 316 else if (IS_ERR(clock)) 315 317 return PTR_ERR(clock); ··· 325 319 r = clk_get_rate(clock); 326 320 if (!r) 327 321 return -ENODEV; 322 + 323 + if (is_ick) 324 + t->ick = clock; 325 + else 326 + t->fck = clock; 328 327 329 328 *rate = r; 330 329 ··· 350 339 351 340 static void dmtimer_systimer_disable(struct dmtimer_systimer *t) 352 341 { 353 - writel_relaxed(0, t->base + t->sysc); 342 + if (!dmtimer_systimer_revision1(t)) 343 + return; 344 + 345 + writel_relaxed(DMTIMER_TYPE1_DISABLE, t->base + t->sysc); 354 346 } 355 347 356 348 static int __init dmtimer_systimer_setup(struct device_node *np, ··· 380 366 pr_err("%s: clock source init failed: %i\n", __func__, error); 381 367 382 368 /* For ti-sysc, we have timer clocks at the parent module level */ 383 - error = dmtimer_systimer_init_clock(np->parent, "fck", &rate); 369 + error = dmtimer_systimer_init_clock(t, np->parent, "fck", &rate); 384 370 if (error) 385 371 goto err_unmap; 386 372 387 373 t->rate = rate; 388 374 389 - error = dmtimer_systimer_init_clock(np->parent, "ick", &rate); 375 + error = dmtimer_systimer_init_clock(t, np->parent, "ick", &rate); 390 376 if (error) 391 377 goto err_unmap; 392 378 ··· 510 496 struct dmtimer_systimer *t = &clkevt->t; 511 497 512 498 dmtimer_systimer_disable(t); 499 + clk_disable(t->fck); 513 500 } 514 501 515 502 static void omap_clockevent_unidle(struct clock_event_device *evt) 516 503 { 517 504 struct dmtimer_clockevent *clkevt = to_dmtimer_clockevent(evt); 518 505 struct dmtimer_systimer *t = &clkevt->t; 506 + int error; 507 + 508 + error = clk_enable(t->fck); 509 + if (error) 510 + pr_err("could not enable timer fck on resume: %i\n", error); 519 511 520 512 dmtimer_systimer_enable(t); 521 513 writel_relaxed(OMAP_TIMER_INT_OVERFLOW, t->base + t->irq_ena); ··· 590 570 3, /* Timer internal resynch latency */ 591 571 0xffffffff); 592 572 593 - if (of_device_is_compatible(np, "ti,am33xx") || 594 - of_device_is_compatible(np, "ti,am43")) { 573 + if (of_machine_is_compatible("ti,am33xx") || 574 + of_machine_is_compatible("ti,am43")) { 595 575 dev->suspend = omap_clockevent_idle; 596 576 dev->resume = omap_clockevent_unidle; 597 577 } ··· 636 616 637 617 clksrc->loadval = readl_relaxed(t->base + t->counter); 638 618 dmtimer_systimer_disable(t); 619 + clk_disable(t->fck); 639 620 } 640 621 641 622 static void dmtimer_clocksource_resume(struct clocksource *cs) 642 623 { 643 624 struct dmtimer_clocksource *clksrc = to_dmtimer_clocksource(cs); 644 625 struct dmtimer_systimer *t = &clksrc->t; 626 + int error; 627 + 628 + error = clk_enable(t->fck); 629 + if (error) 630 + pr_err("could not enable timer fck on resume: %i\n", error); 645 631 646 632 dmtimer_systimer_enable(t); 647 633 writel_relaxed(clksrc->loadval, t->base + t->counter); ··· 679 653 dev->mask = CLOCKSOURCE_MASK(32); 680 654 dev->flags = CLOCK_SOURCE_IS_CONTINUOUS; 681 655 682 - if (of_device_is_compatible(np, "ti,am33xx") || 683 - of_device_is_compatible(np, "ti,am43")) { 656 + /* Unlike for clockevent, legacy code sets suspend only for am4 */ 657 + if (of_machine_is_compatible("ti,am43")) { 684 658 dev->suspend = dmtimer_clocksource_suspend; 685 659 dev->resume = dmtimer_clocksource_resume; 686 660 }