Loading Documentation/driver-api/clk.rst +1 −8 Original line number Diff line number Diff line Loading @@ -77,9 +77,6 @@ the operations defined in clk-provider.h:: void (*disable_unused)(struct clk_hw *hw); unsigned long (*recalc_rate)(struct clk_hw *hw, unsigned long parent_rate); long (*round_rate)(struct clk_hw *hw, unsigned long rate, unsigned long *parent_rate); int (*determine_rate)(struct clk_hw *hw, struct clk_rate_request *req); int (*set_parent)(struct clk_hw *hw, u8 index); Loading Loading @@ -220,9 +217,7 @@ optional or must be evaluated on a case-by-case basis. +----------------+------+-------------+---------------+-------------+------+ |.recalc_rate | | y | | | | +----------------+------+-------------+---------------+-------------+------+ |.round_rate | | y [1]_ | | | | +----------------+------+-------------+---------------+-------------+------+ |.determine_rate | | y [1]_ | | | | |.determine_rate | | y | | | | +----------------+------+-------------+---------------+-------------+------+ |.set_rate | | y | | | | +----------------+------+-------------+---------------+-------------+------+ Loading @@ -238,8 +233,6 @@ optional or must be evaluated on a case-by-case basis. |.init | | | | | | +----------------+------+-------------+---------------+-------------+------+ .. [1] either one of round_rate or determine_rate is required. Finally, register your clock at run-time with a hardware-specific registration function. This function simply populates struct clk_foo's data and then passes the common struct clk parameters to the framework Loading drivers/clk/clk.c +14 −25 Original line number Diff line number Diff line Loading @@ -1560,8 +1560,6 @@ late_initcall_sync(clk_disable_unused); static int clk_core_determine_round_nolock(struct clk_core *core, struct clk_rate_request *req) { long rate; lockdep_assert_held(&prepare_lock); if (!core) Loading Loading @@ -1591,13 +1589,6 @@ static int clk_core_determine_round_nolock(struct clk_core *core, req->rate = core->rate; } else 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; req->rate = rate; } else { return -EINVAL; } Loading Loading @@ -1682,7 +1673,7 @@ EXPORT_SYMBOL_GPL(clk_hw_forward_rate_request); static bool clk_core_can_round(struct clk_core * const core) { return core->ops->determine_rate || core->ops->round_rate; return core->ops->determine_rate; } static int clk_core_round_rate_nolock(struct clk_core *core, Loading Loading @@ -1750,11 +1741,11 @@ EXPORT_SYMBOL_GPL(__clk_determine_rate); * use. * * Context: prepare_lock must be held. * For clk providers to call from within clk_ops such as .round_rate, * For clk providers to call from within clk_ops such as * .determine_rate. * * Return: returns rounded rate of hw clk if clk supports round_rate operation * else returns the parent rate. * Return: returns rounded rate of hw clk if clk supports determine_rate * operation; else returns the parent rate. */ unsigned long clk_hw_round_rate(struct clk_hw *hw, unsigned long rate) { Loading Loading @@ -2569,12 +2560,13 @@ static int clk_core_set_rate_nolock(struct clk_core *core, * * Setting the CLK_SET_RATE_PARENT flag allows the rate change operation to * propagate up to clk's parent; whether or not this happens depends on the * outcome of clk's .round_rate implementation. If *parent_rate is unchanged * after calling .round_rate then upstream parent propagation is ignored. If * *parent_rate comes back with a new rate for clk's parent then we propagate * up to clk's parent and set its rate. Upward propagation will continue * until either a clk does not support the CLK_SET_RATE_PARENT flag or * .round_rate stops requesting changes to clk's parent_rate. * outcome of clk's .determine_rate implementation. If req->best_parent_rate * is unchanged after calling .determine_rate then upstream parent propagation * is ignored. If req->best_parent_rate comes back with a new rate for clk's * parent then we propagate up to clk's parent and set its rate. Upward * propagation will continue until either a clk does not support the * CLK_SET_RATE_PARENT flag or .determine_rate stops requesting changes to * clk's parent_rate. * * Rate changes are accomplished via tree traversal that also recalculates the * rates for the clocks and fires off POST_RATE_CHANGE notifiers. Loading Loading @@ -2703,8 +2695,6 @@ static int clk_set_rate_range_nolock(struct clk *clk, * FIXME: * There is a catch. It may fail for the usual reason (clock * broken, clock protected, etc) but also because: * - round_rate() was not favorable and fell on the wrong * side of the boundary * - the determine_rate() callback does not really check for * this corner case when determining the rate */ Loading Loading @@ -3915,10 +3905,9 @@ static int __clk_core_init(struct clk_core *core) } /* check that clk_ops are sane. See Documentation/driver-api/clk.rst */ if (core->ops->set_rate && !((core->ops->round_rate || core->ops->determine_rate) && core->ops->recalc_rate)) { pr_err("%s: %s must implement .round_rate or .determine_rate in addition to .recalc_rate\n", if (core->ops->set_rate && !core->ops->determine_rate && core->ops->recalc_rate) { pr_err("%s: %s must implement .determine_rate in addition to .recalc_rate\n", __func__, core->name); ret = -EINVAL; goto out; Loading include/linux/clk-provider.h +6 −12 Original line number Diff line number Diff line Loading @@ -136,10 +136,6 @@ struct clk_duty { * 0. Returns the calculated rate. Optional, but recommended - if * this op is not set then clock rate will be initialized to 0. * * @round_rate: Given a target rate as input, returns the closest rate actually * supported by the clock. The parent rate is an input/output * parameter. * * @determine_rate: Given a target rate as input, returns the closest rate * actually supported by the clock, and optionally the parent clock * that should be used to provide the clock rate. Loading @@ -163,13 +159,13 @@ struct clk_duty { * * @set_rate: Change the rate of this clock. The requested rate is specified * by the second argument, which should typically be the return * of .round_rate call. The third argument gives the parent rate * which is likely helpful for most .set_rate implementation. * of .determine_rate call. The third argument gives the parent * rate which is likely helpful for most .set_rate implementation. * Returns 0 on success, -EERROR otherwise. * * @set_rate_and_parent: Change the rate and the parent of this clock. The * requested rate is specified by the second argument, which * should typically be the return of .round_rate call. The * should typically be the return of clk_round_rate() call. The * third argument gives the parent rate which is likely helpful * for most .set_rate_and_parent implementation. The fourth * argument gives the parent index. This callback is optional (and Loading Loading @@ -244,8 +240,6 @@ struct clk_ops { void (*restore_context)(struct clk_hw *hw); unsigned long (*recalc_rate)(struct clk_hw *hw, unsigned long parent_rate); long (*round_rate)(struct clk_hw *hw, unsigned long rate, unsigned long *parent_rate); int (*determine_rate)(struct clk_hw *hw, struct clk_rate_request *req); int (*set_parent)(struct clk_hw *hw, u8 index); Loading Loading @@ -679,7 +673,7 @@ struct clk_div_table { * @lock: register lock * * Clock with an adjustable divider affecting its output frequency. Implements * .recalc_rate, .set_rate and .round_rate * .recalc_rate, .set_rate and .determine_rate * * @flags: * CLK_DIVIDER_ONE_BASED - by default the divisor is the value read from the Loading Loading @@ -1126,7 +1120,7 @@ void of_fixed_factor_clk_setup(struct device_node *node); * * Clock with a fixed multiplier and divider. The output frequency is the * parent clock rate divided by div and multiplied by mult. * Implements .recalc_rate, .set_rate, .round_rate and .recalc_accuracy * Implements .recalc_rate, .set_rate, .determine_rate and .recalc_accuracy * * Flags: * * CLK_FIXED_FACTOR_FIXED_ACCURACY - Use the value in @acc instead of the Loading Loading @@ -1254,7 +1248,7 @@ void clk_hw_unregister_fractional_divider(struct clk_hw *hw); * @lock: register lock * * Clock with an adjustable multiplier affecting its output frequency. * Implements .recalc_rate, .set_rate and .round_rate * Implements .recalc_rate, .set_rate and .determine_rate * * @flags: * CLK_MULTIPLIER_ZERO_BYPASS - By default, the multiplier is the value read Loading Loading
Documentation/driver-api/clk.rst +1 −8 Original line number Diff line number Diff line Loading @@ -77,9 +77,6 @@ the operations defined in clk-provider.h:: void (*disable_unused)(struct clk_hw *hw); unsigned long (*recalc_rate)(struct clk_hw *hw, unsigned long parent_rate); long (*round_rate)(struct clk_hw *hw, unsigned long rate, unsigned long *parent_rate); int (*determine_rate)(struct clk_hw *hw, struct clk_rate_request *req); int (*set_parent)(struct clk_hw *hw, u8 index); Loading Loading @@ -220,9 +217,7 @@ optional or must be evaluated on a case-by-case basis. +----------------+------+-------------+---------------+-------------+------+ |.recalc_rate | | y | | | | +----------------+------+-------------+---------------+-------------+------+ |.round_rate | | y [1]_ | | | | +----------------+------+-------------+---------------+-------------+------+ |.determine_rate | | y [1]_ | | | | |.determine_rate | | y | | | | +----------------+------+-------------+---------------+-------------+------+ |.set_rate | | y | | | | +----------------+------+-------------+---------------+-------------+------+ Loading @@ -238,8 +233,6 @@ optional or must be evaluated on a case-by-case basis. |.init | | | | | | +----------------+------+-------------+---------------+-------------+------+ .. [1] either one of round_rate or determine_rate is required. Finally, register your clock at run-time with a hardware-specific registration function. This function simply populates struct clk_foo's data and then passes the common struct clk parameters to the framework Loading
drivers/clk/clk.c +14 −25 Original line number Diff line number Diff line Loading @@ -1560,8 +1560,6 @@ late_initcall_sync(clk_disable_unused); static int clk_core_determine_round_nolock(struct clk_core *core, struct clk_rate_request *req) { long rate; lockdep_assert_held(&prepare_lock); if (!core) Loading Loading @@ -1591,13 +1589,6 @@ static int clk_core_determine_round_nolock(struct clk_core *core, req->rate = core->rate; } else 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; req->rate = rate; } else { return -EINVAL; } Loading Loading @@ -1682,7 +1673,7 @@ EXPORT_SYMBOL_GPL(clk_hw_forward_rate_request); static bool clk_core_can_round(struct clk_core * const core) { return core->ops->determine_rate || core->ops->round_rate; return core->ops->determine_rate; } static int clk_core_round_rate_nolock(struct clk_core *core, Loading Loading @@ -1750,11 +1741,11 @@ EXPORT_SYMBOL_GPL(__clk_determine_rate); * use. * * Context: prepare_lock must be held. * For clk providers to call from within clk_ops such as .round_rate, * For clk providers to call from within clk_ops such as * .determine_rate. * * Return: returns rounded rate of hw clk if clk supports round_rate operation * else returns the parent rate. * Return: returns rounded rate of hw clk if clk supports determine_rate * operation; else returns the parent rate. */ unsigned long clk_hw_round_rate(struct clk_hw *hw, unsigned long rate) { Loading Loading @@ -2569,12 +2560,13 @@ static int clk_core_set_rate_nolock(struct clk_core *core, * * Setting the CLK_SET_RATE_PARENT flag allows the rate change operation to * propagate up to clk's parent; whether or not this happens depends on the * outcome of clk's .round_rate implementation. If *parent_rate is unchanged * after calling .round_rate then upstream parent propagation is ignored. If * *parent_rate comes back with a new rate for clk's parent then we propagate * up to clk's parent and set its rate. Upward propagation will continue * until either a clk does not support the CLK_SET_RATE_PARENT flag or * .round_rate stops requesting changes to clk's parent_rate. * outcome of clk's .determine_rate implementation. If req->best_parent_rate * is unchanged after calling .determine_rate then upstream parent propagation * is ignored. If req->best_parent_rate comes back with a new rate for clk's * parent then we propagate up to clk's parent and set its rate. Upward * propagation will continue until either a clk does not support the * CLK_SET_RATE_PARENT flag or .determine_rate stops requesting changes to * clk's parent_rate. * * Rate changes are accomplished via tree traversal that also recalculates the * rates for the clocks and fires off POST_RATE_CHANGE notifiers. Loading Loading @@ -2703,8 +2695,6 @@ static int clk_set_rate_range_nolock(struct clk *clk, * FIXME: * There is a catch. It may fail for the usual reason (clock * broken, clock protected, etc) but also because: * - round_rate() was not favorable and fell on the wrong * side of the boundary * - the determine_rate() callback does not really check for * this corner case when determining the rate */ Loading Loading @@ -3915,10 +3905,9 @@ static int __clk_core_init(struct clk_core *core) } /* check that clk_ops are sane. See Documentation/driver-api/clk.rst */ if (core->ops->set_rate && !((core->ops->round_rate || core->ops->determine_rate) && core->ops->recalc_rate)) { pr_err("%s: %s must implement .round_rate or .determine_rate in addition to .recalc_rate\n", if (core->ops->set_rate && !core->ops->determine_rate && core->ops->recalc_rate) { pr_err("%s: %s must implement .determine_rate in addition to .recalc_rate\n", __func__, core->name); ret = -EINVAL; goto out; Loading
include/linux/clk-provider.h +6 −12 Original line number Diff line number Diff line Loading @@ -136,10 +136,6 @@ struct clk_duty { * 0. Returns the calculated rate. Optional, but recommended - if * this op is not set then clock rate will be initialized to 0. * * @round_rate: Given a target rate as input, returns the closest rate actually * supported by the clock. The parent rate is an input/output * parameter. * * @determine_rate: Given a target rate as input, returns the closest rate * actually supported by the clock, and optionally the parent clock * that should be used to provide the clock rate. Loading @@ -163,13 +159,13 @@ struct clk_duty { * * @set_rate: Change the rate of this clock. The requested rate is specified * by the second argument, which should typically be the return * of .round_rate call. The third argument gives the parent rate * which is likely helpful for most .set_rate implementation. * of .determine_rate call. The third argument gives the parent * rate which is likely helpful for most .set_rate implementation. * Returns 0 on success, -EERROR otherwise. * * @set_rate_and_parent: Change the rate and the parent of this clock. The * requested rate is specified by the second argument, which * should typically be the return of .round_rate call. The * should typically be the return of clk_round_rate() call. The * third argument gives the parent rate which is likely helpful * for most .set_rate_and_parent implementation. The fourth * argument gives the parent index. This callback is optional (and Loading Loading @@ -244,8 +240,6 @@ struct clk_ops { void (*restore_context)(struct clk_hw *hw); unsigned long (*recalc_rate)(struct clk_hw *hw, unsigned long parent_rate); long (*round_rate)(struct clk_hw *hw, unsigned long rate, unsigned long *parent_rate); int (*determine_rate)(struct clk_hw *hw, struct clk_rate_request *req); int (*set_parent)(struct clk_hw *hw, u8 index); Loading Loading @@ -679,7 +673,7 @@ struct clk_div_table { * @lock: register lock * * Clock with an adjustable divider affecting its output frequency. Implements * .recalc_rate, .set_rate and .round_rate * .recalc_rate, .set_rate and .determine_rate * * @flags: * CLK_DIVIDER_ONE_BASED - by default the divisor is the value read from the Loading Loading @@ -1126,7 +1120,7 @@ void of_fixed_factor_clk_setup(struct device_node *node); * * Clock with a fixed multiplier and divider. The output frequency is the * parent clock rate divided by div and multiplied by mult. * Implements .recalc_rate, .set_rate, .round_rate and .recalc_accuracy * Implements .recalc_rate, .set_rate, .determine_rate and .recalc_accuracy * * Flags: * * CLK_FIXED_FACTOR_FIXED_ACCURACY - Use the value in @acc instead of the Loading Loading @@ -1254,7 +1248,7 @@ void clk_hw_unregister_fractional_divider(struct clk_hw *hw); * @lock: register lock * * Clock with an adjustable multiplier affecting its output frequency. * Implements .recalc_rate, .set_rate and .round_rate * Implements .recalc_rate, .set_rate and .determine_rate * * @flags: * CLK_MULTIPLIER_ZERO_BYPASS - By default, the multiplier is the value read Loading