From: Chen-Yu Tsai <[email protected]>
Hi everyone,
This is v2 of the sunxi-ng clk parent rewrite part 1.
Changes since v1:
- Collected Maxime's Acked-by for sunxi patches
- Expanded possible_parents_show() to cover most cases
- Added comment to CLK_HW_INIT_HWS detailing usage for sharing
compound literal
As mentioned in my reply to the cover letter of v1, I can merge all the
patches through the sunxi tree and send a combined (with other sunxi
stuff) PR, or as an independent branch, whichever is preferred.
Excerpt from original cover letter follows:
This is series is the first part of a large series (I haven't done the
rest) of patches to rewrite the clk parent relationship handling within
the sunxi-ng clk driver. This is based on Stephen's recent work allowing
clk drivers to specify clk parents using struct clk_hw * or parsing DT
phandles in the clk node.
This series can be split into a few major parts:
1) The first patch is a small fix for clk debugfs representation. This
was done before commit 1a079560b145 ("clk: Cache core in
clk_fetch_parent_index() without names") was posted, so it might or
might not be needed. Found this when checking my work using
clk_possible_parents.
2) A bunch of CLK_HW_INIT_* helper macros are added. These cover the
situations I encountered, or assume I will encounter, such as single
internal (struct clk_hw *) parent, single DT (struct clk_parent_data
.fw_name), multiple internal parents, and multiple mixed (internal +
DT) parents. A special variant for just an internal single parent is
added, CLK_HW_INIT_HWS, which lets the driver share the singular
list, instead of having the compiler create a compound literal every
time. It might even make sense to only keep this variant.
3) A bunch of CLK_FIXED_FACTOR_* helper macros are added. The rationale
is the same as the single parent CLK_HW_INIT_* helpers.
4) Bulk conversion of CLK_FIXED_FACTOR to use local parent references,
either struct clk_hw * or DT .fw_name types, whichever the hardware
requires.
5) The beginning of SUNXI_CCU_GATE conversion to local parent
references. This part is not done. They are included as justification
and examples for the shared list of clk parents case.
Thanks
ChenYu
Chen-Yu Tsai (25):
clk: Fix debugfs clk_possible_parents for clks without parent string
names
clk: Add CLK_HW_INIT_* macros using .parent_hws
clk: Add CLK_HW_INIT_FW_NAME macro using .fw_name in .parent_data
clk: Add CLK_HW_INIT_PARENT_DATA macro using .parent_data
clk: fixed-factor: Add CLK_FIXED_FACTOR_HW which takes clk_hw pointer
as parent
clk: fixed-factor: Add CLK_FIXED_FACTOR_HWS which takes list of struct
clk_hw *
clk: fixed-factor: Add CLK_FIXED_FACTOR_FW_NAME for DT clock-names
parent
clk: sunxi-ng: switch to of_clk_hw_register() for registering clks
clk: sunxi-ng: sun8i-r: Use local parent references for CLK_HW_INIT_*
clk: sunxi-ng: a10: Use local parent references for CLK_FIXED_FACTOR
clk: sunxi-ng: sun5i: Use local parent references for CLK_FIXED_FACTOR
clk: sunxi-ng: a31: Use local parent references for CLK_FIXED_FACTOR
clk: sunxi-ng: a23: Use local parent references for CLK_FIXED_FACTOR
clk: sunxi-ng: a33: Use local parent references for CLK_FIXED_FACTOR
clk: sunxi-ng: h3: Use local parent references for CLK_FIXED_FACTOR
clk: sunxi-ng: r40: Use local parent references for CLK_FIXED_FACTOR
clk: sunxi-ng: v3s: Use local parent references for CLK_FIXED_FACTOR
clk: sunxi-ng: sun8i-r: Use local parent references for
CLK_FIXED_FACTOR
clk: sunxi-ng: f1c100s: Use local parent references for
CLK_FIXED_FACTOR
clk: sunxi-ng: a64: Use local parent references for CLK_FIXED_FACTOR
clk: sunxi-ng: h6: Use local parent references for CLK_FIXED_FACTOR
clk: sunxi-ng: h6-r: Use local parent references for CLK_FIXED_FACTOR
clk: sunxi-ng: gate: Add macros for referencing local clock parents
clk: sunxi-ng: a80-usb: Use local parent references for SUNXI_CCU_GATE
clk: sunxi-ng: sun8i-r: Use local parent references for SUNXI_CCU_GATE
drivers/clk/clk.c | 44 +++++++++-
drivers/clk/sunxi-ng/ccu-sun4i-a10.c | 39 ++++++---
drivers/clk/sunxi-ng/ccu-sun50i-a64.c | 41 +++++----
drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c | 2 +-
drivers/clk/sunxi-ng/ccu-sun50i-h6.c | 69 +++++++++------
drivers/clk/sunxi-ng/ccu-sun5i.c | 34 +++++---
drivers/clk/sunxi-ng/ccu-sun6i-a31.c | 39 ++++++---
drivers/clk/sunxi-ng/ccu-sun8i-a23.c | 34 +++++---
drivers/clk/sunxi-ng/ccu-sun8i-a33.c | 34 +++++---
drivers/clk/sunxi-ng/ccu-sun8i-h3.c | 29 ++++---
drivers/clk/sunxi-ng/ccu-sun8i-r.c | 104 +++++++++++------------
drivers/clk/sunxi-ng/ccu-sun8i-r40.c | 46 ++++++----
drivers/clk/sunxi-ng/ccu-sun8i-v3s.c | 29 ++++---
drivers/clk/sunxi-ng/ccu-sun9i-a80-usb.c | 32 ++++---
drivers/clk/sunxi-ng/ccu-suniv-f1c100s.c | 29 ++++---
drivers/clk/sunxi-ng/ccu_common.c | 2 +-
drivers/clk/sunxi-ng/ccu_gate.h | 53 ++++++++++++
include/linux/clk-provider.h | 89 +++++++++++++++++++
18 files changed, 526 insertions(+), 223 deletions(-)
--
2.20.1
From: Chen-Yu Tsai <[email protected]>
With the new clk parenting code, clk_init_data was expanded to include
.parent_hws, for clk drivers to directly reference parents by clk_hw.
Add a new macro, CLK_FIXED_FACTOR_HW, that can take a struct clk_hw
pointer, instead of a string, as its parent.
Signed-off-by: Chen-Yu Tsai <[email protected]>
---
include/linux/clk-provider.h | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index 0fd14c4874d6..c85e9f3809f2 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -985,6 +985,17 @@ extern struct of_device_id __clk_of_table;
_flags), \
}
+#define CLK_FIXED_FACTOR_HW(_struct, _name, _parent, \
+ _div, _mult, _flags) \
+ struct clk_fixed_factor _struct = { \
+ .div = _div, \
+ .mult = _mult, \
+ .hw.init = CLK_HW_INIT_HW(_name, \
+ _parent, \
+ &clk_fixed_factor_ops, \
+ _flags), \
+ }
+
#ifdef CONFIG_OF
int of_clk_add_provider(struct device_node *np,
struct clk *(*clk_src_get)(struct of_phandle_args *args,
--
2.20.1
From: Chen-Yu Tsai <[email protected]>
With the new clk parenting code and CLK_FIXED_FACTOR_{HW,FW_NAME}
macros, we can reference parents locally via pointers to struct clk_hw
or DT clock-names.
Convert existing CLK_FIXED_FACTOR definitions to either the _HW or
_FW_NAME variant based on whether the parent clock is internal or
external to the CCU.
Acked-by: Maxime Ripard <[email protected]>
Signed-off-by: Chen-Yu Tsai <[email protected]>
---
drivers/clk/sunxi-ng/ccu-sun8i-a33.c | 34 ++++++++++++++++++----------
1 file changed, 22 insertions(+), 12 deletions(-)
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a33.c b/drivers/clk/sunxi-ng/ccu-sun8i-a33.c
index 25bcf3fd2dfc..25a14548f39b 100644
--- a/drivers/clk/sunxi-ng/ccu-sun8i-a33.c
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-a33.c
@@ -588,19 +588,29 @@ static struct ccu_common *sun8i_a33_ccu_clks[] = {
&ats_clk.common,
};
+static const struct clk_hw *clk_parent_pll_audio[] = {
+ &pll_audio_base_clk.common.hw
+};
+
/* We hardcode the divider to 1 for now */
-static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio",
- "pll-audio-base", 1, 1, CLK_SET_RATE_PARENT);
-static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x",
- "pll-audio-base", 2, 1, CLK_SET_RATE_PARENT);
-static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x",
- "pll-audio-base", 1, 1, CLK_SET_RATE_PARENT);
-static CLK_FIXED_FACTOR(pll_audio_8x_clk, "pll-audio-8x",
- "pll-audio-base", 1, 2, CLK_SET_RATE_PARENT);
-static CLK_FIXED_FACTOR(pll_periph_2x_clk, "pll-periph-2x",
- "pll-periph", 1, 2, 0);
-static CLK_FIXED_FACTOR(pll_video_2x_clk, "pll-video-2x",
- "pll-video", 1, 2, 0);
+static CLK_FIXED_FACTOR_HWS(pll_audio_clk, "pll-audio",
+ clk_parent_pll_audio,
+ 1, 1, CLK_SET_RATE_PARENT);
+static CLK_FIXED_FACTOR_HWS(pll_audio_2x_clk, "pll-audio-2x",
+ clk_parent_pll_audio,
+ 2, 1, CLK_SET_RATE_PARENT);
+static CLK_FIXED_FACTOR_HWS(pll_audio_4x_clk, "pll-audio-4x",
+ clk_parent_pll_audio,
+ 1, 1, CLK_SET_RATE_PARENT);
+static CLK_FIXED_FACTOR_HWS(pll_audio_8x_clk, "pll-audio-8x",
+ clk_parent_pll_audio,
+ 1, 2, CLK_SET_RATE_PARENT);
+static CLK_FIXED_FACTOR_HW(pll_periph_2x_clk, "pll-periph-2x",
+ &pll_periph_clk.common.hw,
+ 1, 2, 0);
+static CLK_FIXED_FACTOR_HW(pll_video_2x_clk, "pll-video-2x",
+ &pll_video_clk.common.hw,
+ 1, 2, 0);
static struct clk_hw_onecell_data sun8i_a33_hw_clks = {
.hws = {
--
2.20.1
From: Chen-Yu Tsai <[email protected]>
With the new clk parenting code, struct clk_init_data was expanded to
include .parent_data, for clk drivers that have parents referenced using
a combination of device tree clock-names, clock indices, and/or struct
clk_hw pointers.
Add a new macro that can take a list of struct clk_parent_data for
drivers to use.
Signed-off-by: Chen-Yu Tsai <[email protected]>
---
include/linux/clk-provider.h | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index b19063512a29..0fd14c4874d6 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -956,6 +956,15 @@ extern struct of_device_id __clk_of_table;
.ops = _ops, \
})
+#define CLK_HW_INIT_PARENTS_DATA(_name, _parents, _ops, _flags) \
+ (&(struct clk_init_data) { \
+ .flags = _flags, \
+ .name = _name, \
+ .parent_data = _parents, \
+ .num_parents = ARRAY_SIZE(_parents), \
+ .ops = _ops, \
+ })
+
#define CLK_HW_INIT_NO_PARENT(_name, _ops, _flags) \
(&(struct clk_init_data) { \
.flags = _flags, \
--
2.20.1
From: Chen-Yu Tsai <[email protected]>
With the new clk parenting code and CLK_FIXED_FACTOR_{HW,FW_NAME}
macros, we can reference parents locally via pointers to struct clk_hw
or DT clock-names.
Convert existing CLK_FIXED_FACTOR definitions to either the _HW or
_FW_NAME variant based on whether the parent clock is internal or
external to the CCU.
Acked-by: Maxime Ripard <[email protected]>
Signed-off-by: Chen-Yu Tsai <[email protected]>
---
drivers/clk/sunxi-ng/ccu-sun8i-v3s.c | 29 ++++++++++++++++++----------
1 file changed, 19 insertions(+), 10 deletions(-)
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c b/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c
index ec64eb692ecf..60f011b1fbf6 100644
--- a/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c
@@ -437,17 +437,26 @@ static struct ccu_common *sun8i_v3s_ccu_clks[] = {
&mipi_csi_clk.common,
};
+static const struct clk_hw *clk_parent_pll_audio[] = {
+ &pll_audio_base_clk.common.hw
+};
+
/* We hardcode the divider to 4 for now */
-static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio",
- "pll-audio-base", 4, 1, CLK_SET_RATE_PARENT);
-static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x",
- "pll-audio-base", 2, 1, CLK_SET_RATE_PARENT);
-static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x",
- "pll-audio-base", 1, 1, CLK_SET_RATE_PARENT);
-static CLK_FIXED_FACTOR(pll_audio_8x_clk, "pll-audio-8x",
- "pll-audio-base", 1, 2, CLK_SET_RATE_PARENT);
-static CLK_FIXED_FACTOR(pll_periph0_2x_clk, "pll-periph0-2x",
- "pll-periph0", 1, 2, 0);
+static CLK_FIXED_FACTOR_HWS(pll_audio_clk, "pll-audio",
+ clk_parent_pll_audio,
+ 4, 1, CLK_SET_RATE_PARENT);
+static CLK_FIXED_FACTOR_HWS(pll_audio_2x_clk, "pll-audio-2x",
+ clk_parent_pll_audio,
+ 2, 1, CLK_SET_RATE_PARENT);
+static CLK_FIXED_FACTOR_HWS(pll_audio_4x_clk, "pll-audio-4x",
+ clk_parent_pll_audio,
+ 1, 1, CLK_SET_RATE_PARENT);
+static CLK_FIXED_FACTOR_HWS(pll_audio_8x_clk, "pll-audio-8x",
+ clk_parent_pll_audio,
+ 1, 2, CLK_SET_RATE_PARENT);
+static CLK_FIXED_FACTOR_HW(pll_periph0_2x_clk, "pll-periph0-2x",
+ &pll_periph0_clk.common.hw,
+ 1, 2, 0);
static struct clk_hw_onecell_data sun8i_v3s_hw_clks = {
.hws = {
--
2.20.1
From: Chen-Yu Tsai <[email protected]>
With the new clk parenting code, struct clk_init_data was expanded to
include .parent_hws, for clk drivers to directly list parents by
pointing to their respective struct clk_hw's.
Add macros that can take either one single struct clk_hw *, or an array
of them, for drivers to use.
A special CLK_HW_INIT_HWS macro is included, which takes an array of
struct clk_hw *, but sets .num_parents to 1. This variant is to allow
the reuse of the array, instead of having a compound literal allocated
for each clk sharing the same parent.
Signed-off-by: Chen-Yu Tsai <[email protected]>
---
include/linux/clk-provider.h | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index bb6118f79784..70aad5cefea7 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -904,6 +904,29 @@ extern struct of_device_id __clk_of_table;
.ops = _ops, \
})
+#define CLK_HW_INIT_HW(_name, _parent, _ops, _flags) \
+ (&(struct clk_init_data) { \
+ .flags = _flags, \
+ .name = _name, \
+ .parent_hws = (const struct clk_hw*[]) { _parent }, \
+ .num_parents = 1, \
+ .ops = _ops, \
+ })
+
+/*
+ * This macro is intended for drivers to be able to share the otherwise
+ * individual struct clk_hw[] compound literals created by the compiler
+ * when using CLK_HW_INIT_HW. It does NOT support multiple parents.
+ */
+#define CLK_HW_INIT_HWS(_name, _parent, _ops, _flags) \
+ (&(struct clk_init_data) { \
+ .flags = _flags, \
+ .name = _name, \
+ .parent_hws = _parent, \
+ .num_parents = 1, \
+ .ops = _ops, \
+ })
+
#define CLK_HW_INIT_PARENTS(_name, _parents, _ops, _flags) \
(&(struct clk_init_data) { \
.flags = _flags, \
@@ -913,6 +936,15 @@ extern struct of_device_id __clk_of_table;
.ops = _ops, \
})
+#define CLK_HW_INIT_PARENTS_HW(_name, _parents, _ops, _flags) \
+ (&(struct clk_init_data) { \
+ .flags = _flags, \
+ .name = _name, \
+ .parent_hws = _parents, \
+ .num_parents = ARRAY_SIZE(_parents), \
+ .ops = _ops, \
+ })
+
#define CLK_HW_INIT_NO_PARENT(_name, _ops, _flags) \
(&(struct clk_init_data) { \
.flags = _flags, \
--
2.20.1