Skip to content

Commit 9a34b45

Browse files
mszyprowmturquette
authored andcommitted
clk: Add support for runtime PM
Registers for some clocks might be located in the SOC area, which are under the power domain. To enable access to those registers respective domain has to be turned on. Additionally, registers for such clocks will usually loose its contents when power domain is turned off, so additional saving and restoring of them might be needed in the clock controller driver. This patch adds basic infrastructure in the clocks core to allow implementing driver for such clocks under power domains. Clock provider can supply a struct device pointer, which is the used by clock core for tracking and managing clock's controller runtime pm state. Each clk_prepare() operation will first call pm_runtime_get_sync() on the supplied device, while clk_unprepare() will do pm_runtime_put_sync() at the end. Additional calls to pm_runtime_get/put functions are required to ensure that any register access (like calculating/changing clock rates and unpreparing/disabling unused clocks on boot) will be done with clock controller in runtime resumend state. When one wants to register clock controller, which make use of this feature, he has to: 1. Provide a struct device to the core when registering the provider. 2. Ensure to enable runtime PM for that device before registering clocks. 3. Make sure that the runtime PM status of the controller device reflects the HW state. Signed-off-by: Marek Szyprowski <[email protected]> Reviewed-by: Ulf Hansson <[email protected]> Acked-by: Krzysztof Kozlowski <[email protected]> Signed-off-by: Michael Turquette <[email protected]> Link: lkml.kernel.org/r/[email protected]
1 parent 5771a8c commit 9a34b45

File tree

1 file changed

+112
-14
lines changed

1 file changed

+112
-14
lines changed

drivers/clk/clk.c

Lines changed: 112 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <linux/of.h>
2222
#include <linux/device.h>
2323
#include <linux/init.h>
24+
#include <linux/pm_runtime.h>
2425
#include <linux/sched.h>
2526
#include <linux/clkdev.h>
2627

@@ -46,6 +47,7 @@ struct clk_core {
4647
const struct clk_ops *ops;
4748
struct clk_hw *hw;
4849
struct module *owner;
50+
struct device *dev;
4951
struct clk_core *parent;
5052
const char **parent_names;
5153
struct clk_core **parents;
@@ -87,6 +89,26 @@ struct clk {
8789
struct hlist_node clks_node;
8890
};
8991

92+
/*** runtime pm ***/
93+
static int clk_pm_runtime_get(struct clk_core *core)
94+
{
95+
int ret = 0;
96+
97+
if (!core->dev)
98+
return 0;
99+
100+
ret = pm_runtime_get_sync(core->dev);
101+
return ret < 0 ? ret : 0;
102+
}
103+
104+
static void clk_pm_runtime_put(struct clk_core *core)
105+
{
106+
if (!core->dev)
107+
return;
108+
109+
pm_runtime_put_sync(core->dev);
110+
}
111+
90112
/*** locking ***/
91113
static void clk_prepare_lock(void)
92114
{
@@ -150,26 +172,57 @@ static void clk_enable_unlock(unsigned long flags)
150172

151173
static bool clk_core_is_prepared(struct clk_core *core)
152174
{
175+
bool ret = false;
176+
153177
/*
154178
* .is_prepared is optional for clocks that can prepare
155179
* fall back to software usage counter if it is missing
156180
*/
157181
if (!core->ops->is_prepared)
158182
return core->prepare_count;
159183

160-
return core->ops->is_prepared(core->hw);
184+
if (!clk_pm_runtime_get(core)) {
185+
ret = core->ops->is_prepared(core->hw);
186+
clk_pm_runtime_put(core);
187+
}
188+
189+
return ret;
161190
}
162191

163192
static bool clk_core_is_enabled(struct clk_core *core)
164193
{
194+
bool ret = false;
195+
165196
/*
166197
* .is_enabled is only mandatory for clocks that gate
167198
* fall back to software usage counter if .is_enabled is missing
168199
*/
169200
if (!core->ops->is_enabled)
170201
return core->enable_count;
171202

172-
return core->ops->is_enabled(core->hw);
203+
/*
204+
* Check if clock controller's device is runtime active before
205+
* calling .is_enabled callback. If not, assume that clock is
206+
* disabled, because we might be called from atomic context, from
207+
* which pm_runtime_get() is not allowed.
208+
* This function is called mainly from clk_disable_unused_subtree,
209+
* which ensures proper runtime pm activation of controller before
210+
* taking enable spinlock, but the below check is needed if one tries
211+
* to call it from other places.
212+
*/
213+
if (core->dev) {
214+
pm_runtime_get_noresume(core->dev);
215+
if (!pm_runtime_active(core->dev)) {
216+
ret = false;
217+
goto done;
218+
}
219+
}
220+
221+
ret = core->ops->is_enabled(core->hw);
222+
done:
223+
clk_pm_runtime_put(core);
224+
225+
return ret;
173226
}
174227

175228
/*** helper functions ***/
@@ -489,6 +542,8 @@ static void clk_core_unprepare(struct clk_core *core)
489542
if (core->ops->unprepare)
490543
core->ops->unprepare(core->hw);
491544

545+
clk_pm_runtime_put(core);
546+
492547
trace_clk_unprepare_complete(core);
493548
clk_core_unprepare(core->parent);
494549
}
@@ -530,26 +585,33 @@ static int clk_core_prepare(struct clk_core *core)
530585
return 0;
531586

532587
if (core->prepare_count == 0) {
533-
ret = clk_core_prepare(core->parent);
588+
ret = clk_pm_runtime_get(core);
534589
if (ret)
535590
return ret;
536591

592+
ret = clk_core_prepare(core->parent);
593+
if (ret)
594+
goto runtime_put;
595+
537596
trace_clk_prepare(core);
538597

539598
if (core->ops->prepare)
540599
ret = core->ops->prepare(core->hw);
541600

542601
trace_clk_prepare_complete(core);
543602

544-
if (ret) {
545-
clk_core_unprepare(core->parent);
546-
return ret;
547-
}
603+
if (ret)
604+
goto unprepare;
548605
}
549606

550607
core->prepare_count++;
551608

552609
return 0;
610+
unprepare:
611+
clk_core_unprepare(core->parent);
612+
runtime_put:
613+
clk_pm_runtime_put(core);
614+
return ret;
553615
}
554616

555617
static int clk_core_prepare_lock(struct clk_core *core)
@@ -745,6 +807,9 @@ static void clk_unprepare_unused_subtree(struct clk_core *core)
745807
if (core->flags & CLK_IGNORE_UNUSED)
746808
return;
747809

810+
if (clk_pm_runtime_get(core))
811+
return;
812+
748813
if (clk_core_is_prepared(core)) {
749814
trace_clk_unprepare(core);
750815
if (core->ops->unprepare_unused)
@@ -753,6 +818,8 @@ static void clk_unprepare_unused_subtree(struct clk_core *core)
753818
core->ops->unprepare(core->hw);
754819
trace_clk_unprepare_complete(core);
755820
}
821+
822+
clk_pm_runtime_put(core);
756823
}
757824

758825
static void clk_disable_unused_subtree(struct clk_core *core)
@@ -768,6 +835,9 @@ static void clk_disable_unused_subtree(struct clk_core *core)
768835
if (core->flags & CLK_OPS_PARENT_ENABLE)
769836
clk_core_prepare_enable(core->parent);
770837

838+
if (clk_pm_runtime_get(core))
839+
goto unprepare_out;
840+
771841
flags = clk_enable_lock();
772842

773843
if (core->enable_count)
@@ -792,6 +862,8 @@ static void clk_disable_unused_subtree(struct clk_core *core)
792862

793863
unlock_out:
794864
clk_enable_unlock(flags);
865+
clk_pm_runtime_put(core);
866+
unprepare_out:
795867
if (core->flags & CLK_OPS_PARENT_ENABLE)
796868
clk_core_disable_unprepare(core->parent);
797869
}
@@ -1038,9 +1110,13 @@ EXPORT_SYMBOL_GPL(clk_get_accuracy);
10381110
static unsigned long clk_recalc(struct clk_core *core,
10391111
unsigned long parent_rate)
10401112
{
1041-
if (core->ops->recalc_rate)
1042-
return core->ops->recalc_rate(core->hw, parent_rate);
1043-
return parent_rate;
1113+
unsigned long rate = parent_rate;
1114+
1115+
if (core->ops->recalc_rate && !clk_pm_runtime_get(core)) {
1116+
rate = core->ops->recalc_rate(core->hw, parent_rate);
1117+
clk_pm_runtime_put(core);
1118+
}
1119+
return rate;
10441120
}
10451121

10461122
/**
@@ -1565,6 +1641,7 @@ static int clk_core_set_rate_nolock(struct clk_core *core,
15651641
{
15661642
struct clk_core *top, *fail_clk;
15671643
unsigned long rate = req_rate;
1644+
int ret = 0;
15681645

15691646
if (!core)
15701647
return 0;
@@ -1581,21 +1658,28 @@ static int clk_core_set_rate_nolock(struct clk_core *core,
15811658
if (!top)
15821659
return -EINVAL;
15831660

1661+
ret = clk_pm_runtime_get(core);
1662+
if (ret)
1663+
return ret;
1664+
15841665
/* notify that we are about to change rates */
15851666
fail_clk = clk_propagate_rate_change(top, PRE_RATE_CHANGE);
15861667
if (fail_clk) {
15871668
pr_debug("%s: failed to set %s rate\n", __func__,
15881669
fail_clk->name);
15891670
clk_propagate_rate_change(top, ABORT_RATE_CHANGE);
1590-
return -EBUSY;
1671+
ret = -EBUSY;
1672+
goto err;
15911673
}
15921674

15931675
/* change the rates */
15941676
clk_change_rate(top);
15951677

15961678
core->req_rate = req_rate;
1679+
err:
1680+
clk_pm_runtime_put(core);
15971681

1598-
return 0;
1682+
return ret;
15991683
}
16001684

16011685
/**
@@ -1826,12 +1910,16 @@ static int clk_core_set_parent(struct clk_core *core, struct clk_core *parent)
18261910
p_rate = parent->rate;
18271911
}
18281912

1913+
ret = clk_pm_runtime_get(core);
1914+
if (ret)
1915+
goto out;
1916+
18291917
/* propagate PRE_RATE_CHANGE notifications */
18301918
ret = __clk_speculate_rates(core, p_rate);
18311919

18321920
/* abort if a driver objects */
18331921
if (ret & NOTIFY_STOP_MASK)
1834-
goto out;
1922+
goto runtime_put;
18351923

18361924
/* do the re-parent */
18371925
ret = __clk_set_parent(core, parent, p_index);
@@ -1844,6 +1932,8 @@ static int clk_core_set_parent(struct clk_core *core, struct clk_core *parent)
18441932
__clk_recalc_accuracies(core);
18451933
}
18461934

1935+
runtime_put:
1936+
clk_pm_runtime_put(core);
18471937
out:
18481938
clk_prepare_unlock();
18491939

@@ -2350,7 +2440,7 @@ static inline void clk_debug_unregister(struct clk_core *core)
23502440
*/
23512441
static int __clk_core_init(struct clk_core *core)
23522442
{
2353-
int i, ret = 0;
2443+
int i, ret;
23542444
struct clk_core *orphan;
23552445
struct hlist_node *tmp2;
23562446
unsigned long rate;
@@ -2360,6 +2450,10 @@ static int __clk_core_init(struct clk_core *core)
23602450

23612451
clk_prepare_lock();
23622452

2453+
ret = clk_pm_runtime_get(core);
2454+
if (ret)
2455+
goto unlock;
2456+
23632457
/* check to see if a clock with this name is already registered */
23642458
if (clk_core_lookup(core->name)) {
23652459
pr_debug("%s: clk %s already initialized\n",
@@ -2512,6 +2606,8 @@ static int __clk_core_init(struct clk_core *core)
25122606

25132607
kref_init(&core->ref);
25142608
out:
2609+
clk_pm_runtime_put(core);
2610+
unlock:
25152611
clk_prepare_unlock();
25162612

25172613
if (!ret)
@@ -2583,6 +2679,8 @@ struct clk *clk_register(struct device *dev, struct clk_hw *hw)
25832679
goto fail_name;
25842680
}
25852681
core->ops = hw->init->ops;
2682+
if (dev && pm_runtime_enabled(dev))
2683+
core->dev = dev;
25862684
if (dev && dev->driver)
25872685
core->owner = dev->driver->owner;
25882686
core->hw = hw;

0 commit comments

Comments
 (0)