Linux MIPS Architecture development
 help / color / mirror / Atom feed
From: James Hogan <james.hogan@imgtec.com>
To: Paul Burton <paul.burton@imgtec.com>, <linux-mips@linux-mips.org>
Cc: Lars-Peter Clausen <lars@metafoo.de>,
	Mike Turquette <mturquette@linaro.org>,
	Stephen Boyd <sboyd@codeaurora.org>, <linux-clk@vger.kernel.org>
Subject: Re: [PATCH v4 25/37] clk: ingenic: add driver for Ingenic SoC CGU clocks
Date: Tue, 28 Apr 2015 11:17:44 +0100	[thread overview]
Message-ID: <553F5E48.1090905@imgtec.com> (raw)
In-Reply-To: <1429881457-16016-26-git-send-email-paul.burton@imgtec.com>

[-- Attachment #1: Type: text/plain, Size: 3973 bytes --]

Hi Paul,

On 24/04/15 14:17, Paul Burton wrote:
> +static int register_clock(struct ingenic_cgu *cgu, unsigned idx)
> +{
> +	const struct ingenic_cgu_clk_info *clk_info = &cgu->clock_info[idx];
> +	struct clk_init_data clk_init;
> +	struct ingenic_clk *ingenic_clk = NULL;
> +	struct clk *clk, *parent;
> +	const char *parent_names[4];
> +	unsigned caps, i, num_possible;
> +	int err = -EINVAL;
> +
> +	BUILD_BUG_ON(ARRAY_SIZE(clk_info->parents) > ARRAY_SIZE(parent_names));
> +
> +	if (clk_info->type == CGU_CLK_EXT) {
> +		clk = of_clk_get_by_name(cgu->np, clk_info->name);
> +		if (IS_ERR(clk)) {
> +			pr_err("%s: no external clock '%s' provided\n",
> +			       __func__, clk_info->name);
> +			err = -ENODEV;
> +			goto out;
> +		}
> +		err = clk_register_clkdev(clk, clk_info->name, NULL);
> +		if (err) {
> +			clk_put(clk);
> +			goto out;
> +		}
> +		cgu->clocks.clks[idx] = clk;
> +		return 0;
> +	}
> +
> +	if (!clk_info->type) {
> +		pr_err("%s: no clock type specified for '%s'\n", __func__,
> +		       clk_info->name);
> +		goto out;
> +	}
> +
> +	ingenic_clk = kzalloc(sizeof(*ingenic_clk), GFP_KERNEL);
> +	if (!ingenic_clk) {
> +		err = -ENOMEM;
> +		goto out;
> +	}
> +
> +	ingenic_clk->hw.init = &clk_init;
> +	ingenic_clk->cgu = cgu;
> +	ingenic_clk->idx = idx;
> +
> +	clk_init.name = clk_info->name;
> +	clk_init.flags = 0;
> +	clk_init.parent_names = parent_names;
> +
> +	caps = clk_info->type;
> +
> +	if (caps & (CGU_CLK_MUX | CGU_CLK_CUSTOM)) {
> +		clk_init.num_parents = 0;
> +
> +		if (caps & CGU_CLK_MUX)
> +			num_possible = 1 << clk_info->mux.bits;
> +		else
> +			num_possible = ARRAY_SIZE(clk_info->parents);
> +
> +		for (i = 0; i < num_possible; i++) {
> +			if (clk_info->parents[i] == -1)
> +				continue;
> +
> +			parent = cgu->clocks.clks[clk_info->parents[i]];
> +			parent_names[clk_init.num_parents] =
> +				__clk_get_name(parent);
> +			clk_init.num_parents++;
> +		}
> +
> +		BUG_ON(!clk_init.num_parents);
> +		BUG_ON(clk_init.num_parents > ARRAY_SIZE(parent_names));
> +	} else {
> +		BUG_ON(clk_info->parents[0] == -1);
> +		clk_init.num_parents = 1;
> +		parent = cgu->clocks.clks[clk_info->parents[0]];
> +		parent_names[0] = __clk_get_name(parent);
> +	}
> +
> +	if (caps & CGU_CLK_CUSTOM) {
> +		clk_init.ops = clk_info->custom.clk_ops;
> +
> +		caps &= ~CGU_CLK_CUSTOM;
> +
> +		if (caps) {
> +			pr_err("%s: custom clock may not be combined with type 0x%x\n",
> +			       __func__, caps);
> +			goto out;
> +		}
> +	} else if (caps & CGU_CLK_PLL) {
> +		clk_init.ops = &ingenic_pll_ops;
> +
> +		caps &= ~CGU_CLK_PLL;
> +
> +		if (caps) {
> +			pr_err("%s: PLL may not be combined with type 0x%x\n",
> +			       __func__, caps);
> +			goto out;
> +		}
> +	} else {
> +		clk_init.ops = &ingenic_clk_ops;
> +	}
> +
> +	/* nothing to do for gates or fixed dividers */
> +	caps &= ~(CGU_CLK_GATE | CGU_CLK_FIXDIV);
> +
> +	if (caps & CGU_CLK_MUX) {
> +		if (!(caps & CGU_CLK_MUX_GLITCHFREE))
> +			clk_init.flags |= CLK_SET_PARENT_GATE;
> +
> +		caps &= ~(CGU_CLK_MUX | CGU_CLK_MUX_GLITCHFREE);
> +	}
> +
> +	if (caps & CGU_CLK_DIV) {
> +		caps &= ~CGU_CLK_DIV;
> +	} else {
> +		/* pass rate changes to the parent clock */
> +		clk_init.flags |= CLK_SET_RATE_PARENT;
> +	}
> +
> +	if (caps) {
> +		pr_err("%s: unknown clock type 0x%x\n", __func__, caps);
> +		goto out;
> +	}
> +
> +	clk = clk_register(NULL, &ingenic_clk->hw);
> +	if (IS_ERR(clk)) {
> +		pr_err("%s: failed to register clock '%s'\n", __func__,
> +		       clk_info->name);
> +		err = PTR_ERR(clk);
> +		goto out;
> +	}
> +
> +	err = clk_register_clkdev(clk, clk_info->name, NULL);
> +	if (err)
> +		goto out;

Again, should this unregister the clock in the event of failure?

> +
> +	cgu->clocks.clks[idx] = clk;
> +out:
> +	if (err)
> +		kfree(ingenic_clk);
> +	return err;
> +}

Cheers
James


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

WARNING: multiple messages have this Message-ID (diff)
From: James Hogan <james.hogan@imgtec.com>
To: Paul Burton <paul.burton@imgtec.com>, linux-mips@linux-mips.org
Cc: Lars-Peter Clausen <lars@metafoo.de>,
	Mike Turquette <mturquette@linaro.org>,
	Stephen Boyd <sboyd@codeaurora.org>,
	linux-clk@vger.kernel.org
Subject: Re: [PATCH v4 25/37] clk: ingenic: add driver for Ingenic SoC CGU clocks
Date: Tue, 28 Apr 2015 11:17:44 +0100	[thread overview]
Message-ID: <553F5E48.1090905@imgtec.com> (raw)
Message-ID: <20150428101744.APw-jtJTONL00OlJiF0sgrwCGViesMQNab53HXiKTC8@z> (raw)
In-Reply-To: <1429881457-16016-26-git-send-email-paul.burton@imgtec.com>

[-- Attachment #1: Type: text/plain, Size: 3973 bytes --]

Hi Paul,

On 24/04/15 14:17, Paul Burton wrote:
> +static int register_clock(struct ingenic_cgu *cgu, unsigned idx)
> +{
> +	const struct ingenic_cgu_clk_info *clk_info = &cgu->clock_info[idx];
> +	struct clk_init_data clk_init;
> +	struct ingenic_clk *ingenic_clk = NULL;
> +	struct clk *clk, *parent;
> +	const char *parent_names[4];
> +	unsigned caps, i, num_possible;
> +	int err = -EINVAL;
> +
> +	BUILD_BUG_ON(ARRAY_SIZE(clk_info->parents) > ARRAY_SIZE(parent_names));
> +
> +	if (clk_info->type == CGU_CLK_EXT) {
> +		clk = of_clk_get_by_name(cgu->np, clk_info->name);
> +		if (IS_ERR(clk)) {
> +			pr_err("%s: no external clock '%s' provided\n",
> +			       __func__, clk_info->name);
> +			err = -ENODEV;
> +			goto out;
> +		}
> +		err = clk_register_clkdev(clk, clk_info->name, NULL);
> +		if (err) {
> +			clk_put(clk);
> +			goto out;
> +		}
> +		cgu->clocks.clks[idx] = clk;
> +		return 0;
> +	}
> +
> +	if (!clk_info->type) {
> +		pr_err("%s: no clock type specified for '%s'\n", __func__,
> +		       clk_info->name);
> +		goto out;
> +	}
> +
> +	ingenic_clk = kzalloc(sizeof(*ingenic_clk), GFP_KERNEL);
> +	if (!ingenic_clk) {
> +		err = -ENOMEM;
> +		goto out;
> +	}
> +
> +	ingenic_clk->hw.init = &clk_init;
> +	ingenic_clk->cgu = cgu;
> +	ingenic_clk->idx = idx;
> +
> +	clk_init.name = clk_info->name;
> +	clk_init.flags = 0;
> +	clk_init.parent_names = parent_names;
> +
> +	caps = clk_info->type;
> +
> +	if (caps & (CGU_CLK_MUX | CGU_CLK_CUSTOM)) {
> +		clk_init.num_parents = 0;
> +
> +		if (caps & CGU_CLK_MUX)
> +			num_possible = 1 << clk_info->mux.bits;
> +		else
> +			num_possible = ARRAY_SIZE(clk_info->parents);
> +
> +		for (i = 0; i < num_possible; i++) {
> +			if (clk_info->parents[i] == -1)
> +				continue;
> +
> +			parent = cgu->clocks.clks[clk_info->parents[i]];
> +			parent_names[clk_init.num_parents] =
> +				__clk_get_name(parent);
> +			clk_init.num_parents++;
> +		}
> +
> +		BUG_ON(!clk_init.num_parents);
> +		BUG_ON(clk_init.num_parents > ARRAY_SIZE(parent_names));
> +	} else {
> +		BUG_ON(clk_info->parents[0] == -1);
> +		clk_init.num_parents = 1;
> +		parent = cgu->clocks.clks[clk_info->parents[0]];
> +		parent_names[0] = __clk_get_name(parent);
> +	}
> +
> +	if (caps & CGU_CLK_CUSTOM) {
> +		clk_init.ops = clk_info->custom.clk_ops;
> +
> +		caps &= ~CGU_CLK_CUSTOM;
> +
> +		if (caps) {
> +			pr_err("%s: custom clock may not be combined with type 0x%x\n",
> +			       __func__, caps);
> +			goto out;
> +		}
> +	} else if (caps & CGU_CLK_PLL) {
> +		clk_init.ops = &ingenic_pll_ops;
> +
> +		caps &= ~CGU_CLK_PLL;
> +
> +		if (caps) {
> +			pr_err("%s: PLL may not be combined with type 0x%x\n",
> +			       __func__, caps);
> +			goto out;
> +		}
> +	} else {
> +		clk_init.ops = &ingenic_clk_ops;
> +	}
> +
> +	/* nothing to do for gates or fixed dividers */
> +	caps &= ~(CGU_CLK_GATE | CGU_CLK_FIXDIV);
> +
> +	if (caps & CGU_CLK_MUX) {
> +		if (!(caps & CGU_CLK_MUX_GLITCHFREE))
> +			clk_init.flags |= CLK_SET_PARENT_GATE;
> +
> +		caps &= ~(CGU_CLK_MUX | CGU_CLK_MUX_GLITCHFREE);
> +	}
> +
> +	if (caps & CGU_CLK_DIV) {
> +		caps &= ~CGU_CLK_DIV;
> +	} else {
> +		/* pass rate changes to the parent clock */
> +		clk_init.flags |= CLK_SET_RATE_PARENT;
> +	}
> +
> +	if (caps) {
> +		pr_err("%s: unknown clock type 0x%x\n", __func__, caps);
> +		goto out;
> +	}
> +
> +	clk = clk_register(NULL, &ingenic_clk->hw);
> +	if (IS_ERR(clk)) {
> +		pr_err("%s: failed to register clock '%s'\n", __func__,
> +		       clk_info->name);
> +		err = PTR_ERR(clk);
> +		goto out;
> +	}
> +
> +	err = clk_register_clkdev(clk, clk_info->name, NULL);
> +	if (err)
> +		goto out;

Again, should this unregister the clock in the event of failure?

> +
> +	cgu->clocks.clks[idx] = clk;
> +out:
> +	if (err)
> +		kfree(ingenic_clk);
> +	return err;
> +}

Cheers
James


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

  parent reply	other threads:[~2015-04-28 10:17 UTC|newest]

Thread overview: 101+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-04-24 13:17 [PATCH v4 00/37] JZ4780 & CI20 support Paul Burton
2015-04-24 13:17 ` Paul Burton
2015-04-24 13:17 ` [PATCH v4 01/37] devicetree/bindings: add Ingenic Semiconductor vendor prefix Paul Burton
2015-04-24 13:17   ` Paul Burton
2015-04-24 13:17 ` [PATCH v4 02/37] devicetree/bindings: add Qi Hardware " Paul Burton
2015-04-24 13:17   ` Paul Burton
2015-04-24 13:17 ` [PATCH v4 03/37] MIPS: JZ4740: introduce CONFIG_MACH_INGENIC Paul Burton
2015-04-24 13:17   ` Paul Burton
2015-04-24 13:17 ` [PATCH v4 04/37] MIPS: ingenic: add newer vendor IDs Paul Burton
2015-04-24 13:17   ` Paul Burton
2015-04-24 13:17 ` [PATCH v4 05/37] MIPS: JZ4740: require & include DT Paul Burton
2015-04-24 13:17   ` Paul Burton
2015-04-24 13:17 ` [PATCH v4 06/37] MIPS: irq_cpu: declare irqchip table entry Paul Burton
2015-04-24 13:17   ` Paul Burton
2015-04-24 13:17 ` [PATCH v4 07/37] MIPS: JZ4740: probe CPU interrupt controller via DT Paul Burton
2015-04-24 13:17   ` Paul Burton
2015-04-24 13:17 ` [PATCH v4 08/37] MIPS: JZ4740: use generic plat_irq_dispatch Paul Burton
2015-04-24 13:17   ` Paul Burton
2015-04-24 13:17 ` [PATCH v4 09/37] MIPS: JZ4740: move arch_init_irq out of arch/mips/jz4740/irq.c Paul Burton
2015-04-24 13:17   ` Paul Burton
2015-04-24 13:17 ` [PATCH v4 10/37] devicetree: document Ingenic SoC interrupt controller binding Paul Burton
2015-04-24 13:17   ` Paul Burton
2015-04-24 13:17 ` [PATCH v4 11/37] MIPS: JZ4740: probe interrupt controller via DT Paul Burton
2015-04-24 13:17   ` Paul Burton
2015-04-24 13:17 ` [PATCH v4 12/37] MIPS: JZ4740: parse SoC interrupt controller parent IRQ from DT Paul Burton
2015-04-24 13:17   ` Paul Burton
2015-04-24 13:17 ` [PATCH v4 13/37] MIPS: JZ4740: register an irq_domain for the interrupt controller Paul Burton
2015-04-24 13:17   ` Paul Burton
2015-04-28 10:46   ` James Hogan
2015-04-28 10:46     ` James Hogan
2015-04-24 13:17 ` [PATCH v4 14/37] MIPS: JZ4740: drop intc debugfs code Paul Burton
2015-04-24 13:17   ` Paul Burton
2015-04-28  7:20   ` Lars-Peter Clausen
2015-04-24 13:17 ` [PATCH v4 15/37] MIPS: JZ4740: remove jz_intc_base global Paul Burton
2015-04-24 13:17   ` Paul Burton
2015-04-27 22:35   ` James Hogan
2015-04-27 22:35     ` James Hogan
2015-04-24 13:17 ` [PATCH v4 16/37] MIPS: JZ4740: support >32 interrupts Paul Burton
2015-04-24 13:17   ` Paul Burton
2015-04-24 13:17 ` [PATCH v4 17/37] MIPS: JZ4740: define IRQ numbers based on number of intc IRQs Paul Burton
2015-04-24 13:17   ` Paul Burton
2015-04-24 13:17 ` [PATCH v4 18/37] MIPS: JZ4740: read intc base address from DT Paul Burton
2015-04-24 13:17   ` Paul Burton
2015-04-24 13:17 ` [PATCH v4 19/37] MIPS: JZ4740: avoid JZ4740-specific naming Paul Burton
2015-04-24 13:17   ` Paul Burton
2015-04-24 13:17 ` [PATCH v4 20/37] MIPS: JZ4740: support newer SoC interrupt controllers Paul Burton
2015-04-24 13:17   ` Paul Burton
2015-04-28 11:03   ` James Hogan
2015-04-28 11:03     ` James Hogan
2015-04-24 13:17 ` [PATCH v4 21/37] irqchip: move Ingenic SoC intc driver to drivers/irqchip Paul Burton
2015-04-24 13:17   ` Paul Burton
2015-04-24 13:17 ` [PATCH v4 22/37] MIPS: JZ4740: call jz4740_clock_init earlier Paul Burton
2015-04-24 13:17   ` Paul Burton
2015-04-24 13:17 ` [PATCH v4 23/37] MIPS: JZ4740: replace use of jz4740_clock_bdata Paul Burton
2015-04-24 13:17   ` Paul Burton
2015-04-24 13:17 ` [PATCH v4 24/37] devicetree: add Ingenic CGU binding documentation Paul Burton
2015-04-24 13:17   ` Paul Burton
2015-04-24 13:17 ` [PATCH v4 25/37] clk: ingenic: add driver for Ingenic SoC CGU clocks Paul Burton
2015-04-24 13:17   ` Paul Burton
2015-04-27 23:00   ` James Hogan
2015-04-27 23:00     ` James Hogan
2015-04-28 10:17   ` James Hogan [this message]
2015-04-28 10:17     ` James Hogan
2015-05-20 23:16   ` Stephen Boyd
2015-04-24 13:17 ` [PATCH v4 26/37] MIPS,clk: migrate JZ4740 to common clock framework Paul Burton
2015-04-24 13:17   ` Paul Burton
2015-05-13  2:52   ` Michael Turquette
2015-05-13  2:52     ` Michael Turquette
2015-05-24 15:01     ` Paul Burton
2015-05-24 15:01       ` Paul Burton
2015-04-24 13:17 ` [PATCH v4 27/37] MIPS,clk: move jz4740_clock_set_wait_mode to jz4740-cgu Paul Burton
2015-04-24 13:17   ` Paul Burton
2015-05-13  2:56   ` [PATCH v4 27/37] MIPS, clk: " Michael Turquette
2015-05-13  2:56     ` Michael Turquette
2015-04-24 13:17 ` [PATCH v4 28/37] MIPS,clk: move jz4740 UDC auto suspend functions " Paul Burton
2015-04-24 13:17   ` Paul Burton
2015-05-13  3:06   ` [PATCH v4 28/37] MIPS, clk: " Michael Turquette
2015-05-13  3:06     ` Michael Turquette
2015-05-24 15:02     ` Paul Burton
2015-05-24 15:02       ` Paul Burton
2015-04-24 13:17 ` [PATCH v4 29/37] MIPS,clk: move jz4740 clock suspend,resume " Paul Burton
2015-04-24 13:17   ` Paul Burton
2015-04-24 13:17 ` [PATCH v4 30/37] clk: ingenic: add JZ4780 CGU support Paul Burton
2015-04-24 13:17   ` Paul Burton
2015-05-20 23:07   ` Stephen Boyd
2015-04-24 13:17 ` [PATCH v4 31/37] MIPS: JZ4740: remove clock.h Paul Burton
2015-04-24 13:17   ` Paul Burton
2015-04-24 13:17 ` [PATCH v4 32/37] MIPS: JZ4740: only detect RAM size if not specified in DT Paul Burton
2015-04-24 13:17   ` Paul Burton
2015-04-24 13:17 ` [PATCH v4 33/37] devicetree: document Ingenic SoC UART binding Paul Burton
2015-04-24 13:17   ` Paul Burton
2015-04-24 13:17 ` [PATCH v4 34/37] serial: 8250_ingenic: support for Ingenic SoC UARTs Paul Burton
2015-04-24 13:17   ` Paul Burton
2015-04-24 13:17 ` [PATCH v4 35/37] MIPS: JZ4740: use Ingenic SoC UART driver Paul Burton
2015-04-24 13:17   ` Paul Burton
2015-04-24 13:17 ` [PATCH v4 36/37] MIPS: ingenic: initial JZ4780 support Paul Burton
2015-04-24 13:17   ` Paul Burton
2015-04-28 10:36   ` James Hogan
2015-04-28 10:36     ` James Hogan
2015-04-24 13:17 ` [PATCH v4 37/37] MIPS: ingenic: initial MIPS Creator CI20 support Paul Burton
2015-04-24 13:17   ` Paul Burton

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=553F5E48.1090905@imgtec.com \
    --to=james.hogan@imgtec.com \
    --cc=lars@metafoo.de \
    --cc=linux-clk@vger.kernel.org \
    --cc=linux-mips@linux-mips.org \
    --cc=mturquette@linaro.org \
    --cc=paul.burton@imgtec.com \
    --cc=sboyd@codeaurora.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox