mirror of
https://github.com/Fishwaldo/build.git
synced 2025-03-29 10:11:23 +00:00
146 lines
4 KiB
Diff
146 lines
4 KiB
Diff
From c87711484070e9fb733330662a19f7fc1de9b368 Mon Sep 17 00:00:00 2001
|
|
From: Jerome Brunet <jbrunet@baylibre.com>
|
|
Date: Mon, 20 Mar 2017 14:35:47 +0100
|
|
Subject: [PATCH 48/79] clk: rework calls to round and determine rate callbacks
|
|
|
|
Rework the way the callbacks round_rate and determine_rate are called. The
|
|
goal is to do this at a single point and make it easier to add conditions
|
|
before calling them.
|
|
|
|
This rework is done to ease the integration of "protected" clock
|
|
functionality.
|
|
|
|
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
|
|
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
|
|
---
|
|
drivers/clk/clk.c | 78 +++++++++++++++++++++++++++++++------------------------
|
|
1 file changed, 44 insertions(+), 34 deletions(-)
|
|
|
|
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
|
|
index dceaf0f..8cc4672 100644
|
|
--- a/drivers/clk/clk.c
|
|
+++ b/drivers/clk/clk.c
|
|
@@ -833,16 +833,34 @@ static int clk_disable_unused(void)
|
|
}
|
|
late_initcall_sync(clk_disable_unused);
|
|
|
|
-static int clk_core_round_rate_nolock(struct clk_core *core,
|
|
- struct clk_rate_request *req)
|
|
+static int clk_core_determine_round(struct clk_core *core,
|
|
+ struct clk_rate_request *req)
|
|
{
|
|
- struct clk_core *parent;
|
|
long rate;
|
|
|
|
- lockdep_assert_held(&prepare_lock);
|
|
+ if (core->ops->determine_rate) {
|
|
+ return core->ops->determine_rate(core->hw, req);
|
|
+ } else if (core->ops->round_rate) {
|
|
+ rate = core->ops->round_rate(core->hw, req->rate,
|
|
+ &req->best_parent_rate);
|
|
+ if (rate < 0)
|
|
+ return rate;
|
|
|
|
- if (!core)
|
|
- return 0;
|
|
+ req->rate = rate;
|
|
+ } else {
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static void clk_core_init_rate_req(struct clk_core *core,
|
|
+ struct clk_rate_request *req)
|
|
+{
|
|
+ struct clk_core *parent;
|
|
+
|
|
+ if (WARN_ON(!core || !req))
|
|
+ return;
|
|
|
|
parent = core->parent;
|
|
if (parent) {
|
|
@@ -852,22 +870,24 @@ static int clk_core_round_rate_nolock(struct clk_core *core,
|
|
req->best_parent_hw = NULL;
|
|
req->best_parent_rate = 0;
|
|
}
|
|
+}
|
|
|
|
- if (core->ops->determine_rate) {
|
|
- return core->ops->determine_rate(core->hw, req);
|
|
- } else if (core->ops->round_rate) {
|
|
- rate = core->ops->round_rate(core->hw, req->rate,
|
|
- &req->best_parent_rate);
|
|
- if (rate < 0)
|
|
- return rate;
|
|
+static int clk_core_round_rate_nolock(struct clk_core *core,
|
|
+ struct clk_rate_request *req)
|
|
+{
|
|
+ lockdep_assert_held(&prepare_lock);
|
|
|
|
- req->rate = rate;
|
|
- } else if (core->flags & CLK_SET_RATE_PARENT) {
|
|
- return clk_core_round_rate_nolock(parent, req);
|
|
- } else {
|
|
- req->rate = core->rate;
|
|
- }
|
|
+ if (!core)
|
|
+ return 0;
|
|
+
|
|
+ clk_core_init_rate_req(core, req);
|
|
+
|
|
+ if (core->ops->determine_rate || core->ops->round_rate)
|
|
+ return clk_core_determine_round(core, req);
|
|
+ else if (core->flags & CLK_SET_RATE_PARENT)
|
|
+ return clk_core_round_rate_nolock(core->parent, req);
|
|
|
|
+ req->rate = core->rate;
|
|
return 0;
|
|
}
|
|
|
|
@@ -1356,36 +1376,26 @@ static struct clk_core *clk_calc_new_rates(struct clk_core *core,
|
|
clk_core_get_boundaries(core, &min_rate, &max_rate);
|
|
|
|
/* find the closest rate and parent clk/rate */
|
|
- if (core->ops->determine_rate) {
|
|
+ if (core->ops->determine_rate || core->ops->round_rate) {
|
|
struct clk_rate_request req;
|
|
|
|
req.rate = rate;
|
|
req.min_rate = min_rate;
|
|
req.max_rate = max_rate;
|
|
- if (parent) {
|
|
- req.best_parent_hw = parent->hw;
|
|
- req.best_parent_rate = parent->rate;
|
|
- } else {
|
|
- req.best_parent_hw = NULL;
|
|
- req.best_parent_rate = 0;
|
|
- }
|
|
|
|
- ret = core->ops->determine_rate(core->hw, &req);
|
|
+ clk_core_init_rate_req(core, &req);
|
|
+
|
|
+ ret = clk_core_determine_round(core, &req);
|
|
if (ret < 0)
|
|
return NULL;
|
|
|
|
best_parent_rate = req.best_parent_rate;
|
|
new_rate = req.rate;
|
|
parent = req.best_parent_hw ? req.best_parent_hw->core : NULL;
|
|
- } else if (core->ops->round_rate) {
|
|
- ret = core->ops->round_rate(core->hw, rate,
|
|
- &best_parent_rate);
|
|
- if (ret < 0)
|
|
- return NULL;
|
|
|
|
- new_rate = ret;
|
|
if (new_rate < min_rate || new_rate > max_rate)
|
|
return NULL;
|
|
+
|
|
} else if (!parent || !(core->flags & CLK_SET_RATE_PARENT)) {
|
|
/* pass-through clock without adjustable parent */
|
|
core->new_rate = core->rate;
|
|
--
|
|
1.9.1
|
|
|