2022-05-16 21:40:32 +00:00
|
|
|
From 1008f7a86f470914e78a54a2a75cf8bbc8b8f9db Mon Sep 17 00:00:00 2001
|
|
|
|
From: Maxime Ripard <maxime@cerno.tech>
|
|
|
|
Date: Fri, 15 Apr 2022 14:17:41 +0200
|
|
|
|
Subject: [PATCH] clk: Add clk_get_rate_range
|
|
|
|
|
|
|
|
With the recent introduction of clock drivers that will force their
|
|
|
|
clock rate to either the minimum or maximum boundaries, it becomes
|
|
|
|
harder for clock users to discover either boundary of their clock.
|
|
|
|
|
|
|
|
Indeed, the best way to do that previously was to call clk_round_rate()
|
|
|
|
on either 0 or ULONG_MAX and count on the driver to clamp the rate to
|
|
|
|
the current boundary, but that won't work anymore.
|
|
|
|
|
|
|
|
Since any other alternative (calling clk_set_rate_range() and looking at
|
|
|
|
the returned value, calling clk_round_rate() still, or just doing
|
|
|
|
nothing) depends on how the driver will behaves, we actually are
|
|
|
|
punching a hole through the abstraction provided by the clock framework.
|
|
|
|
|
|
|
|
In order to avoid any abstraction violation, let's create a bunch of
|
|
|
|
accessors that will return the current minimum and maximum for a given
|
|
|
|
clock.
|
|
|
|
|
|
|
|
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
|
|
|
|
---
|
|
|
|
drivers/clk/clk.c | 18 ++++++++++++++
|
|
|
|
include/linux/clk.h | 59 +++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
2 files changed, 77 insertions(+)
|
|
|
|
|
|
|
|
--- a/drivers/clk/clk.c
|
|
|
|
+++ b/drivers/clk/clk.c
|
2024-04-28 19:35:55 +00:00
|
|
|
@@ -2679,6 +2679,24 @@ int clk_set_max_rate(struct clk *clk, un
|
2022-05-16 21:40:32 +00:00
|
|
|
EXPORT_SYMBOL_GPL(clk_set_max_rate);
|
|
|
|
|
|
|
|
/**
|
|
|
|
+ * clk_get_rate_range - returns the clock rate range for a clock source
|
|
|
|
+ * @clk: clock source
|
|
|
|
+ * @min: Pointer to the variable that will hold the minimum
|
|
|
|
+ * @max: Pointer to the variable that will hold the maximum
|
|
|
|
+ *
|
|
|
|
+ * Fills the @min and @max variables with the minimum and maximum that
|
|
|
|
+ * the clock source can reach.
|
|
|
|
+ */
|
|
|
|
+void clk_get_rate_range(struct clk *clk, unsigned long *min, unsigned long *max)
|
|
|
|
+{
|
|
|
|
+ if (!clk || !min || !max)
|
|
|
|
+ return;
|
|
|
|
+
|
|
|
|
+ clk_core_get_boundaries(clk->core, min, max);
|
|
|
|
+}
|
|
|
|
+EXPORT_SYMBOL_GPL(clk_get_rate_range);
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
* clk_get_parent - return the parent of a clk
|
|
|
|
* @clk: the clk whose parent gets returned
|
|
|
|
*
|
|
|
|
--- a/include/linux/clk.h
|
|
|
|
+++ b/include/linux/clk.h
|
2023-08-30 18:44:05 +00:00
|
|
|
@@ -807,6 +807,17 @@ bool clk_has_parent(struct clk *clk, str
|
2022-05-16 21:40:32 +00:00
|
|
|
int clk_set_rate_range(struct clk *clk, unsigned long min, unsigned long max);
|
|
|
|
|
|
|
|
/**
|
|
|
|
+ * clk_get_rate_range - returns the clock rate range for a clock source
|
|
|
|
+ * @clk: clock source
|
|
|
|
+ * @min: Pointer to the variable that will hold the minimum
|
|
|
|
+ * @max: Pointer to the variable that will hold the maximum
|
|
|
|
+ *
|
|
|
|
+ * Fills the @min and @max variables with the minimum and maximum that
|
|
|
|
+ * the clock source can reach.
|
|
|
|
+ */
|
|
|
|
+void clk_get_rate_range(struct clk *clk, unsigned long *min, unsigned long *max);
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
* clk_set_min_rate - set a minimum clock rate for a clock source
|
|
|
|
* @clk: clock source
|
|
|
|
* @rate: desired minimum clock rate in Hz, inclusive
|
2022-12-14 15:11:04 +00:00
|
|
|
@@ -1018,6 +1029,16 @@ static inline int clk_set_rate_range(str
|
2022-05-16 21:40:32 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
+static inline void clk_get_rate_range(struct clk *clk, unsigned long *min,
|
|
|
|
+ unsigned long *max)
|
|
|
|
+{
|
|
|
|
+ if (!min || !max)
|
|
|
|
+ return;
|
|
|
|
+
|
|
|
|
+ *min = 0;
|
|
|
|
+ *max = ULONG_MAX;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
static inline int clk_set_min_rate(struct clk *clk, unsigned long rate)
|
|
|
|
{
|
|
|
|
return 0;
|
2022-12-14 15:11:04 +00:00
|
|
|
@@ -1108,6 +1129,44 @@ static inline int clk_drop_range(struct
|
2022-05-16 21:40:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
+ * clk_get_min_rate - returns the minimum clock rate for a clock source
|
|
|
|
+ * @clk: clock source
|
|
|
|
+ *
|
|
|
|
+ * Returns either the minimum clock rate in Hz that clock source can
|
|
|
|
+ * reach, or 0 on error.
|
|
|
|
+ */
|
|
|
|
+static inline unsigned long clk_get_min_rate(struct clk *clk)
|
|
|
|
+{
|
|
|
|
+ unsigned long min, max;
|
|
|
|
+
|
|
|
|
+ if (!clk)
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
+ clk_get_rate_range(clk, &min, &max);
|
|
|
|
+
|
|
|
|
+ return min;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * clk_get_max_rate - returns the maximum clock rate for a clock source
|
|
|
|
+ * @clk: clock source
|
|
|
|
+ *
|
|
|
|
+ * Returns either the maximum clock rate in Hz that clock source can
|
|
|
|
+ * reach, or 0 on error.
|
|
|
|
+ */
|
|
|
|
+static inline unsigned long clk_get_max_rate(struct clk *clk)
|
|
|
|
+{
|
|
|
|
+ unsigned long min, max;
|
|
|
|
+
|
|
|
|
+ if (!clk)
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
+ clk_get_rate_range(clk, &min, &max);
|
|
|
|
+
|
|
|
|
+ return max;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
* clk_get_optional - lookup and obtain a reference to an optional clock
|
|
|
|
* producer.
|
|
|
|
* @dev: device for clock "consumer"
|