]> Git Repo - linux.git/commitdiff
Merge tag 'timers-urgent-2020-07-25' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <[email protected]>
Sat, 25 Jul 2020 20:27:12 +0000 (13:27 -0700)
committerLinus Torvalds <[email protected]>
Sat, 25 Jul 2020 20:27:12 +0000 (13:27 -0700)
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

1  2 
drivers/bus/ti-sysc.c

diff --combined drivers/bus/ti-sysc.c
index 4f513fa3362f0e9bbbc549722e7c9418e5ed3712,c6427d0bc94c98104ed9244362b59dc7eabc4817..191c97b84715f4e06ba0597f4efffb2ef4cd9cd5
@@@ -236,14 -236,15 +236,14 @@@ static int sysc_wait_softreset(struct s
                syss_done = ddata->cfg.syss_mask;
  
        if (syss_offset >= 0) {
 -              error = readx_poll_timeout(sysc_read_sysstatus, ddata, rstval,
 -                                         (rstval & ddata->cfg.syss_mask) ==
 -                                         syss_done,
 -                                         100, MAX_MODULE_SOFTRESET_WAIT);
 +              error = readx_poll_timeout_atomic(sysc_read_sysstatus, ddata,
 +                              rstval, (rstval & ddata->cfg.syss_mask) ==
 +                              syss_done, 100, MAX_MODULE_SOFTRESET_WAIT);
  
        } else if (ddata->cfg.quirks & SYSC_QUIRK_RESET_STATUS) {
 -              error = readx_poll_timeout(sysc_read_sysconfig, ddata, rstval,
 -                                         !(rstval & sysc_mask),
 -                                         100, MAX_MODULE_SOFTRESET_WAIT);
 +              error = readx_poll_timeout_atomic(sysc_read_sysconfig, ddata,
 +                              rstval, !(rstval & sysc_mask),
 +                              100, MAX_MODULE_SOFTRESET_WAIT);
        }
  
        return error;
@@@ -1278,8 -1279,7 +1278,8 @@@ static int __maybe_unused sysc_noirq_su
  
        ddata = dev_get_drvdata(dev);
  
 -      if (ddata->cfg.quirks & SYSC_QUIRK_LEGACY_IDLE)
 +      if (ddata->cfg.quirks &
 +          (SYSC_QUIRK_LEGACY_IDLE | SYSC_QUIRK_NO_IDLE))
                return 0;
  
        return pm_runtime_force_suspend(dev);
@@@ -1291,8 -1291,7 +1291,8 @@@ static int __maybe_unused sysc_noirq_re
  
        ddata = dev_get_drvdata(dev);
  
 -      if (ddata->cfg.quirks & SYSC_QUIRK_LEGACY_IDLE)
 +      if (ddata->cfg.quirks &
 +          (SYSC_QUIRK_LEGACY_IDLE | SYSC_QUIRK_NO_IDLE))
                return 0;
  
        return pm_runtime_force_resume(dev);
@@@ -1729,8 -1728,8 +1729,8 @@@ static void sysc_quirk_rtc(struct sysc 
  
        local_irq_save(flags);
        /* RTC_STATUS BUSY bit may stay active for 1/32768 seconds (~30 usec) */
 -      error = readl_poll_timeout(ddata->module_va + 0x44, val,
 -                                 !(val & BIT(0)), 100, 50);
 +      error = readl_poll_timeout_atomic(ddata->module_va + 0x44, val,
 +                                        !(val & BIT(0)), 100, 50);
        if (error)
                dev_warn(ddata->dev, "rtc busy timeout\n");
        /* Now we have ~15 microseconds to read/write various registers */
@@@ -2865,6 -2864,24 +2865,24 @@@ static int sysc_check_disabled_devices(
        return error;
  }
  
+ /*
+  * Ignore timers tagged with no-reset and no-idle. These are likely in use,
+  * for example by drivers/clocksource/timer-ti-dm-systimer.c. If more checks
+  * are needed, we could also look at the timer register configuration.
+  */
+ static int sysc_check_active_timer(struct sysc *ddata)
+ {
+       if (ddata->cap->type != TI_SYSC_OMAP2_TIMER &&
+           ddata->cap->type != TI_SYSC_OMAP4_TIMER)
+               return 0;
+       if ((ddata->cfg.quirks & SYSC_QUIRK_NO_RESET_ON_INIT) &&
+           (ddata->cfg.quirks & SYSC_QUIRK_NO_IDLE))
+               return -EBUSY;
+       return 0;
+ }
  static const struct of_device_id sysc_match_table[] = {
        { .compatible = "simple-bus", },
        { /* sentinel */ },
@@@ -2921,6 -2938,10 +2939,10 @@@ static int sysc_probe(struct platform_d
        if (error)
                return error;
  
+       error = sysc_check_active_timer(ddata);
+       if (error)
+               return error;
        error = sysc_get_clocks(ddata);
        if (error)
                return error;
This page took 0.072842 seconds and 4 git commands to generate.