diff for duplicates of <20180619170737.33232.41279@harbor.lan> diff --git a/a/1.txt b/N1/1.txt index eeae440..a68664c 100644 --- a/a/1.txt +++ b/N1/1.txt @@ -1,23 +1,18 @@ Quoting Jerome Brunet (2018-06-19 07:41:41) > Add the possibility to apply and query the clock signal duty cycle ratio. -> = - +> > This is useful when the duty cycle of the clock signal depends on some > other parameters controlled by the clock framework. -> = - +> > For example, the duty cycle of a divider may depends on the raw divider -> setting (ratio =3D N / div) , which is controlled by the CCF. In such cas= -e, +> setting (ratio = N / div) , which is controlled by the CCF. In such case, > going through the pwm framework to control the duty cycle ratio of this > clock would be a burden. -> = - +> > A clock provider is not required to implement the operation to set and get > the duty cycle. If it does not implement .get_duty_cycle(), the ratio is > assumed to be 50%. -> = - +> > This change also adds a new flag, CLK_DUTY_CYCLE_PARENT. This flag should > be used to indicate that a clock, such as gates and muxes, may inherit > the duty cycle ratio of its parent clock. If a clock does not provide a @@ -25,8 +20,7 @@ e, > will be directly forwarded to its parent clock, if any. For > set_duty_cycle(), the clock should also have CLK_SET_RATE_PARENT for the > call to be forwarded -> = - +> > Signed-off-by: Jerome Brunet <jbrunet@baylibre.com> Applied to clk-core-duty-cycle. @@ -35,44 +29,36 @@ Regards, Mike > --- -> = - +> > The series has been developed to handled the sample clocks provided by > audio clock controller of amlogic's A113 SoC. To support i2s modes, this > clock need to have a 50% duty cycle ratio, while it should be just one > pulse of the parent clock in dsp modes. -> = - +> > Changes since v3 [2]: > - rebased on top of v4.18-rc1 -> = - +> > Changes since v2 [1]: > - Fix kbuild robot issue with the trace file (imcomplete change related > to clk_duty structure) -> = - +> > Changes since v1 [0]: > - Use a structure to hold the duty cycle ratio > - Change the way parent traversal is done, so the core framework is > more aware of what is going on. Pass-through ops dropped as a result > - Only one debugfs entry for the duty cycle ratio, instead of 2 > - Minor fixes as pointed out by Stephen -> = - +> > [0]: https://lkml.kernel.org/r/20180416175743.20826-1-jbrunet@baylibre.com > [1]: https://lkml.kernel.org/r/20180420153431.13003-1-jbrunet@baylibre.com > [2]: https://lkml.kernel.org/r/20180420211141.28929-1-jbrunet@baylibre.com -> = - -> drivers/clk/clk.c | 199 +++++++++++++++++++++++++++++++++++++= -++++-- +> +> drivers/clk/clk.c | 199 +++++++++++++++++++++++++++++++++++++++++-- > include/linux/clk-provider.h | 26 ++++++ > include/linux/clk.h | 33 +++++++ > include/trace/events/clk.h | 36 ++++++++ > 4 files changed, 289 insertions(+), 5 deletions(-) -> = - +> > diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c > index 97c09243fb21..e108f591d84a 100644 > --- a/drivers/clk/clk.c @@ -88,33 +74,31 @@ Mike > @@ -2412,6 +2413,172 @@ int clk_get_phase(struct clk *clk) > } > EXPORT_SYMBOL_GPL(clk_get_phase); -> = - +> > +static void clk_core_reset_duty_cycle_nolock(struct clk_core *core) > +{ > + /* Assume a default value of 50% */ -> + core->duty.num =3D 1; -> + core->duty.den =3D 2; +> + core->duty.num = 1; +> + core->duty.den = 2; > +} > + -> +static int clk_core_update_duty_cycle_parent_nolock(struct clk_core *cor= -e); +> +static int clk_core_update_duty_cycle_parent_nolock(struct clk_core *core); > + > +static int clk_core_update_duty_cycle_nolock(struct clk_core *core) > +{ -> + struct clk_duty *duty =3D &core->duty; -> + int ret =3D 0; +> + struct clk_duty *duty = &core->duty; +> + int ret = 0; > + > + if (!core->ops->get_duty_cycle) > + return clk_core_update_duty_cycle_parent_nolock(core); > + -> + ret =3D core->ops->get_duty_cycle(core->hw, duty); +> + ret = core->ops->get_duty_cycle(core->hw, duty); > + if (ret) > + goto reset; > + > + /* Don't trust the clock provider too much */ -> + if (duty->den =3D=3D 0 || duty->num > duty->den) { -> + ret =3D -EINVAL; +> + if (duty->den == 0 || duty->num > duty->den) { +> + ret = -EINVAL; > + goto reset; > + } > + @@ -125,16 +109,14 @@ e); > + return ret; > +} > + -> +static int clk_core_update_duty_cycle_parent_nolock(struct clk_core *cor= -e) +> +static int clk_core_update_duty_cycle_parent_nolock(struct clk_core *core) > +{ -> + int ret =3D 0; +> + int ret = 0; > + > + if (core->parent && > + core->flags & CLK_DUTY_CYCLE_PARENT) { -> + ret =3D clk_core_update_duty_cycle_nolock(core->parent); -> + memcpy(&core->duty, &core->parent->duty, sizeof(core->dut= -y)); +> + ret = clk_core_update_duty_cycle_nolock(core->parent); +> + memcpy(&core->duty, &core->parent->duty, sizeof(core->duty)); > + } else { > + clk_core_reset_duty_cycle_nolock(core); > + } @@ -160,7 +142,7 @@ y)); > + if (!core->ops->set_duty_cycle) > + return clk_core_set_duty_cycle_parent_nolock(core, duty); > + -> + ret =3D core->ops->set_duty_cycle(core->hw, duty); +> + ret = core->ops->set_duty_cycle(core->hw, duty); > + if (!ret) > + memcpy(&core->duty, duty, sizeof(*duty)); > + @@ -172,14 +154,12 @@ y)); > +static int clk_core_set_duty_cycle_parent_nolock(struct clk_core *core, > + struct clk_duty *duty) > +{ -> + int ret =3D 0; +> + int ret = 0; > + > + if (core->parent && > + core->flags & (CLK_DUTY_CYCLE_PARENT | CLK_SET_RATE_PARENT)) { -> + ret =3D clk_core_set_duty_cycle_nolock(core->parent, duty= -); -> + memcpy(&core->duty, &core->parent->duty, sizeof(core->dut= -y)); +> + ret = clk_core_set_duty_cycle_nolock(core->parent, duty); +> + memcpy(&core->duty, &core->parent->duty, sizeof(core->duty)); > + } > + > + return ret; @@ -196,8 +176,7 @@ y)); > + * > + * Returns (0) on success, a negative errno otherwise. > + */ -> +int clk_set_duty_cycle(struct clk *clk, unsigned int num, unsigned int d= -en) +> +int clk_set_duty_cycle(struct clk *clk, unsigned int num, unsigned int den) > +{ > + int ret; > + struct clk_duty duty; @@ -206,18 +185,18 @@ en) > + return 0; > + > + /* sanity check the ratio */ -> + if (den =3D=3D 0 || num > den) +> + if (den == 0 || num > den) > + return -EINVAL; > + -> + duty.num =3D num; -> + duty.den =3D den; +> + duty.num = num; +> + duty.den = den; > + > + clk_prepare_lock(); > + > + if (clk->exclusive_count) > + clk_core_rate_unprotect(clk->core); > + -> + ret =3D clk_core_set_duty_cycle_nolock(clk->core, &duty); +> + ret = clk_core_set_duty_cycle_nolock(clk->core, &duty); > + > + if (clk->exclusive_count) > + clk_core_rate_protect(clk->core); @@ -231,14 +210,14 @@ en) > +static int clk_core_get_scaled_duty_cycle(struct clk_core *core, > + unsigned int scale) > +{ -> + struct clk_duty *duty =3D &core->duty; +> + struct clk_duty *duty = &core->duty; > + int ret; > + > + clk_prepare_lock(); > + -> + ret =3D clk_core_update_duty_cycle_nolock(core); +> + ret = clk_core_update_duty_cycle_nolock(core); > + if (!ret) -> + ret =3D mult_frac(scale, duty->num, duty->den); +> + ret = mult_frac(scale, duty->num, duty->den); > + > + clk_prepare_unlock(); > + @@ -246,14 +225,11 @@ en) > +} > + > +/** -> + * clk_get_scaled_duty_cycle - return the duty cycle ratio of a clock si= -gnal +> + * clk_get_scaled_duty_cycle - return the duty cycle ratio of a clock signal > + * @clk: clock signal source -> + * @scale: scaling factor to be applied to represent the ratio as an int= -eger +> + * @scale: scaling factor to be applied to represent the ratio as an integer > + * -> + * Returns the duty cycle ratio of a clock node multiplied by the provid= -ed +> + * Returns the duty cycle ratio of a clock node multiplied by the provided > + * scaling factor, or negative errno on error. > + */ > +int clk_get_scaled_duty_cycle(struct clk *clk, unsigned int scale) @@ -268,12 +244,10 @@ ed > /** > * clk_is_match - check if two clk's point to the same hardware clock > * @p: clk compared against q -> @@ -2465,12 +2632,13 @@ static void clk_summary_show_one(struct seq_file = -*s, struct clk_core *c, +> @@ -2465,12 +2632,13 @@ static void clk_summary_show_one(struct seq_file *s, struct clk_core *c, > if (!c) > return; -> = - +> > - seq_printf(s, "%*s%-*s %7d %8d %8d %11lu %10lu %-3d\n", > + seq_printf(s, "%*s%-*s %7d %8d %8d %11lu %10lu %5d %6d\n", > level * 3 + 1, "", @@ -284,45 +258,30 @@ ed > + clk_core_get_phase(c), > + clk_core_get_scaled_duty_cycle(c, 100000)); > } -> = - -> static void clk_summary_show_subtree(struct seq_file *s, struct clk_core= - *c, -> @@ -2492,9 +2660,9 @@ static int clk_summary_show(struct seq_file *s, voi= -d *data) +> +> static void clk_summary_show_subtree(struct seq_file *s, struct clk_core *c, +> @@ -2492,9 +2660,9 @@ static int clk_summary_show(struct seq_file *s, void *data) > struct clk_core *c; -> struct hlist_head **lists =3D (struct hlist_head **)s->private; -> = - -> - seq_puts(s, " enable prepare pr= -otect \n"); -> - seq_puts(s, " clock count count = -count rate accuracy phase\n"); -> - seq_puts(s, "----------------------------------------------------= -------------------------------------\n"); -> + seq_puts(s, " enable prepare pr= -otect duty\n"); -> + seq_puts(s, " clock count count = -count rate accuracy phase cycle\n"); -> + seq_puts(s, "----------------------------------------------------= ------------------------------------------\n"); -> = - +> struct hlist_head **lists = (struct hlist_head **)s->private; +> +> - seq_puts(s, " enable prepare protect \n"); +> - seq_puts(s, " clock count count count rate accuracy phase\n"); +> - seq_puts(s, "----------------------------------------------------------------------------------------\n"); +> + seq_puts(s, " enable prepare protect duty\n"); +> + seq_puts(s, " clock count count count rate accuracy phase cycle\n"); +> + seq_puts(s, "---------------------------------------------------------------------------------------------\n"); +> > clk_prepare_lock(); -> = - -> @@ -2521,6 +2689,8 @@ static void clk_dump_one(struct seq_file *s, struct= - clk_core *c, int level) +> +> @@ -2521,6 +2689,8 @@ static void clk_dump_one(struct seq_file *s, struct clk_core *c, int level) > seq_printf(s, "\"rate\": %lu,", clk_core_get_rate(c)); > seq_printf(s, "\"accuracy\": %lu,", clk_core_get_accuracy(c)); > seq_printf(s, "\"phase\": %d", clk_core_get_phase(c)); > + seq_printf(s, "\"duty_cycle\": %u", > + clk_core_get_scaled_duty_cycle(c, 100000)); > } -> = - -> static void clk_dump_subtree(struct seq_file *s, struct clk_core *c, int= - level) +> +> static void clk_dump_subtree(struct seq_file *s, struct clk_core *c, int level) > @@ -2582,6 +2752,7 @@ static const struct { > ENTRY(CLK_SET_RATE_UNGATE), > ENTRY(CLK_IS_CRITICAL), @@ -330,18 +289,15 @@ count rate accuracy phase cycle\n"); > + ENTRY(CLK_DUTY_CYCLE_PARENT), > #undef ENTRY > }; -> = - -> @@ -2620,6 +2791,17 @@ static int possible_parents_show(struct seq_file *= -s, void *data) +> +> @@ -2620,6 +2791,17 @@ static int possible_parents_show(struct seq_file *s, void *data) > } > DEFINE_SHOW_ATTRIBUTE(possible_parents); -> = - +> > +static int clk_duty_cycle_show(struct seq_file *s, void *data) > +{ -> + struct clk_core *core =3D s->private; -> + struct clk_duty *duty =3D &core->duty; +> + struct clk_core *core = s->private; +> + struct clk_duty *duty = &core->duty; > + > + seq_printf(s, "%u/%u\n", duty->num, duty->den); > + @@ -349,40 +305,30 @@ s, void *data) > +} > +DEFINE_SHOW_ATTRIBUTE(clk_duty_cycle); > + -> static void clk_debug_create_one(struct clk_core *core, struct dentry *p= -dentry) +> static void clk_debug_create_one(struct clk_core *core, struct dentry *pdentry) > { > struct dentry *root; -> @@ -2638,6 +2820,8 @@ static void clk_debug_create_one(struct clk_core *c= -ore, struct dentry *pdentry) -> debugfs_create_u32("clk_enable_count", 0444, root, &core->enable_= -count); -> debugfs_create_u32("clk_protect_count", 0444, root, &core->protec= -t_count); -> debugfs_create_u32("clk_notifier_count", 0444, root, &core->notif= -ier_count); +> @@ -2638,6 +2820,8 @@ static void clk_debug_create_one(struct clk_core *core, struct dentry *pdentry) +> debugfs_create_u32("clk_enable_count", 0444, root, &core->enable_count); +> debugfs_create_u32("clk_protect_count", 0444, root, &core->protect_count); +> debugfs_create_u32("clk_notifier_count", 0444, root, &core->notifier_count); > + debugfs_create_file("clk_duty_cycle", 0444, root, core, > + &clk_duty_cycle_fops); -> = - +> > if (core->num_parents > 1) -> debugfs_create_file("clk_possible_parents", 0444, root, c= -ore, +> debugfs_create_file("clk_possible_parents", 0444, root, core, > @@ -2855,6 +3039,11 @@ static int __clk_core_init(struct clk_core *core) > else -> core->phase =3D 0; -> = - +> core->phase = 0; +> > + /* > + * Set clk's duty cycle. > + */ > + clk_core_update_duty_cycle_nolock(core); > + > /* -> * Set clk's rate. The preferred method is to use .recalc_rate. = - For -> * simple clocks and lazy developers the default fallback is to u= -se the +> * Set clk's rate. The preferred method is to use .recalc_rate. For +> * simple clocks and lazy developers the default fallback is to use the > diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h > index b7cfa037e593..08b1aa70a38d 100644 > --- a/include/linux/clk-provider.h @@ -393,15 +339,13 @@ se the > #define CLK_OPS_PARENT_ENABLE BIT(12) > +/* duty cycle call may be forwarded to the parent clock */ > +#define CLK_DUTY_CYCLE_PARENT BIT(13) -> = - +> > struct clk; > struct clk_hw; > @@ -66,6 +68,17 @@ struct clk_rate_request { > struct clk_hw *best_parent_hw; > }; -> = - +> > +/** > + * struct clk_duty - Struture encoding the duty cycle ratio of a clock > + * @@ -414,31 +358,24 @@ se the > +}; > + > /** -> * struct clk_ops - Callback operations for hardware clocks; these are = -to +> * struct clk_ops - Callback operations for hardware clocks; these are to > * be provided by the clock implementation, and will be called by drivers > @@ -169,6 +182,15 @@ struct clk_rate_request { > * by the second argument. Valid values for degrees are > * 0-359. Return 0 on success, otherwise -EERROR. > * -> + * @get_duty_cycle: Queries the hardware to get the current duty cycle r= -atio -> + * of a clock. Returned values denominator cannot be 0 and = -must be +> + * @get_duty_cycle: Queries the hardware to get the current duty cycle ratio +> + * of a clock. Returned values denominator cannot be 0 and must be > + * superior or equal to the numerator. > + * -> + * @set_duty_cycle: Apply the duty cycle ratio to this clock signal spec= -ified by -> + * the numerator (2nd argurment) and denominator (3rd argu= -ment). +> + * @set_duty_cycle: Apply the duty cycle ratio to this clock signal specified by +> + * the numerator (2nd argurment) and denominator (3rd argument). > + * Argument must be a valid ratio (denominator > 0 -> + * and >=3D numerator) Return 0 on success, otherwise -EERR= -OR. +> + * and >= numerator) Return 0 on success, otherwise -EERROR. > + * > * @init: Perform platform-specific initialization magic. > * This is not not used by any of the basic clock types. -> * Please consider other ways of solving initialization prob= -lems +> * Please consider other ways of solving initialization problems > @@ -218,6 +240,10 @@ struct clk_ops { > unsigned long parent_accuracy); > int (*get_phase)(struct clk_hw *hw); @@ -448,8 +385,7 @@ lems > + int (*set_duty_cycle)(struct clk_hw *hw, > + struct clk_duty *duty); > void (*init)(struct clk_hw *hw); -> void (*debug_init)(struct clk_hw *hw, struct dentry *d= -entry); +> void (*debug_init)(struct clk_hw *hw, struct dentry *dentry); > }; > diff --git a/include/linux/clk.h b/include/linux/clk.h > index 0dbd0885b2c2..4f750c481b82 100644 @@ -458,29 +394,24 @@ entry); > @@ -141,6 +141,27 @@ int clk_set_phase(struct clk *clk, int degrees); > */ > int clk_get_phase(struct clk *clk); -> = - +> > +/** > + * clk_set_duty_cycle - adjust the duty cycle ratio of a clock signal > + * @clk: clock signal source > + * @num: numerator of the duty cycle ratio to be applied > + * @den: denominator of the duty cycle ratio to be applied > + * -> + * Adjust the duty cycle of a clock signal by the specified ratio. Retur= -ns 0 on +> + * Adjust the duty cycle of a clock signal by the specified ratio. Returns 0 on > + * success, -EERROR otherwise. > + */ -> +int clk_set_duty_cycle(struct clk *clk, unsigned int num, unsigned int d= -en); +> +int clk_set_duty_cycle(struct clk *clk, unsigned int num, unsigned int den); > + > +/** > + * clk_get_duty_cycle - return the duty cycle ratio of a clock signal > + * @clk: clock signal source -> + * @scale: scaling factor to be applied to represent the ratio as an int= -eger +> + * @scale: scaling factor to be applied to represent the ratio as an integer > + * -> + * Returns the duty cycle ratio multiplied by the scale provided, otherw= -ise +> + * Returns the duty cycle ratio multiplied by the scale provided, otherwise > + * returns -EERROR. > + */ > +int clk_get_scaled_duty_cycle(struct clk *clk, unsigned int scale); @@ -491,8 +422,7 @@ ise > @@ -183,6 +204,18 @@ static inline long clk_get_phase(struct clk *clk) > return -ENOTSUPP; > } -> = - +> > +static inline int clk_set_duty_cycle(struct clk *clk, unsigned int num, > + unsigned int den) > +{ @@ -507,7 +437,7 @@ ise > + > static inline bool clk_is_match(const struct clk *p, const struct clk *q) > { -> return p =3D=3D q; +> return p == q; > diff --git a/include/trace/events/clk.h b/include/trace/events/clk.h > index 2cd449328aee..9004ffff7f32 100644 > --- a/include/trace/events/clk.h @@ -515,8 +445,7 @@ ise > @@ -192,6 +192,42 @@ DEFINE_EVENT(clk_phase, clk_set_phase_complete, > TP_ARGS(core, phase) > ); -> = - +> > +DECLARE_EVENT_CLASS(clk_duty_cycle, > + > + TP_PROTO(struct clk_core *core, struct clk_duty *duty), @@ -531,8 +460,8 @@ ise > + > + TP_fast_assign( > + __assign_str(name, core->name); -> + __entry->num =3D duty->num; -> + __entry->den =3D duty->den; +> + __entry->num = duty->num; +> + __entry->den = duty->den; > + ), > + > + TP_printk("%s %u/%u", __get_str(name), (unsigned int)__entry->num, @@ -554,10 +483,8 @@ ise > +); > + > #endif /* _TRACE_CLK_H */ -> = - +> > /* This part must be outside protection */ -> -- = - +> -- > 2.14.3 ->=20 +> diff --git a/a/content_digest b/N1/content_digest index 7814ce1..d637d00 100644 --- a/a/content_digest +++ b/N1/content_digest @@ -14,24 +14,19 @@ "b\0" "Quoting Jerome Brunet (2018-06-19 07:41:41)\n" "> Add the possibility to apply and query the clock signal duty cycle ratio.\n" - "> =\n" - "\n" + "> \n" "> This is useful when the duty cycle of the clock signal depends on some\n" "> other parameters controlled by the clock framework.\n" - "> =\n" - "\n" + "> \n" "> For example, the duty cycle of a divider may depends on the raw divider\n" - "> setting (ratio =3D N / div) , which is controlled by the CCF. In such cas=\n" - "e,\n" + "> setting (ratio = N / div) , which is controlled by the CCF. In such case,\n" "> going through the pwm framework to control the duty cycle ratio of this\n" "> clock would be a burden.\n" - "> =\n" - "\n" + "> \n" "> A clock provider is not required to implement the operation to set and get\n" "> the duty cycle. If it does not implement .get_duty_cycle(), the ratio is\n" "> assumed to be 50%.\n" - "> =\n" - "\n" + "> \n" "> This change also adds a new flag, CLK_DUTY_CYCLE_PARENT. This flag should\n" "> be used to indicate that a clock, such as gates and muxes, may inherit\n" "> the duty cycle ratio of its parent clock. If a clock does not provide a\n" @@ -39,8 +34,7 @@ "> will be directly forwarded to its parent clock, if any. For\n" "> set_duty_cycle(), the clock should also have CLK_SET_RATE_PARENT for the\n" "> call to be forwarded\n" - "> =\n" - "\n" + "> \n" "> Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>\n" "\n" "Applied to clk-core-duty-cycle.\n" @@ -49,44 +43,36 @@ "Mike\n" "\n" "> ---\n" - "> =\n" - "\n" + "> \n" "> The series has been developed to handled the sample clocks provided by\n" "> audio clock controller of amlogic's A113 SoC. To support i2s modes, this\n" "> clock need to have a 50% duty cycle ratio, while it should be just one\n" "> pulse of the parent clock in dsp modes.\n" - "> =\n" - "\n" + "> \n" "> Changes since v3 [2]:\n" "> - rebased on top of v4.18-rc1\n" - "> =\n" - "\n" + "> \n" "> Changes since v2 [1]:\n" "> - Fix kbuild robot issue with the trace file (imcomplete change related\n" "> to clk_duty structure)\n" - "> =\n" - "\n" + "> \n" "> Changes since v1 [0]:\n" "> - Use a structure to hold the duty cycle ratio\n" "> - Change the way parent traversal is done, so the core framework is\n" "> more aware of what is going on. Pass-through ops dropped as a result\n" "> - Only one debugfs entry for the duty cycle ratio, instead of 2\n" "> - Minor fixes as pointed out by Stephen\n" - "> =\n" - "\n" + "> \n" "> [0]: https://lkml.kernel.org/r/20180416175743.20826-1-jbrunet@baylibre.com\n" "> [1]: https://lkml.kernel.org/r/20180420153431.13003-1-jbrunet@baylibre.com\n" "> [2]: https://lkml.kernel.org/r/20180420211141.28929-1-jbrunet@baylibre.com\n" - "> =\n" - "\n" - "> drivers/clk/clk.c | 199 +++++++++++++++++++++++++++++++++++++=\n" - "++++--\n" + "> \n" + "> drivers/clk/clk.c | 199 +++++++++++++++++++++++++++++++++++++++++--\n" "> include/linux/clk-provider.h | 26 ++++++\n" "> include/linux/clk.h | 33 +++++++\n" "> include/trace/events/clk.h | 36 ++++++++\n" "> 4 files changed, 289 insertions(+), 5 deletions(-)\n" - "> =\n" - "\n" + "> \n" "> diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c\n" "> index 97c09243fb21..e108f591d84a 100644\n" "> --- a/drivers/clk/clk.c\n" @@ -102,33 +88,31 @@ "> @@ -2412,6 +2413,172 @@ int clk_get_phase(struct clk *clk)\n" "> }\n" "> EXPORT_SYMBOL_GPL(clk_get_phase);\n" - "> =\n" - "\n" + "> \n" "> +static void clk_core_reset_duty_cycle_nolock(struct clk_core *core)\n" "> +{\n" "> + /* Assume a default value of 50% */\n" - "> + core->duty.num =3D 1;\n" - "> + core->duty.den =3D 2;\n" + "> + core->duty.num = 1;\n" + "> + core->duty.den = 2;\n" "> +}\n" "> +\n" - "> +static int clk_core_update_duty_cycle_parent_nolock(struct clk_core *cor=\n" - "e);\n" + "> +static int clk_core_update_duty_cycle_parent_nolock(struct clk_core *core);\n" "> +\n" "> +static int clk_core_update_duty_cycle_nolock(struct clk_core *core)\n" "> +{\n" - "> + struct clk_duty *duty =3D &core->duty;\n" - "> + int ret =3D 0;\n" + "> + struct clk_duty *duty = &core->duty;\n" + "> + int ret = 0;\n" "> +\n" "> + if (!core->ops->get_duty_cycle)\n" "> + return clk_core_update_duty_cycle_parent_nolock(core);\n" "> +\n" - "> + ret =3D core->ops->get_duty_cycle(core->hw, duty);\n" + "> + ret = core->ops->get_duty_cycle(core->hw, duty);\n" "> + if (ret)\n" "> + goto reset;\n" "> +\n" "> + /* Don't trust the clock provider too much */\n" - "> + if (duty->den =3D=3D 0 || duty->num > duty->den) {\n" - "> + ret =3D -EINVAL;\n" + "> + if (duty->den == 0 || duty->num > duty->den) {\n" + "> + ret = -EINVAL;\n" "> + goto reset;\n" "> + }\n" "> +\n" @@ -139,16 +123,14 @@ "> + return ret;\n" "> +}\n" "> +\n" - "> +static int clk_core_update_duty_cycle_parent_nolock(struct clk_core *cor=\n" - "e)\n" + "> +static int clk_core_update_duty_cycle_parent_nolock(struct clk_core *core)\n" "> +{\n" - "> + int ret =3D 0;\n" + "> + int ret = 0;\n" "> +\n" "> + if (core->parent &&\n" "> + core->flags & CLK_DUTY_CYCLE_PARENT) {\n" - "> + ret =3D clk_core_update_duty_cycle_nolock(core->parent);\n" - "> + memcpy(&core->duty, &core->parent->duty, sizeof(core->dut=\n" - "y));\n" + "> + ret = clk_core_update_duty_cycle_nolock(core->parent);\n" + "> + memcpy(&core->duty, &core->parent->duty, sizeof(core->duty));\n" "> + } else {\n" "> + clk_core_reset_duty_cycle_nolock(core);\n" "> + }\n" @@ -174,7 +156,7 @@ "> + if (!core->ops->set_duty_cycle)\n" "> + return clk_core_set_duty_cycle_parent_nolock(core, duty);\n" "> +\n" - "> + ret =3D core->ops->set_duty_cycle(core->hw, duty);\n" + "> + ret = core->ops->set_duty_cycle(core->hw, duty);\n" "> + if (!ret)\n" "> + memcpy(&core->duty, duty, sizeof(*duty));\n" "> +\n" @@ -186,14 +168,12 @@ "> +static int clk_core_set_duty_cycle_parent_nolock(struct clk_core *core,\n" "> + struct clk_duty *duty)\n" "> +{\n" - "> + int ret =3D 0;\n" + "> + int ret = 0;\n" "> +\n" "> + if (core->parent &&\n" "> + core->flags & (CLK_DUTY_CYCLE_PARENT | CLK_SET_RATE_PARENT)) {\n" - "> + ret =3D clk_core_set_duty_cycle_nolock(core->parent, duty=\n" - ");\n" - "> + memcpy(&core->duty, &core->parent->duty, sizeof(core->dut=\n" - "y));\n" + "> + ret = clk_core_set_duty_cycle_nolock(core->parent, duty);\n" + "> + memcpy(&core->duty, &core->parent->duty, sizeof(core->duty));\n" "> + }\n" "> +\n" "> + return ret;\n" @@ -210,8 +190,7 @@ "> + *\n" "> + * Returns (0) on success, a negative errno otherwise.\n" "> + */\n" - "> +int clk_set_duty_cycle(struct clk *clk, unsigned int num, unsigned int d=\n" - "en)\n" + "> +int clk_set_duty_cycle(struct clk *clk, unsigned int num, unsigned int den)\n" "> +{\n" "> + int ret;\n" "> + struct clk_duty duty;\n" @@ -220,18 +199,18 @@ "> + return 0;\n" "> +\n" "> + /* sanity check the ratio */\n" - "> + if (den =3D=3D 0 || num > den)\n" + "> + if (den == 0 || num > den)\n" "> + return -EINVAL;\n" "> +\n" - "> + duty.num =3D num;\n" - "> + duty.den =3D den;\n" + "> + duty.num = num;\n" + "> + duty.den = den;\n" "> +\n" "> + clk_prepare_lock();\n" "> +\n" "> + if (clk->exclusive_count)\n" "> + clk_core_rate_unprotect(clk->core);\n" "> +\n" - "> + ret =3D clk_core_set_duty_cycle_nolock(clk->core, &duty);\n" + "> + ret = clk_core_set_duty_cycle_nolock(clk->core, &duty);\n" "> +\n" "> + if (clk->exclusive_count)\n" "> + clk_core_rate_protect(clk->core);\n" @@ -245,14 +224,14 @@ "> +static int clk_core_get_scaled_duty_cycle(struct clk_core *core,\n" "> + unsigned int scale)\n" "> +{\n" - "> + struct clk_duty *duty =3D &core->duty;\n" + "> + struct clk_duty *duty = &core->duty;\n" "> + int ret;\n" "> +\n" "> + clk_prepare_lock();\n" "> +\n" - "> + ret =3D clk_core_update_duty_cycle_nolock(core);\n" + "> + ret = clk_core_update_duty_cycle_nolock(core);\n" "> + if (!ret)\n" - "> + ret =3D mult_frac(scale, duty->num, duty->den);\n" + "> + ret = mult_frac(scale, duty->num, duty->den);\n" "> +\n" "> + clk_prepare_unlock();\n" "> +\n" @@ -260,14 +239,11 @@ "> +}\n" "> +\n" "> +/**\n" - "> + * clk_get_scaled_duty_cycle - return the duty cycle ratio of a clock si=\n" - "gnal\n" + "> + * clk_get_scaled_duty_cycle - return the duty cycle ratio of a clock signal\n" "> + * @clk: clock signal source\n" - "> + * @scale: scaling factor to be applied to represent the ratio as an int=\n" - "eger\n" + "> + * @scale: scaling factor to be applied to represent the ratio as an integer\n" "> + *\n" - "> + * Returns the duty cycle ratio of a clock node multiplied by the provid=\n" - "ed\n" + "> + * Returns the duty cycle ratio of a clock node multiplied by the provided\n" "> + * scaling factor, or negative errno on error.\n" "> + */\n" "> +int clk_get_scaled_duty_cycle(struct clk *clk, unsigned int scale)\n" @@ -282,12 +258,10 @@ "> /**\n" "> * clk_is_match - check if two clk's point to the same hardware clock\n" "> * @p: clk compared against q\n" - "> @@ -2465,12 +2632,13 @@ static void clk_summary_show_one(struct seq_file =\n" - "*s, struct clk_core *c,\n" + "> @@ -2465,12 +2632,13 @@ static void clk_summary_show_one(struct seq_file *s, struct clk_core *c,\n" "> if (!c)\n" "> return;\n" - "> =\n" - "\n" + "> \n" "> - seq_printf(s, \"%*s%-*s %7d %8d %8d %11lu %10lu %-3d\\n\",\n" "> + seq_printf(s, \"%*s%-*s %7d %8d %8d %11lu %10lu %5d %6d\\n\",\n" "> level * 3 + 1, \"\",\n" @@ -298,45 +272,30 @@ "> + clk_core_get_phase(c),\n" "> + clk_core_get_scaled_duty_cycle(c, 100000));\n" "> }\n" - "> =\n" - "\n" - "> static void clk_summary_show_subtree(struct seq_file *s, struct clk_core=\n" - " *c,\n" - "> @@ -2492,9 +2660,9 @@ static int clk_summary_show(struct seq_file *s, voi=\n" - "d *data)\n" + "> \n" + "> static void clk_summary_show_subtree(struct seq_file *s, struct clk_core *c,\n" + "> @@ -2492,9 +2660,9 @@ static int clk_summary_show(struct seq_file *s, void *data)\n" "> struct clk_core *c;\n" - "> struct hlist_head **lists =3D (struct hlist_head **)s->private;\n" - "> =\n" - "\n" - "> - seq_puts(s, \" enable prepare pr=\n" - "otect \\n\");\n" - "> - seq_puts(s, \" clock count count =\n" - "count rate accuracy phase\\n\");\n" - "> - seq_puts(s, \"----------------------------------------------------=\n" - "------------------------------------\\n\");\n" - "> + seq_puts(s, \" enable prepare pr=\n" - "otect duty\\n\");\n" - "> + seq_puts(s, \" clock count count =\n" - "count rate accuracy phase cycle\\n\");\n" - "> + seq_puts(s, \"----------------------------------------------------=\n" - "-----------------------------------------\\n\");\n" - "> =\n" - "\n" + "> struct hlist_head **lists = (struct hlist_head **)s->private;\n" + "> \n" + "> - seq_puts(s, \" enable prepare protect \\n\");\n" + "> - seq_puts(s, \" clock count count count rate accuracy phase\\n\");\n" + "> - seq_puts(s, \"----------------------------------------------------------------------------------------\\n\");\n" + "> + seq_puts(s, \" enable prepare protect duty\\n\");\n" + "> + seq_puts(s, \" clock count count count rate accuracy phase cycle\\n\");\n" + "> + seq_puts(s, \"---------------------------------------------------------------------------------------------\\n\");\n" + "> \n" "> clk_prepare_lock();\n" - "> =\n" - "\n" - "> @@ -2521,6 +2689,8 @@ static void clk_dump_one(struct seq_file *s, struct=\n" - " clk_core *c, int level)\n" + "> \n" + "> @@ -2521,6 +2689,8 @@ static void clk_dump_one(struct seq_file *s, struct clk_core *c, int level)\n" "> seq_printf(s, \"\\\"rate\\\": %lu,\", clk_core_get_rate(c));\n" "> seq_printf(s, \"\\\"accuracy\\\": %lu,\", clk_core_get_accuracy(c));\n" "> seq_printf(s, \"\\\"phase\\\": %d\", clk_core_get_phase(c));\n" "> + seq_printf(s, \"\\\"duty_cycle\\\": %u\",\n" "> + clk_core_get_scaled_duty_cycle(c, 100000));\n" "> }\n" - "> =\n" - "\n" - "> static void clk_dump_subtree(struct seq_file *s, struct clk_core *c, int=\n" - " level)\n" + "> \n" + "> static void clk_dump_subtree(struct seq_file *s, struct clk_core *c, int level)\n" "> @@ -2582,6 +2752,7 @@ static const struct {\n" "> ENTRY(CLK_SET_RATE_UNGATE),\n" "> ENTRY(CLK_IS_CRITICAL),\n" @@ -344,18 +303,15 @@ "> + ENTRY(CLK_DUTY_CYCLE_PARENT),\n" "> #undef ENTRY\n" "> };\n" - "> =\n" - "\n" - "> @@ -2620,6 +2791,17 @@ static int possible_parents_show(struct seq_file *=\n" - "s, void *data)\n" + "> \n" + "> @@ -2620,6 +2791,17 @@ static int possible_parents_show(struct seq_file *s, void *data)\n" "> }\n" "> DEFINE_SHOW_ATTRIBUTE(possible_parents);\n" - "> =\n" - "\n" + "> \n" "> +static int clk_duty_cycle_show(struct seq_file *s, void *data)\n" "> +{\n" - "> + struct clk_core *core =3D s->private;\n" - "> + struct clk_duty *duty =3D &core->duty;\n" + "> + struct clk_core *core = s->private;\n" + "> + struct clk_duty *duty = &core->duty;\n" "> +\n" "> + seq_printf(s, \"%u/%u\\n\", duty->num, duty->den);\n" "> +\n" @@ -363,40 +319,30 @@ "> +}\n" "> +DEFINE_SHOW_ATTRIBUTE(clk_duty_cycle);\n" "> +\n" - "> static void clk_debug_create_one(struct clk_core *core, struct dentry *p=\n" - "dentry)\n" + "> static void clk_debug_create_one(struct clk_core *core, struct dentry *pdentry)\n" "> {\n" "> struct dentry *root;\n" - "> @@ -2638,6 +2820,8 @@ static void clk_debug_create_one(struct clk_core *c=\n" - "ore, struct dentry *pdentry)\n" - "> debugfs_create_u32(\"clk_enable_count\", 0444, root, &core->enable_=\n" - "count);\n" - "> debugfs_create_u32(\"clk_protect_count\", 0444, root, &core->protec=\n" - "t_count);\n" - "> debugfs_create_u32(\"clk_notifier_count\", 0444, root, &core->notif=\n" - "ier_count);\n" + "> @@ -2638,6 +2820,8 @@ static void clk_debug_create_one(struct clk_core *core, struct dentry *pdentry)\n" + "> debugfs_create_u32(\"clk_enable_count\", 0444, root, &core->enable_count);\n" + "> debugfs_create_u32(\"clk_protect_count\", 0444, root, &core->protect_count);\n" + "> debugfs_create_u32(\"clk_notifier_count\", 0444, root, &core->notifier_count);\n" "> + debugfs_create_file(\"clk_duty_cycle\", 0444, root, core,\n" "> + &clk_duty_cycle_fops);\n" - "> =\n" - "\n" + "> \n" "> if (core->num_parents > 1)\n" - "> debugfs_create_file(\"clk_possible_parents\", 0444, root, c=\n" - "ore,\n" + "> debugfs_create_file(\"clk_possible_parents\", 0444, root, core,\n" "> @@ -2855,6 +3039,11 @@ static int __clk_core_init(struct clk_core *core)\n" "> else\n" - "> core->phase =3D 0;\n" - "> =\n" - "\n" + "> core->phase = 0;\n" + "> \n" "> + /*\n" "> + * Set clk's duty cycle.\n" "> + */\n" "> + clk_core_update_duty_cycle_nolock(core);\n" "> +\n" "> /*\n" - "> * Set clk's rate. The preferred method is to use .recalc_rate. =\n" - " For\n" - "> * simple clocks and lazy developers the default fallback is to u=\n" - "se the\n" + "> * Set clk's rate. The preferred method is to use .recalc_rate. For\n" + "> * simple clocks and lazy developers the default fallback is to use the\n" "> diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h\n" "> index b7cfa037e593..08b1aa70a38d 100644\n" "> --- a/include/linux/clk-provider.h\n" @@ -407,15 +353,13 @@ "> #define CLK_OPS_PARENT_ENABLE BIT(12)\n" "> +/* duty cycle call may be forwarded to the parent clock */\n" "> +#define CLK_DUTY_CYCLE_PARENT BIT(13)\n" - "> =\n" - "\n" + "> \n" "> struct clk;\n" "> struct clk_hw;\n" "> @@ -66,6 +68,17 @@ struct clk_rate_request {\n" "> struct clk_hw *best_parent_hw;\n" "> };\n" - "> =\n" - "\n" + "> \n" "> +/**\n" "> + * struct clk_duty - Struture encoding the duty cycle ratio of a clock\n" "> + *\n" @@ -428,31 +372,24 @@ "> +};\n" "> +\n" "> /**\n" - "> * struct clk_ops - Callback operations for hardware clocks; these are =\n" - "to\n" + "> * struct clk_ops - Callback operations for hardware clocks; these are to\n" "> * be provided by the clock implementation, and will be called by drivers\n" "> @@ -169,6 +182,15 @@ struct clk_rate_request {\n" "> * by the second argument. Valid values for degrees are\n" "> * 0-359. Return 0 on success, otherwise -EERROR.\n" "> *\n" - "> + * @get_duty_cycle: Queries the hardware to get the current duty cycle r=\n" - "atio\n" - "> + * of a clock. Returned values denominator cannot be 0 and =\n" - "must be\n" + "> + * @get_duty_cycle: Queries the hardware to get the current duty cycle ratio\n" + "> + * of a clock. Returned values denominator cannot be 0 and must be\n" "> + * superior or equal to the numerator.\n" "> + *\n" - "> + * @set_duty_cycle: Apply the duty cycle ratio to this clock signal spec=\n" - "ified by\n" - "> + * the numerator (2nd argurment) and denominator (3rd argu=\n" - "ment).\n" + "> + * @set_duty_cycle: Apply the duty cycle ratio to this clock signal specified by\n" + "> + * the numerator (2nd argurment) and denominator (3rd argument).\n" "> + * Argument must be a valid ratio (denominator > 0\n" - "> + * and >=3D numerator) Return 0 on success, otherwise -EERR=\n" - "OR.\n" + "> + * and >= numerator) Return 0 on success, otherwise -EERROR.\n" "> + *\n" "> * @init: Perform platform-specific initialization magic.\n" "> * This is not not used by any of the basic clock types.\n" - "> * Please consider other ways of solving initialization prob=\n" - "lems\n" + "> * Please consider other ways of solving initialization problems\n" "> @@ -218,6 +240,10 @@ struct clk_ops {\n" "> unsigned long parent_accuracy);\n" "> int (*get_phase)(struct clk_hw *hw);\n" @@ -462,8 +399,7 @@ "> + int (*set_duty_cycle)(struct clk_hw *hw,\n" "> + struct clk_duty *duty);\n" "> void (*init)(struct clk_hw *hw);\n" - "> void (*debug_init)(struct clk_hw *hw, struct dentry *d=\n" - "entry);\n" + "> void (*debug_init)(struct clk_hw *hw, struct dentry *dentry);\n" "> };\n" "> diff --git a/include/linux/clk.h b/include/linux/clk.h\n" "> index 0dbd0885b2c2..4f750c481b82 100644\n" @@ -472,29 +408,24 @@ "> @@ -141,6 +141,27 @@ int clk_set_phase(struct clk *clk, int degrees);\n" "> */\n" "> int clk_get_phase(struct clk *clk);\n" - "> =\n" - "\n" + "> \n" "> +/**\n" "> + * clk_set_duty_cycle - adjust the duty cycle ratio of a clock signal\n" "> + * @clk: clock signal source\n" "> + * @num: numerator of the duty cycle ratio to be applied\n" "> + * @den: denominator of the duty cycle ratio to be applied\n" "> + *\n" - "> + * Adjust the duty cycle of a clock signal by the specified ratio. Retur=\n" - "ns 0 on\n" + "> + * Adjust the duty cycle of a clock signal by the specified ratio. Returns 0 on\n" "> + * success, -EERROR otherwise.\n" "> + */\n" - "> +int clk_set_duty_cycle(struct clk *clk, unsigned int num, unsigned int d=\n" - "en);\n" + "> +int clk_set_duty_cycle(struct clk *clk, unsigned int num, unsigned int den);\n" "> +\n" "> +/**\n" "> + * clk_get_duty_cycle - return the duty cycle ratio of a clock signal\n" "> + * @clk: clock signal source\n" - "> + * @scale: scaling factor to be applied to represent the ratio as an int=\n" - "eger\n" + "> + * @scale: scaling factor to be applied to represent the ratio as an integer\n" "> + *\n" - "> + * Returns the duty cycle ratio multiplied by the scale provided, otherw=\n" - "ise\n" + "> + * Returns the duty cycle ratio multiplied by the scale provided, otherwise\n" "> + * returns -EERROR.\n" "> + */\n" "> +int clk_get_scaled_duty_cycle(struct clk *clk, unsigned int scale);\n" @@ -505,8 +436,7 @@ "> @@ -183,6 +204,18 @@ static inline long clk_get_phase(struct clk *clk)\n" "> return -ENOTSUPP;\n" "> }\n" - "> =\n" - "\n" + "> \n" "> +static inline int clk_set_duty_cycle(struct clk *clk, unsigned int num,\n" "> + unsigned int den)\n" "> +{\n" @@ -521,7 +451,7 @@ "> +\n" "> static inline bool clk_is_match(const struct clk *p, const struct clk *q)\n" "> {\n" - "> return p =3D=3D q;\n" + "> return p == q;\n" "> diff --git a/include/trace/events/clk.h b/include/trace/events/clk.h\n" "> index 2cd449328aee..9004ffff7f32 100644\n" "> --- a/include/trace/events/clk.h\n" @@ -529,8 +459,7 @@ "> @@ -192,6 +192,42 @@ DEFINE_EVENT(clk_phase, clk_set_phase_complete,\n" "> TP_ARGS(core, phase)\n" "> );\n" - "> =\n" - "\n" + "> \n" "> +DECLARE_EVENT_CLASS(clk_duty_cycle,\n" "> +\n" "> + TP_PROTO(struct clk_core *core, struct clk_duty *duty),\n" @@ -545,8 +474,8 @@ "> +\n" "> + TP_fast_assign(\n" "> + __assign_str(name, core->name);\n" - "> + __entry->num =3D duty->num;\n" - "> + __entry->den =3D duty->den;\n" + "> + __entry->num = duty->num;\n" + "> + __entry->den = duty->den;\n" "> + ),\n" "> +\n" "> + TP_printk(\"%s %u/%u\", __get_str(name), (unsigned int)__entry->num,\n" @@ -568,12 +497,10 @@ "> +);\n" "> +\n" "> #endif /* _TRACE_CLK_H */\n" - "> =\n" - "\n" + "> \n" "> /* This part must be outside protection */\n" - "> -- =\n" - "\n" + "> -- \n" "> 2.14.3\n" - >=20 + > -b85518a5c854e46fc4579067cecc6595bdd7f99725afd8f31cc651c380aff8bb +0658e5719e1d691bba27543a099b14f69ffd2cd42046fb36cf2b60d08fc29bcd
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.