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 --]
next prev 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