linux/drivers/clocksource
Geert Uytterhoeven 54d46b7fbc clockevents/drivers/sh_cmt: Only perform clocksource suspend/resume if enabled
Currently the sh_cmt clocksource timer is disabled or enabled
unconditionally on clocksource suspend resp. resume, even if a
better clocksource is present (e.g. arch_sys_counter) and the
sh_cmt clocksource is not enabled.

As sh_cmt is a syscore device when its timer is enabled, this
may lead to a genpd.prepared_count imbalance in the presence of
PM Domains, which may cause a lock-up during reboot after s2ram.

During suspend:
  - pm_genpd_prepare() is called for all non-syscore devices (incl.
    sh_cmt), increasing genpd.prepared_count for each device,
  - clocksource.suspend() is called for all clocksource devices,
  - sh_cmt_clocksource_suspend() calls sh_cmt_stop(), which is a no-op
    as the clocksource was not enabled.

During resume:
  - clocksource.resume() is called for all clocksource devices,
  - sh_cmt_clocksource_resume() calls sh_cmt_start(), which enables the
    clocksource timer, and turns sh_cmt into a syscore device,
  - pm_genpd_complete() is called for all non-syscore devices (excl.
    sh_cmt now!), decreasing genpd.prepared_count for each device but
    sh_cmt.

Now genpd.prepared_count of the PM Domain containing sh_cmt is
still 1 instead of zero.  On subsequent suspend/resume cycles,
sh_cmt is still a syscore device, hence it's skipped for
pm_genpd_{prepare,complete}(), keeping the imbalance of
genpd.prepared_count at 1.

During reboot:

  - platform_drv_shutdown() is called for any platform device that has
    a driver with a .shutdown() method (only rcar-dmac on R-Car Gen2),

  - platform_drv_shutdown() calls dev_pm_domain_detach(), which
    calls genpd_dev_pm_detach(),

  - genpd_dev_pm_detach() keeps calling pm_genpd_remove_device() until
    it doesn't return -EAGAIN[*],

  - If the device is part of the same PM Domain as sh_cmt,
    pm_genpd_remove_device() always fails with -EAGAIN due to
    genpd.prepared_count > 0.

  - Infinite loop in genpd_dev_pm_detach()[*].

[*] Commit 93af5e9354 ("PM / Domains: Avoid infinite loops in
    attach/detach code") already limited the number of loop iterations,
    avoiding the lock-up.

To fix this, only disable or enable the clocksource timer on
clocksource suspend resp. resume if the clocksource was enabled.

This was tested on r8a7791/koelsch with the CPG Clock Domain:

  - using arch_sys_counter as the clocksource, which is the default, and
    which showed the problem,

  - using sh_cmt as a clocksource ("echo ffca0000.timer > \
    /sys/devices/system/clocksource/clocksource0/current_clocksource"),
    which behaves the same as before.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/1438875126-12596-2-git-send-email-daniel.lezcano@linaro.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
2015-08-08 10:50:08 +02:00
..
acpi_pm.c treewide: Fix printks with 0x%# 2013-08-27 10:49:38 +02:00
arm_arch_timer.c Initial ACPI support for arm64: 2015-04-24 08:23:45 -07:00
arm_global_timer.c ARM: make it easier to check the CPU part number correctly 2014-07-18 12:29:02 +01:00
armv7m_systick.c clocksource/drivers/armv7m_systick: Add ARM System timer driver 2015-06-02 12:10:14 +02:00
asm9260_timer.c clocksource: asm9260: Fix of_io_request_and_map error check 2015-05-05 10:35:58 +02:00
bcm2835_timer.c clocksource: bcm2835: Switch to sched_clock_register() 2013-07-30 11:24:51 -07:00
bcm_kona_timer.c clocksource: kona: fix __iomem annotation 2015-01-05 14:43:36 +01:00
cadence_ttc_timer.c clocksource: cadence_ttc: Add support for 32bit mode 2014-09-29 01:59:09 +02:00
clksrc-dbx500-prcmu.c clocksource: dbx500-prcmu: Switch to sched_clock_register() 2013-07-30 11:24:52 -07:00
clksrc-of.c of: consolidate linker section OF match table declarations 2014-05-20 14:25:24 -05:00
clps711x-timer.c clocksource: clps711x: Add CLPS711X clocksource driver 2014-07-23 12:02:35 +02:00
cs5535-clockevt.c clocksource: misc drivers: Remove deprecated IRQF_DISABLED 2013-12-11 11:40:27 +01:00
dummy_timer.c time: Replace __get_cpu_var uses 2014-08-26 13:45:44 -04:00
dw_apb_timer_of.c clocksource/drivers/dw_apb_timers_of: Fix IO endianness causing time jumps 2015-03-31 09:15:57 +02:00
dw_apb_timer.c drivers: fix up obsolete cpu function usage. 2015-03-05 13:37:02 +10:30
em_sti.c clocksource: Rename __clocksource_updatefreq_*() to __clocksource_update_freq_*() 2015-03-13 08:07:08 +01:00
exynos_mct.c clocksource: exynos_mct: Avoid blocking calls in the cpu hotplug notifier 2015-06-26 21:53:01 +02:00
fsl_ftm_timer.c clocksource: Add Freescale FlexTimer Module (FTM) timer support 2014-05-23 10:12:04 +02:00
h8300_timer8.c h8300: fix typo. 2015-06-23 13:36:00 +09:00
h8300_timer16.c h8300: clocksource 2015-06-23 13:35:55 +09:00
h8300_tpu.c h8300: clocksource 2015-06-23 13:35:55 +09:00
i8253.c
Kconfig Merge branch 'for-linus' of git://ftp.arm.linux.org.uk/~rmk/linux-arm 2015-06-26 12:20:00 -07:00
Makefile Merge branch 'for-linus' of git://ftp.arm.linux.org.uk/~rmk/linux-arm 2015-06-26 12:20:00 -07:00
meson6_timer.c ARM: meson6: clocksource: Add Meson6 timer support 2014-09-29 01:50:05 +02:00
metag_generic.c drivers/clocksource: Replace __get_cpu_var used for address calculation 2014-08-26 13:45:46 -04:00
mips-gic-timer.c CLOCKSOURCE: mips-gic: Allow GIC clock to be specified in device-tree 2015-04-01 17:22:11 +02:00
mmio.c clocksource: Fix clocksource_mmio_readX_down 2014-05-23 09:19:40 +02:00
moxart_timer.c ARM: clocksource: moxart: Add bitops.h include 2013-08-01 01:13:34 +02:00
mtk_timer.c clocksource: mtk: Fix race conditions in probe code 2015-02-25 10:28:49 +01:00
mxs_timer.c clocksource: mxs_timer: Switch to sched_clock_register() 2013-07-30 11:24:52 -07:00
nomadik-mtu.c ARM: SoC DT updates for 3.14 2014-01-23 18:45:38 -08:00
pxa_timer.c clocksource: pxa: Fix section mismatch 2015-02-25 10:28:55 +01:00
qcom-timer.c clocksource/drivers/qcom: Remove dead code 2015-06-02 12:10:08 +02:00
rockchip_timer.c clockevents: rockchip: Add rockchip timer for rk3288 2015-01-29 14:02:13 +01:00
samsung_pwm_timer.c clocksource: misc drivers: Remove deprecated IRQF_DISABLED 2013-12-11 11:40:27 +01:00
scx200_hrt.c
sh_cmt.c clockevents/drivers/sh_cmt: Only perform clocksource suspend/resume if enabled 2015-08-08 10:50:08 +02:00
sh_mtu2.c clocksource: sh_mtu2: Add DT support 2014-07-04 15:50:29 +02:00
sh_tmu.c clocksource: Rename __clocksource_updatefreq_*() to __clocksource_update_freq_*() 2015-03-13 08:07:08 +01:00
sun4i_timer.c clocksource/drivers/sun4i-timer: Only register a sched_clock on sun4i and sun5i 2015-03-31 09:15:58 +02:00
tcb_clksrc.c clocksource: tcb_clksrc: Sanitize IRQ request 2014-09-29 01:50:05 +02:00
tegra20_timer.c ARM, clocksource/drivers: Provide read_boot_clock64() and read_persistent_clock64() and use them 2015-04-03 08:18:23 +02:00
time-armada-370-xp.c Merge branch 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip 2014-12-10 08:18:32 -08:00
time-efm32.c clocksource/drivers/efm32: Use CLOCK_EVT_FEAT_PERIODIC for defining features 2015-03-31 09:15:57 +02:00
time-lpc32xx.c clocksource/drivers/lpc32xx: Add the lpc32xx timer driver 2015-06-02 12:10:10 +02:00
time-orion.c clocksource: orion: Use atomic access for shared registers 2014-03-11 23:05:02 +01:00
timer-atlas7.c clocksource: marco: Rename marco to atlas7 2015-01-29 14:02:06 +01:00
timer-atmel-pit.c clocksource/drivers/at91: Fix IO endianness 2015-03-31 09:15:58 +02:00
timer-atmel-st.c clocksource: atmel-st: remove mach/hardware dependency 2015-03-16 17:03:07 +01:00
timer-digicolor.c clocksource: Driver for Conexant Digicolor SoC timer 2015-01-29 14:02:15 +01:00
timer-imx-gpt.c clocksource/imx: Define clocksource for mx27 2015-07-07 10:44:45 +02:00
timer-integrator-ap.c Merge branch 'for-linus' of git://ftp.arm.linux.org.uk/~rmk/linux-arm 2015-06-26 12:20:00 -07:00
timer-keystone.c clocksource: timer-keystone: Delete unnecessary variable 2014-03-11 23:05:00 +01:00
timer-prima2.c clocksource: sirf: Fix incorrect clock enable counter for timer 2014-07-23 12:02:34 +02:00
timer-sp804.c ARM: 8366/1: move Dual-Timer SP804 driver to drivers/clocksource 2015-06-02 09:58:18 +01:00
timer-sp.h ARM: 8366/1: move Dual-Timer SP804 driver to drivers/clocksource 2015-06-02 09:58:18 +01:00
timer-stm32.c clockevents/drivers/timer-stm32: Fix build warning spotted by kbuild test robot 2015-06-02 12:10:16 +02:00
timer-sun5i.c clocksource: sun5i: Fix of_io_request_and_map error check 2015-05-05 10:35:58 +02:00
timer-u300.c Merge branch 'for-linus' of git://ftp.arm.linux.org.uk/~rmk/linux-arm 2014-04-05 13:20:43 -07:00
versatile.c clocksource: versatile: Adapt for Versatile AB and PB boards 2015-01-29 14:02:16 +01:00
vf_pit_timer.c clocksource: vf_pit_timer: Support shutdown mode 2014-09-29 01:50:05 +02:00
vt8500_timer.c clocksource: vt8500: Remove deprecated IRQF_DISABLED 2013-12-11 11:40:28 +01:00
zevio-timer.c clocksource: nspire: Fix compiler warning 2014-04-29 15:06:43 +02:00