PM: clk: make PM clock layer compatible with clocks that must sleep
authorNicolas Pitre <npitre@baylibre.com>
Mon, 25 Jan 2021 19:29:18 +0000 (14:29 -0500)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Wed, 27 Jan 2021 18:29:32 +0000 (19:29 +0100)
commit0bfa0820c274b019583b3454c6c889c99c24558d
tree8d899f423a9cd330f987d7c894c50335b58116f5
parent6ee1d745b7c9fd573fba142a2efdad76a9f1cb04
PM: clk: make PM clock layer compatible with clocks that must sleep

The clock API splits its interface into sleepable ant atomic contexts:

 - clk_prepare/clk_unprepare for stuff that might sleep

 - clk_enable_clk_disable for anything that may be done in atomic context

The code handling runtime PM for clocks only calls clk_disable() on
suspend requests, and clk_enable on resume requests. This means that
runtime PM with clock providers that only have the prepare/unprepare
methods implemented is basically useless.

Many clock implementations can't accommodate atomic contexts. This is
often the case when communication with the clock happens through another
subsystem like I2C or SCMI.

Let's make the clock PM code useful with such clocks by safely invoking
clk_prepare/clk_unprepare upon resume/suspend requests. Of course, when
such clocks are registered with the PM layer then pm_runtime_irq_safe()
can't be used, and neither pm_runtime_suspend() nor pm_runtime_resume()
may be invoked in atomic context.

For clocks that do implement the enable and disable methods then
everything just works as before.

A note on sparse:
According to https://lwn.net/Articles/109066/ there are things
that sparse can't cope with. In particular, pm_clk_op_lock() and
pm_clk_op_unlock() may or may not lock/unlock psd->lock depending on
some runtime condition. To work around that we tell it the lock is
always untaken for the purpose of static analisys.

Thanks to Naresh Kamboju for reporting issues with the initial patch.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
Tested-by: Naresh Kamboju <naresh.kamboju@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
drivers/base/power/clock_ops.c
drivers/clk/clk.c
include/linux/clk.h
include/linux/pm.h