All of lore.kernel.org
 help / color / mirror / Atom feed
From: Stephen Boyd <sboyd@codeaurora.org>
To: Maxime Ripard <maxime.ripard@free-electrons.com>
Cc: Mike Turquette <mturquette@baylibre.com>,
	Emilio Lopez <emilio@elopez.com.ar>,
	linux-arm-kernel@lists.infradead.org,
	Chen-Yu Tsai <wens@csie.org>, Hans de Goede <hdegoede@redhat.com>,
	linux-clk@vger.kernel.org, linux-sunxi@googlegroups.com
Subject: Re: [PATCH v3 1/5] clk: Add a basic multiplier clock
Date: Fri, 2 Oct 2015 13:43:08 -0700	[thread overview]
Message-ID: <20151002204308.GY12338@codeaurora.org> (raw)
In-Reply-To: <1443512353-28073-2-git-send-email-maxime.ripard@free-electrons.com>

On 09/29, Maxime Ripard wrote:
> diff --git a/drivers/clk/clk-multiplier.c b/drivers/clk/clk-multiplier.c
> new file mode 100644
> index 000000000000..61097e365d55
> --- /dev/null
> +++ b/drivers/clk/clk-multiplier.c
> @@ -0,0 +1,176 @@
> +/*
> + * Copyright (C) 2015 Maxime Ripard <maxime.ripard@free-electrons.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +#include <linux/module.h>

Maybe export.h is more appropriate?

> +#include <linux/clk-provider.h>
> +#include <linux/slab.h>
> +#include <linux/err.h>
> +#include <linux/of.h>
> +
> +#define to_clk_multiplier(_hw) container_of(_hw, struct clk_multiplier, hw)
> +
> +static unsigned long __get_mult(struct clk_multiplier *mult,
> +				unsigned long rate,
> +				unsigned long parent_rate)
> +{
> +	if (mult->flags & CLK_MULTIPLIER_ROUND_CLOSEST)
> +		return DIV_ROUND_CLOSEST(rate, parent_rate);

We should include kernel.h for this macro.

> +
> +	return rate / parent_rate;
> +}
> +
> +static unsigned long clk_multiplier_recalc_rate(struct clk_hw *hw,
> +						unsigned long parent_rate)
> +{
> +	struct clk_multiplier *mult = to_clk_multiplier(hw);
> +	unsigned long val;
> +	
> +	val = clk_readl(mult->reg) >> mult->shift;
> +	val &= GENMASK(mult->width, 0);

and bitops.h for GENMASK

> +
> +	if (!val && mult->flags & CLK_MULTIPLIER_ZERO_BYPASS)
> +		val = 1;
> +	
> +	return parent_rate * val;
> +}
> +
> +static bool __is_best_rate(unsigned long rate, unsigned long new,
> +			   unsigned long best, unsigned long flags)
> +{
> +	if (flags & CLK_MULTIPLIER_ROUND_CLOSEST)

Is the only difference in this function vs the divider one that
flag? Maybe we should make this function generic to the framework
and pass a flag indicating closest or not.

> +		return abs(rate - new) < abs(rate - best);
> +
> +	return new >= rate && new < best;
> +}
> +
> +static unsigned long __bestmult(struct clk_hw *hw, unsigned long rate,
> +				unsigned long *best_parent_rate,
> +				u8 width, unsigned long flags)
> +{
> +	unsigned long orig_parent_rate = *best_parent_rate;
> +	unsigned long parent_rate, current_rate, best_rate = ~0;
> +	unsigned int i, bestmult = 0;
> +
> +	if (!(__clk_get_flags(hw->clk) & CLK_SET_RATE_PARENT))

Please use clk_hw_get_flags. I'd *really* like to kill
__clk_get_flags() but we still have one user in omap code.

> +		return rate / *best_parent_rate;
> +
> +	for (i = 1; i < ((1 << width) - 1); i++) {
> +		if (rate * i == orig_parent_rate) {
> +			/*
> +			 * This is the best case for us if we have a
> +			 * perfect match without changing the parent
> +			 * rate.
> +			 */
> +			*best_parent_rate = orig_parent_rate;
> +			return i;
> +		}
> +
> +		parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw),
> +						rate / i);
> +		current_rate = parent_rate * i;
> +
> +		if (__is_best_rate(rate, current_rate, best_rate, flags)) {
> +			bestmult = i;
> +			best_rate = current_rate;
> +			*best_parent_rate = parent_rate;
> +		}
> +	}
> +
> +	return bestmult;
> +}
> +
> +static int clk_multiplier_set_rate(struct clk_hw *hw, unsigned long rate,
> +			       unsigned long parent_rate)
> +{
> +	struct clk_multiplier *mult = to_clk_multiplier(hw);
> +	unsigned long factor = __get_mult(mult, rate, parent_rate);
> +	unsigned long uninitialized_var(flags);

hmmm ok. We set it to 0 in other drivers.

> +	unsigned long val;
> +
> +	if (mult->lock)
> +		spin_lock_irqsave(mult->lock, flags);

This needs the same "trick" that we did in the generic clock
types to avoid sparse warnings.

> +
> +	val = clk_readl(mult->reg);
> +	val &= ~GENMASK(mult->width + mult->shift, mult->shift);
> +	val |= factor << mult->shift;
> +	clk_writel(val, mult->reg);
> +
> +	if (mult->lock)
> +		spin_unlock_irqrestore(mult->lock, flags);
> +
> +	return 0;
> +}
> +
> +struct clk *clk_register_multiplier(struct device *dev, const char *name,
> +				    const char *parent_name,
> +				    unsigned long flags,
> +				    void __iomem *reg, u8 shift, u8 width,
> +				    u8 clk_mult_flags, spinlock_t *lock)
> +{
> +	struct clk_init_data init;
> +	struct clk_multiplier *mult;
> +	struct clk *clk;
> +
> +	mult = kmalloc(sizeof(*mult), GFP_KERNEL);
> +	if (!mult) {
> +		pr_err("%s: could not allocate multiplier clk\n", __func__);

We don't need allocation error messages.

> +		return ERR_PTR(-ENOMEM);
> +	}

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

WARNING: multiple messages have this Message-ID (diff)
From: sboyd@codeaurora.org (Stephen Boyd)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v3 1/5] clk: Add a basic multiplier clock
Date: Fri, 2 Oct 2015 13:43:08 -0700	[thread overview]
Message-ID: <20151002204308.GY12338@codeaurora.org> (raw)
In-Reply-To: <1443512353-28073-2-git-send-email-maxime.ripard@free-electrons.com>

On 09/29, Maxime Ripard wrote:
> diff --git a/drivers/clk/clk-multiplier.c b/drivers/clk/clk-multiplier.c
> new file mode 100644
> index 000000000000..61097e365d55
> --- /dev/null
> +++ b/drivers/clk/clk-multiplier.c
> @@ -0,0 +1,176 @@
> +/*
> + * Copyright (C) 2015 Maxime Ripard <maxime.ripard@free-electrons.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +#include <linux/module.h>

Maybe export.h is more appropriate?

> +#include <linux/clk-provider.h>
> +#include <linux/slab.h>
> +#include <linux/err.h>
> +#include <linux/of.h>
> +
> +#define to_clk_multiplier(_hw) container_of(_hw, struct clk_multiplier, hw)
> +
> +static unsigned long __get_mult(struct clk_multiplier *mult,
> +				unsigned long rate,
> +				unsigned long parent_rate)
> +{
> +	if (mult->flags & CLK_MULTIPLIER_ROUND_CLOSEST)
> +		return DIV_ROUND_CLOSEST(rate, parent_rate);

We should include kernel.h for this macro.

> +
> +	return rate / parent_rate;
> +}
> +
> +static unsigned long clk_multiplier_recalc_rate(struct clk_hw *hw,
> +						unsigned long parent_rate)
> +{
> +	struct clk_multiplier *mult = to_clk_multiplier(hw);
> +	unsigned long val;
> +	
> +	val = clk_readl(mult->reg) >> mult->shift;
> +	val &= GENMASK(mult->width, 0);

and bitops.h for GENMASK

> +
> +	if (!val && mult->flags & CLK_MULTIPLIER_ZERO_BYPASS)
> +		val = 1;
> +	
> +	return parent_rate * val;
> +}
> +
> +static bool __is_best_rate(unsigned long rate, unsigned long new,
> +			   unsigned long best, unsigned long flags)
> +{
> +	if (flags & CLK_MULTIPLIER_ROUND_CLOSEST)

Is the only difference in this function vs the divider one that
flag? Maybe we should make this function generic to the framework
and pass a flag indicating closest or not.

> +		return abs(rate - new) < abs(rate - best);
> +
> +	return new >= rate && new < best;
> +}
> +
> +static unsigned long __bestmult(struct clk_hw *hw, unsigned long rate,
> +				unsigned long *best_parent_rate,
> +				u8 width, unsigned long flags)
> +{
> +	unsigned long orig_parent_rate = *best_parent_rate;
> +	unsigned long parent_rate, current_rate, best_rate = ~0;
> +	unsigned int i, bestmult = 0;
> +
> +	if (!(__clk_get_flags(hw->clk) & CLK_SET_RATE_PARENT))

Please use clk_hw_get_flags. I'd *really* like to kill
__clk_get_flags() but we still have one user in omap code.

> +		return rate / *best_parent_rate;
> +
> +	for (i = 1; i < ((1 << width) - 1); i++) {
> +		if (rate * i == orig_parent_rate) {
> +			/*
> +			 * This is the best case for us if we have a
> +			 * perfect match without changing the parent
> +			 * rate.
> +			 */
> +			*best_parent_rate = orig_parent_rate;
> +			return i;
> +		}
> +
> +		parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw),
> +						rate / i);
> +		current_rate = parent_rate * i;
> +
> +		if (__is_best_rate(rate, current_rate, best_rate, flags)) {
> +			bestmult = i;
> +			best_rate = current_rate;
> +			*best_parent_rate = parent_rate;
> +		}
> +	}
> +
> +	return bestmult;
> +}
> +
> +static int clk_multiplier_set_rate(struct clk_hw *hw, unsigned long rate,
> +			       unsigned long parent_rate)
> +{
> +	struct clk_multiplier *mult = to_clk_multiplier(hw);
> +	unsigned long factor = __get_mult(mult, rate, parent_rate);
> +	unsigned long uninitialized_var(flags);

hmmm ok. We set it to 0 in other drivers.

> +	unsigned long val;
> +
> +	if (mult->lock)
> +		spin_lock_irqsave(mult->lock, flags);

This needs the same "trick" that we did in the generic clock
types to avoid sparse warnings.

> +
> +	val = clk_readl(mult->reg);
> +	val &= ~GENMASK(mult->width + mult->shift, mult->shift);
> +	val |= factor << mult->shift;
> +	clk_writel(val, mult->reg);
> +
> +	if (mult->lock)
> +		spin_unlock_irqrestore(mult->lock, flags);
> +
> +	return 0;
> +}
> +
> +struct clk *clk_register_multiplier(struct device *dev, const char *name,
> +				    const char *parent_name,
> +				    unsigned long flags,
> +				    void __iomem *reg, u8 shift, u8 width,
> +				    u8 clk_mult_flags, spinlock_t *lock)
> +{
> +	struct clk_init_data init;
> +	struct clk_multiplier *mult;
> +	struct clk *clk;
> +
> +	mult = kmalloc(sizeof(*mult), GFP_KERNEL);
> +	if (!mult) {
> +		pr_err("%s: could not allocate multiplier clk\n", __func__);

We don't need allocation error messages.

> +		return ERR_PTR(-ENOMEM);
> +	}

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

  reply	other threads:[~2015-10-02 20:43 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-09-29  7:39 [PATCH v3 0/5] clk: sunxi: Add support for the Audio PLL Maxime Ripard
2015-09-29  7:39 ` Maxime Ripard
2015-09-29  7:39 ` [PATCH v3 1/5] clk: Add a basic multiplier clock Maxime Ripard
2015-09-29  7:39   ` Maxime Ripard
2015-10-02 20:43   ` Stephen Boyd [this message]
2015-10-02 20:43     ` Stephen Boyd
2015-10-05 10:19     ` Maxime Ripard
2015-10-05 10:19       ` Maxime Ripard
2015-10-05 18:09       ` Stephen Boyd
2015-10-05 18:09         ` Stephen Boyd
2015-10-07 11:04         ` Maxime Ripard
2015-10-07 11:04           ` Maxime Ripard
2015-10-07 19:17           ` Stephen Boyd
2015-10-07 19:17             ` Stephen Boyd
2015-09-29  7:39 ` [PATCH v3 2/5] clk: sunxi: Add a driver for the PLL2 Maxime Ripard
2015-09-29  7:39   ` Maxime Ripard
2015-09-29  7:39 ` [PATCH v3 3/5] clk: sunxi: pll2: Add A13 support Maxime Ripard
2015-09-29  7:39   ` Maxime Ripard
2015-09-29  7:39 ` [PATCH v3 4/5] clk: sunxi: codec clock support Maxime Ripard
2015-09-29  7:39   ` Maxime Ripard
2015-10-02 20:44   ` Stephen Boyd
2015-10-02 20:44     ` Stephen Boyd
2015-10-05  9:05     ` Maxime Ripard
2015-10-05  9:05       ` Maxime Ripard
2015-09-29  7:39 ` [PATCH v3 5/5] clk: sunxi: mod1 " Maxime Ripard
2015-09-29  7:39   ` Maxime Ripard
2015-10-02 20:45   ` Stephen Boyd
2015-10-02 20:45     ` Stephen Boyd
2015-10-05  9:44     ` Maxime Ripard
2015-10-05  9:44       ` Maxime Ripard

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20151002204308.GY12338@codeaurora.org \
    --to=sboyd@codeaurora.org \
    --cc=emilio@elopez.com.ar \
    --cc=hdegoede@redhat.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-clk@vger.kernel.org \
    --cc=linux-sunxi@googlegroups.com \
    --cc=maxime.ripard@free-electrons.com \
    --cc=mturquette@baylibre.com \
    --cc=wens@csie.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.