Skip to content

Commit ff773fd

Browse files
tlebbebarino
authored andcommitted
clk: fixed-factor: add optional accuracy support
Fixed factor clock reports the parent clock accuracy. Add flags and acc fields to `struct clk_fixed_factor` to support setting a fixed accuracy. The default if no flag is set is not changed: use the parent clock accuracy. Signed-off-by: Théo Lebrun <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Stephen Boyd <[email protected]>
1 parent 6613476 commit ff773fd

File tree

2 files changed

+32
-8
lines changed

2 files changed

+32
-8
lines changed

drivers/clk/clk-fixed-factor.c

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,22 @@ static int clk_factor_set_rate(struct clk_hw *hw, unsigned long rate,
5757
return 0;
5858
}
5959

60+
static unsigned long clk_factor_recalc_accuracy(struct clk_hw *hw,
61+
unsigned long parent_accuracy)
62+
{
63+
struct clk_fixed_factor *fix = to_clk_fixed_factor(hw);
64+
65+
if (fix->flags & CLK_FIXED_FACTOR_FIXED_ACCURACY)
66+
return fix->acc;
67+
68+
return parent_accuracy;
69+
}
70+
6071
const struct clk_ops clk_fixed_factor_ops = {
6172
.round_rate = clk_factor_round_rate,
6273
.set_rate = clk_factor_set_rate,
6374
.recalc_rate = clk_factor_recalc_rate,
75+
.recalc_accuracy = clk_factor_recalc_accuracy,
6476
};
6577
EXPORT_SYMBOL_GPL(clk_fixed_factor_ops);
6678

@@ -81,7 +93,7 @@ __clk_hw_register_fixed_factor(struct device *dev, struct device_node *np,
8193
const char *name, const char *parent_name,
8294
const struct clk_hw *parent_hw, int index,
8395
unsigned long flags, unsigned int mult, unsigned int div,
84-
bool devm)
96+
unsigned long acc, unsigned int fixflags, bool devm)
8597
{
8698
struct clk_fixed_factor *fix;
8799
struct clk_init_data init = { };
@@ -105,6 +117,8 @@ __clk_hw_register_fixed_factor(struct device *dev, struct device_node *np,
105117
fix->mult = mult;
106118
fix->div = div;
107119
fix->hw.init = &init;
120+
fix->acc = acc;
121+
fix->flags = fixflags;
108122

109123
init.name = name;
110124
init.ops = &clk_fixed_factor_ops;
@@ -152,7 +166,7 @@ struct clk_hw *devm_clk_hw_register_fixed_factor_index(struct device *dev,
152166
unsigned int mult, unsigned int div)
153167
{
154168
return __clk_hw_register_fixed_factor(dev, NULL, name, NULL, NULL, index,
155-
flags, mult, div, true);
169+
flags, mult, div, 0, 0, true);
156170
}
157171
EXPORT_SYMBOL_GPL(devm_clk_hw_register_fixed_factor_index);
158172

@@ -174,7 +188,7 @@ struct clk_hw *devm_clk_hw_register_fixed_factor_parent_hw(struct device *dev,
174188
unsigned long flags, unsigned int mult, unsigned int div)
175189
{
176190
return __clk_hw_register_fixed_factor(dev, NULL, name, NULL, parent_hw,
177-
-1, flags, mult, div, true);
191+
-1, flags, mult, div, 0, 0, true);
178192
}
179193
EXPORT_SYMBOL_GPL(devm_clk_hw_register_fixed_factor_parent_hw);
180194

@@ -184,7 +198,7 @@ struct clk_hw *clk_hw_register_fixed_factor_parent_hw(struct device *dev,
184198
{
185199
return __clk_hw_register_fixed_factor(dev, NULL, name, NULL,
186200
parent_hw, -1, flags, mult, div,
187-
false);
201+
0, 0, false);
188202
}
189203
EXPORT_SYMBOL_GPL(clk_hw_register_fixed_factor_parent_hw);
190204

@@ -193,7 +207,7 @@ struct clk_hw *clk_hw_register_fixed_factor(struct device *dev,
193207
unsigned int mult, unsigned int div)
194208
{
195209
return __clk_hw_register_fixed_factor(dev, NULL, name, parent_name, NULL, -1,
196-
flags, mult, div, false);
210+
flags, mult, div, 0, 0, false);
197211
}
198212
EXPORT_SYMBOL_GPL(clk_hw_register_fixed_factor);
199213

@@ -240,7 +254,7 @@ struct clk_hw *devm_clk_hw_register_fixed_factor(struct device *dev,
240254
unsigned int mult, unsigned int div)
241255
{
242256
return __clk_hw_register_fixed_factor(dev, NULL, name, parent_name, NULL, -1,
243-
flags, mult, div, true);
257+
flags, mult, div, 0, 0, true);
244258
}
245259
EXPORT_SYMBOL_GPL(devm_clk_hw_register_fixed_factor);
246260

@@ -267,7 +281,7 @@ static struct clk_hw *_of_fixed_factor_clk_setup(struct device_node *node)
267281
of_property_read_string(node, "clock-output-names", &clk_name);
268282

269283
hw = __clk_hw_register_fixed_factor(NULL, node, clk_name, NULL, NULL, 0,
270-
0, mult, div, false);
284+
0, mult, div, 0, 0, false);
271285
if (IS_ERR(hw)) {
272286
/*
273287
* Clear OF_POPULATED flag so that clock registration can be

include/linux/clk-provider.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1084,18 +1084,28 @@ void of_fixed_factor_clk_setup(struct device_node *node);
10841084
* @hw: handle between common and hardware-specific interfaces
10851085
* @mult: multiplier
10861086
* @div: divider
1087+
* @acc: fixed accuracy in ppb
1088+
* @flags: behavior modifying flags
10871089
*
10881090
* Clock with a fixed multiplier and divider. The output frequency is the
10891091
* parent clock rate divided by div and multiplied by mult.
1090-
* Implements .recalc_rate, .set_rate and .round_rate
1092+
* Implements .recalc_rate, .set_rate, .round_rate and .recalc_accuracy
1093+
*
1094+
* Flags:
1095+
* * CLK_FIXED_FACTOR_FIXED_ACCURACY - Use the value in @acc instead of the
1096+
* parent clk accuracy.
10911097
*/
10921098

10931099
struct clk_fixed_factor {
10941100
struct clk_hw hw;
10951101
unsigned int mult;
10961102
unsigned int div;
1103+
unsigned long acc;
1104+
unsigned int flags;
10971105
};
10981106

1107+
#define CLK_FIXED_FACTOR_FIXED_ACCURACY BIT(0)
1108+
10991109
#define to_clk_fixed_factor(_hw) container_of(_hw, struct clk_fixed_factor, hw)
11001110

11011111
extern const struct clk_ops clk_fixed_factor_ops;

0 commit comments

Comments
 (0)