All of lore.kernel.org
 help / color / mirror / Atom feed
From: Michal Simek <michal.simek@xilinx.com>
To: James Kelly <jamespeterkelly@gmail.com>,
	Michal Simek <michal.simek@xilinx.com>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: driverdev-devel@linuxdriverproject.org
Subject: Re: [PATCH 06/14] staging: clocking-wizard: Swap CCF clock providers
Date: Fri, 11 May 2018 08:21:19 +0200	[thread overview]
Message-ID: <56428920-38ea-b4fd-fbc1-2223b8a77781@xilinx.com> (raw)
In-Reply-To: <20180507012040.18187-7-jamespeterkelly@gmail.com>

On 7.5.2018 03:20, James Kelly wrote:
> Replace existing CCF clock providers with new clock provider that can
> be enhanced to meet our needs.
> 
> AXI clock prepare/enable/disable/unprepare is now managed by regmap APIs.
> 
> Unregistering of clk instances now handled by devm APIs.
> 
> Drop warning that fractional ratios are not supported because it used
> undocumented register fields and it won't be needed anymore.
> 
> Signed-off-by: James Kelly <jamespeterkelly@gmail.com>
> ---
>  .../clocking-wizard/clk-xlnx-clock-wizard.c        | 211 +++++++--------------
>  1 file changed, 71 insertions(+), 140 deletions(-)
> 
> diff --git a/drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c b/drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c
> index ba9b1dc93d50..1dbeda92fb9a 100644
> --- a/drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c
> +++ b/drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c
> @@ -76,24 +76,6 @@
>  #define WZRD_CLKNAME_IN1	"clk_in1"
>  #define WZRD_FLAG_MULTIPLY	BIT(0)
>  
> -#define WZRD_CLK_CFG_REG(n)	(0x200 + 4 * (n))
> -
> -#define WZRD_CLKOUT0_FRAC_EN	BIT(18)
> -#define WZRD_CLKFBOUT_FRAC_EN	BIT(26)
> -
> -#define WZRD_CLKFBOUT_MULT_SHIFT	8
> -#define WZRD_CLKFBOUT_MULT_MASK		(0xff << WZRD_CLKFBOUT_MULT_SHIFT)
> -#define WZRD_DIVCLK_DIVIDE_SHIFT	0
> -#define WZRD_DIVCLK_DIVIDE_MASK		(0xff << WZRD_DIVCLK_DIVIDE_SHIFT)
> -#define WZRD_CLKOUT_DIVIDE_SHIFT	0
> -#define WZRD_CLKOUT_DIVIDE_MASK		(0xff << WZRD_DIVCLK_DIVIDE_SHIFT)
> -
> -enum clk_wzrd_int_clks {
> -	wzrd_clk_mul_div,
> -	wzrd_clk_mul,
> -	wzrd_clk_int_max
> -};
> -
>  enum clk_wzrd_clk {
>  	WZRD_CLK_DIV,
>  	WZRD_CLK_PLL,
> @@ -149,14 +131,13 @@ struct clk_wzrd_clk_data {
>  		container_of(_hw, struct clk_wzrd_clk_data, hw)
>  
>  /**
> - * struct clk_wzrd:
> - * @clk_data:		Clock data
> + * struct clk_wzrd - Platform driver data for clocking wizard device
> + *
> + * @clk_data:		Clock data accessible to other devices via device tree
>   * @nb:			Notifier block
> - * @base:		Memory base
>   * @regmap:		Register map for hardware
>   * @clk_in1:		Handle to input clock 'clk_in1'
>   * @axi_clk:		Handle to input clock 's_axi_aclk'
> - * @clks_internal:	Internal clocks
>   * @clkout:		Output clocks
>   * @speed_grade:	Speed grade of the device
>   * @suspended:		Flag indicating power state of the device
> @@ -167,11 +148,9 @@ struct clk_wzrd_clk_data {
>  struct clk_wzrd {
>  	struct clk_onecell_data		clk_data;
>  	struct notifier_block		nb;
> -	void __iomem			*base;
>  	struct regmap			*regmap;
>  	struct clk			*clk_in1;
>  	struct clk			*axi_clk;
> -	struct clk			*clks_internal[wzrd_clk_int_max];
>  	struct clk			*clkout[WZRD_NUM_OUTPUTS];
>  	unsigned int			speed_grade;
>  	bool				suspended;
> @@ -179,7 +158,6 @@ struct clk_wzrd {
>  	struct clk_wzrd_clk_data	pll_data;
>  	struct clk_wzrd_clk_data	clkout_data[0];
>  };
> -
>  #define to_clk_wzrd(_nb) container_of(_nb, struct clk_wzrd, nb)
>  
>  /* maximum frequencies for input/output clocks per speed grade */
> @@ -321,7 +299,6 @@ static int __maybe_unused clk_wzrd_suspend(struct device *dev)
>  {
>  	struct clk_wzrd *cw = dev_get_drvdata(dev);
>  
> -	clk_disable_unprepare(cw->axi_clk);
>  	cw->suspended = true;
>  
>  	return 0;
> @@ -329,15 +306,8 @@ static int __maybe_unused clk_wzrd_suspend(struct device *dev)
>  
>  static int __maybe_unused clk_wzrd_resume(struct device *dev)
>  {
> -	int ret;
>  	struct clk_wzrd *cw = dev_get_drvdata(dev);
>  
> -	ret = clk_prepare_enable(cw->axi_clk);
> -	if (ret) {
> -		dev_err(dev, "unable to enable s_axi_aclk\n");
> -		return ret;
> -	}
> -
>  	cw->suspended = false;
>  
>  	return 0;
> @@ -348,17 +318,32 @@ static SIMPLE_DEV_PM_OPS(clk_wzrd_dev_pm_ops, clk_wzrd_suspend,
>  
>  static int clk_wzrd_get_device_tree_data(struct device *dev)
>  {
> -	int ret;
> -	unsigned long rate;
> +	int num_outputs, ret;
>  	struct clk_wzrd *cw;
> +	struct device_node *node = dev->of_node;
> +
> +	num_outputs = of_property_count_strings(node,
> +						"clock-output-names");
> +	if (num_outputs < 1) {
> +		dev_err(dev, "No clock output names in device tree\n");
> +		if (num_outputs < 0)
> +			return num_outputs;
> +		else
> +			return -EINVAL;
> +	}
> +	if (num_outputs > WZRD_NUM_OUTPUTS) {
> +		dev_warn(dev, "Too many clock output names in device tree\n");
> +		num_outputs = WZRD_NUM_OUTPUTS;
> +	}
>  
> -	cw = devm_kzalloc(dev, sizeof(*cw), GFP_KERNEL);
> +	cw = devm_kzalloc(dev, sizeof(*cw) + num_outputs *
> +			  sizeof(struct clk_wzrd_clk_data), GFP_KERNEL);
>  	if (!cw)
>  		return -ENOMEM;
>  	dev_set_drvdata(dev, cw);
> +	cw->clk_data.clk_num = num_outputs;
>  
> -	ret = of_property_read_u32(dev->of_node, "speed-grade",
> -				   &cw->speed_grade);
> +	ret = of_property_read_u32(node, "speed-grade", &cw->speed_grade);
>  	if (!ret) {
>  		if (cw->speed_grade < 1 || cw->speed_grade > 3) {
>  			dev_warn(dev, "invalid speed grade '%d'\n",
> @@ -380,18 +365,12 @@ static int clk_wzrd_get_device_tree_data(struct device *dev)
>  			dev_err(dev, "Clock %s not found\n", WZRD_CLKNAME_AXI);
>  		return PTR_ERR(cw->axi_clk);
>  	}
> -	ret = clk_prepare_enable(cw->axi_clk);
> +	ret = clk_set_max_rate(cw->axi_clk, WZRD_ACLK_MAX_FREQ);
>  	if (ret) {
> -		dev_err(dev, "enabling %s failed\n", WZRD_CLKNAME_AXI);
> +		dev_err(dev, "Unable to set clock %s to valid range\n",
> +			WZRD_CLKNAME_AXI);
>  		return ret;
>  	}
> -	rate = clk_get_rate(cw->axi_clk);
> -	if (rate > WZRD_ACLK_MAX_FREQ) {
> -		dev_err(dev, "%s frequency (%lu) too high\n", WZRD_CLKNAME_AXI,
> -			rate);
> -		clk_disable_unprepare(cw->axi_clk);
> -		return -EINVAL;
> -	}
>  
>  	return 0;
>  }
> @@ -399,12 +378,18 @@ static int clk_wzrd_get_device_tree_data(struct device *dev)
>  static int clk_wzrd_regmap_alloc(struct device *dev)
>  {
>  	struct resource *mem;
> +	void __iomem *base;
>  	struct clk_wzrd *cw = dev_get_drvdata(dev);
>  
>  	mem = platform_get_resource(to_platform_device(dev), IORESOURCE_MEM, 0);
> -	cw->base = devm_ioremap_resource(dev, mem);
> -	if (IS_ERR(cw->base))
> -		return PTR_ERR(cw->base);
> +	base = devm_ioremap_resource(dev, mem);
> +	if (IS_ERR(base))
> +		return PTR_ERR(base);
> +
> +	cw->regmap = devm_regmap_init_mmio_clk(dev, WZRD_CLKNAME_AXI,
> +					       base, &clk_wzrd_regmap_config);
> +	if (IS_ERR(cw->regmap))
> +		return PTR_ERR(cw->regmap);
>  
>  	return 0;
>  }
> @@ -412,115 +397,68 @@ static int clk_wzrd_regmap_alloc(struct device *dev)
>  static int clk_wzrd_register_ccf(struct device *dev)
>  {
>  	int i, ret;
> -	u32 reg;
> -	const char *clk_name;
> +	const char *clk_div_name;
> +	const char *clk_pll_name;
> +
>  	struct clk_wzrd *cw = dev_get_drvdata(dev);
>  
> -	/* we don't support fractional div/mul yet */
> -	reg = readl(cw->base + WZRD_CLK_CFG_REG(0)) &
> -		    WZRD_CLKFBOUT_FRAC_EN;
> -	reg |= readl(cw->base + WZRD_CLK_CFG_REG(2)) &
> -		     WZRD_CLKOUT0_FRAC_EN;
> -	if (reg)
> -		dev_warn(dev, "fractional div/mul not supported\n");
> -
> -	/* register div */
> -	reg = (readl(cw->base + WZRD_CLK_CFG_REG(0)) &
> -	       WZRD_DIVCLK_DIVIDE_MASK) >> WZRD_DIVCLK_DIVIDE_SHIFT;
> -	clk_name = kasprintf(GFP_KERNEL, "%s_mul_div", dev_name(dev));
> -	if (!clk_name) {
> -		ret = -ENOMEM;
> -		goto err_disable_clk;
> -	}
> -	cw->clks_internal[wzrd_clk_mul_div] = clk_register_fixed_factor(
> -			dev, clk_name,
> -			__clk_get_name(cw->clk_in1),
> -			0, 1, reg);
> -	kfree(clk_name);
> -	if (IS_ERR(cw->clks_internal[wzrd_clk_mul_div])) {
> -		dev_err(dev, "unable to register divider clock\n");
> -		ret = PTR_ERR(cw->clks_internal[wzrd_clk_mul_div]);
> -		goto err_disable_clk;
> -	}
> +	clk_div_name = kasprintf(GFP_KERNEL, "%s_div", dev_name(dev));
> +	if (!clk_div_name)
> +		return -ENOMEM;
> +	ret = clk_wzrd_register_clk(dev, clk_div_name, WZRD_CLK_DIV, 0, 0);
> +	if (ret)
> +		goto err_free_div_name;
>  
> -	/* register multiplier */
> -	reg = (readl(cw->base + WZRD_CLK_CFG_REG(0)) &
> -	       WZRD_CLKFBOUT_MULT_MASK) >> WZRD_CLKFBOUT_MULT_SHIFT;
> -	clk_name = kasprintf(GFP_KERNEL, "%s_mul", dev_name(dev));
> -	if (!clk_name) {
> +	clk_pll_name = kasprintf(GFP_KERNEL, "%s_pll", dev_name(dev));
> +	if (!clk_pll_name) {
>  		ret = -ENOMEM;
> -		goto err_rm_int_clk;
> -	}
> -	cw->clks_internal[wzrd_clk_mul] = clk_register_fixed_factor(
> -			dev, clk_name,
> -			__clk_get_name(cw->clks_internal[wzrd_clk_mul_div]),
> -			0, reg, 1);
> -	if (IS_ERR(cw->clks_internal[wzrd_clk_mul])) {
> -		dev_err(dev, "unable to register fixed-factor clock\n");
> -		ret = PTR_ERR(cw->clks_internal[wzrd_clk_mul]);
> -		goto err_rm_int_clk;
> +		goto err_free_div_name;
>  	}
> +	ret = clk_wzrd_register_clk(dev, clk_pll_name, WZRD_CLK_PLL, 0, 0);
> +	if (ret)
> +		goto err_free_pll_name;
>  
> -	/* register div per output */
> -	for (i = WZRD_NUM_OUTPUTS - 1; i >= 0 ; i--) {
> +	for (i = cw->clk_data.clk_num - 1; i >= 0 ; i--) {
>  		const char *clkout_name;
>  
>  		if (of_property_read_string_index(dev->of_node,
>  						  "clock-output-names", i,
>  						  &clkout_name)) {
> -			dev_err(dev,
> -				"clock output name not specified\n");
> +			dev_err(dev, "clock output %d name not specified\n", i);
>  			ret = -EINVAL;
> -			goto err_rm_int_clks;
> +			goto err_free_pll_name;
>  		}
> -		reg = readl(cw->base + WZRD_CLK_CFG_REG(2) + i * 12);
> -		reg &= WZRD_CLKOUT_DIVIDE_MASK;
> -		reg >>= WZRD_CLKOUT_DIVIDE_SHIFT;
> -		cw->clkout[i] = clk_register_fixed_factor(dev, clkout_name,
> -							  clk_name, 0, 1, reg);
> -		if (IS_ERR(cw->clkout[i])) {
> -			int j;
> -
> -			for (j = i + 1; j < WZRD_NUM_OUTPUTS; j++)
> -				clk_unregister(cw->clkout[j]);
> -			dev_err(dev,
> -				"unable to register divider clock\n");
> -			ret = PTR_ERR(cw->clkout[i]);
> -			goto err_rm_int_clks;
> -		}
> -	}
>  
> -	kfree(clk_name);
> +		ret = clk_wzrd_register_clk(dev, clkout_name, WZRD_CLK_OUT,
> +					    i, 0);
> +		if (ret)
> +			goto err_free_pll_name;
> +
> +		cw->clkout[i] = cw->clkout_data[i].hw.clk;
> +	}
>  
>  	cw->clk_data.clks = cw->clkout;
> -	cw->clk_data.clk_num = ARRAY_SIZE(cw->clkout);
>  	of_clk_add_provider(dev->of_node, of_clk_src_onecell_get,
>  			    &cw->clk_data);
>  
>  	if (cw->speed_grade) {
>  		cw->nb.notifier_call = clk_wzrd_clk_notifier;
>  
> -		ret = clk_notifier_register(cw->clk_in1,
> -					    &cw->nb);
> -		if (ret)
> -			dev_warn(dev,
> -				 "unable to register clock notifier\n");
> +		ret = clk_notifier_register(cw->clk_in1, &cw->nb);
> +			if (ret)
> +				dev_warn(dev, "Unable to register input clock notifier\n");
>  
>  		ret = clk_notifier_register(cw->axi_clk, &cw->nb);
> -		if (ret)
> -			dev_warn(dev,
> -				 "unable to register clock notifier\n");
> +			if (ret)
> +				dev_warn(dev, "Unable to register AXI clock notifier\n");
>  	}
>  
> -	return 0;
> +	ret = 0;
>  
> -err_rm_int_clks:
> -	clk_unregister(cw->clks_internal[1]);
> -err_rm_int_clk:
> -	kfree(clk_name);
> -	clk_unregister(cw->clks_internal[0]);
> -err_disable_clk:
> -	clk_disable_unprepare(cw->axi_clk);
> +err_free_pll_name:
> +	kfree(clk_pll_name);
> +err_free_div_name:
> +	kfree(clk_div_name);
>  
>  	return ret;
>  }
> @@ -547,23 +485,15 @@ static int clk_wzrd_probe(struct platform_device *pdev)
>  
>  static int clk_wzrd_remove(struct platform_device *pdev)
>  {
> -	int i;
>  	struct clk_wzrd *cw = platform_get_drvdata(pdev);
>  
>  	of_clk_del_provider(pdev->dev.of_node);
>  
> -	for (i = 0; i < WZRD_NUM_OUTPUTS; i++)
> -		clk_unregister(cw->clkout[i]);
> -	for (i = 0; i < wzrd_clk_int_max; i++)
> -		clk_unregister(cw->clks_internal[i]);
> -
>  	if (cw->speed_grade) {
>  		clk_notifier_unregister(cw->axi_clk, &cw->nb);
>  		clk_notifier_unregister(cw->clk_in1, &cw->nb);
>  	}
>  
> -	clk_disable_unprepare(cw->axi_clk);
> -
>  	return 0;
>  }
>  
> @@ -577,6 +507,7 @@ static struct platform_driver clk_wzrd_driver = {
>  	.driver = {
>  		.name = "clk-wizard",
>  		.of_match_table = clk_wzrd_ids,
> +		.owner = THIS_MODULE,

This is not needed and coccinelle check this.
drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c:510:3-8: No need
to set .owner here. The core will do it.


Also there is one more warning.
drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c:391:1-3:
WARNING: PTR_ERR_OR_ZERO can be used

Thanks,
Michal

  reply	other threads:[~2018-05-11  6:21 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-05-07  1:20 [PATCH 00/14] staging: clocking-wizard: Implement many TODOs James Kelly
2018-05-07  1:20 ` [PATCH 01/14] staging: clocking-wizard: Add principles of operation James Kelly
2018-05-11  6:04   ` Michal Simek
2018-05-11  7:31     ` James Kelly
2018-05-11  7:59       ` Michal Simek
2018-05-14 13:36     ` Dan Carpenter
2018-05-07  1:20 ` [PATCH 02/14] staging: clocking-wizard: Reverse order of internal clocks James Kelly
2018-05-07  1:20 ` [PATCH 03/14] staging: clocking-wizard: Split probe function James Kelly
2018-05-14 13:47   ` Dan Carpenter
2018-05-14 14:47     ` Dan Carpenter
2018-05-14 19:30     ` James Kelly
2018-05-15  7:42       ` Dan Carpenter
2018-05-07  1:20 ` [PATCH 04/14] staging: clocking-wizard: Cosmetic cleanups James Kelly
2018-05-07  1:20 ` [PATCH 05/14] staging: clocking-wizard: Implement CCF clock provider James Kelly
2018-05-11  6:06   ` Michal Simek
2018-05-11  7:58     ` James Kelly
2018-05-11  8:05       ` Michal Simek
2018-05-07  1:20 ` [PATCH 06/14] staging: clocking-wizard: Swap CCF clock providers James Kelly
2018-05-11  6:21   ` Michal Simek [this message]
2018-05-11  6:24   ` Michal Simek
2018-05-07  1:20 ` [PATCH 07/14] staging: clocking-wizard: Add hardware constaints James Kelly
2018-05-07  1:20 ` [PATCH 08/14] staging: clocking-wizard: Support fractional ratios James Kelly
2018-05-07  5:00   ` kbuild test robot
2018-05-07  1:20 ` [PATCH 09/14] staging: clocking-wizard: Provide more information in debugfs James Kelly
2018-05-11  6:27   ` Michal Simek
2018-05-07  1:20 ` [PATCH 10/14] staging: clocking-wizard: Support clk_round_rate James Kelly
2018-05-11  6:31   ` Michal Simek
2018-05-15  7:52   ` Dan Carpenter
2018-05-15  7:56     ` Greg Kroah-Hartman
2018-05-07  1:20 ` [PATCH 11/14] staging: clocking-wizard: Support clk_set_rate James Kelly
2018-05-11  6:33   ` Michal Simek
2018-05-07  1:20 ` [PATCH 12/14] staging: clocking-wizard: Automatically set internal clock rates James Kelly
2018-05-07  1:20 ` [PATCH 13/14] staging: clocking-wizard: Automatically set input clock rate James Kelly
2018-05-07  1:20 ` [PATCH 14/14] staging: clocking-wizard: Add debugfs entries to facilitate testing James Kelly
2018-05-14 12:02 ` [PATCH 00/14] staging: clocking-wizard: Implement many TODOs Greg Kroah-Hartman
2018-05-14 19:32   ` James Kelly

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=56428920-38ea-b4fd-fbc1-2223b8a77781@xilinx.com \
    --to=michal.simek@xilinx.com \
    --cc=driverdev-devel@linuxdriverproject.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=jamespeterkelly@gmail.com \
    /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.