[v1,1/1] clk: npcm7xx: get fixed clocks from DT

Message ID 20181111134712.318321-2-tali.perry1@gmail.com
State Not Applicable, archived
Headers show
Series
  • clk: npcm7xx: fix base address and of_clk_get_by_name
Related show

Commit Message

Tali Perry Nov. 11, 2018, 1:47 p.m.
From: Tali Perry <tali.perry1@gmail.com>

Nuvoton NPCM7XX Clock Controller
fix base address and of_clk_get_by_name error handling.
    Also update error messages to be more informative.
    
    In case clk_base allocation is erronoeous the return value is null.
    Also fix handling of of_clk_get_by_name returns an error. 
    Print a better error message pointing to the dt-binding documention.

This patch is re-submitted since it was already pushed to main 
(just the diff, without the full driver which is already in 
master branch.)


Signed-off-by: Tali Perry <tali.perry1@gmail.com>
Reviewed-by: Rob Herring <robh@kernel.org>
Signed-off-by: Wei Yongjun <weiyongjun1@huawei.com>

---
 drivers/clk/clk-npcm7xx.c | 99 +++++++++++++++++++++++++++++++++++------------
 1 file changed, 75 insertions(+), 24 deletions(-)

Comments

Stephen Boyd Nov. 30, 2018, 12:23 a.m. | #1
Quoting tali.perry1@gmail.com (2018-11-11 05:47:12)
> From: Tali Perry <tali.perry1@gmail.com>
> 
> Nuvoton NPCM7XX Clock Controller
> fix base address and of_clk_get_by_name error handling.
>     Also update error messages to be more informative.
>     
>     In case clk_base allocation is erronoeous the return value is null.
>     Also fix handling of of_clk_get_by_name returns an error. 
>     Print a better error message pointing to the dt-binding documention.
> 
> This patch is re-submitted since it was already pushed to main 
> (just the diff, without the full driver which is already in 
> master branch.)
> 
> 
> Signed-off-by: Tali Perry <tali.perry1@gmail.com>
> Reviewed-by: Rob Herring <robh@kernel.org>
> Signed-off-by: Wei Yongjun <weiyongjun1@huawei.com>
> 

I don't know what's going on with this patch. Is it something new? Can
you break it up into logical changes and submit them with proper commit
text? The signoff chain is also odd. Can you follow
Documentation/process/submitting-patches.rst?

> ---
>  drivers/clk/clk-npcm7xx.c | 99 +++++++++++++++++++++++++++++++++++------------
>  1 file changed, 75 insertions(+), 24 deletions(-)
> 
> diff --git a/drivers/clk/clk-npcm7xx.c b/drivers/clk/clk-npcm7xx.c
> index 740af90a9508..91a937720f4e 100644
> --- a/drivers/clk/clk-npcm7xx.c
> +++ b/drivers/clk/clk-npcm7xx.c
> @@ -7,17 +7,26 @@
>   * Copyright (C) 2018 Nuvoton Technologies tali.perry@nuvoton.com
>   */
>  
> -#include <linux/module.h>
> -#include <linux/clk-provider.h>
> -#include <linux/io.h>
> -#include <linux/kernel.h>
> -#include <linux/of.h>
> -#include <linux/of_address.h>
> -#include <linux/slab.h>
> -#include <linux/err.h>
> -#include <linux/bitfield.h>
> -
> -#include <dt-bindings/clock/nuvoton,npcm7xx-clock.h>
> +
> +
> +
> + #include <linux/module.h>
> + #include <linux/clk.h>
> + #include <linux/clk-provider.h>
> + #include <linux/device.h>
> + #include <linux/io.h>
> + #include <linux/kernel.h>
> + #include <linux/of.h>
> + #include <linux/of_device.h>
> + #include <linux/of_platform.h>
> + #include <linux/of_address.h>
> + #include <linux/platform_device.h>
> + #include <linux/slab.h>
> + #include <linux/err.h>
> + #include <linux/rational.h>
> + #include <linux/bitfield.h>
> + #include <dt-bindings/clock/nuvoton,npcm7xx-clock.h>

Is any of this hunk necessary or relevant to the subject of this patch?

> +
>  
>  struct npcm7xx_clk_pll {
> @@ -44,7 +56,8 @@ static unsigned long npcm7xx_clk_pll_recalc_rate(struct clk_hw *hw,
>         u64 ret;
>  
>         if (parent_rate == 0) {
> -               pr_err("%s: parent rate is zero", __func__);
> +               pr_err("%s: parent rate is zero. reg=%x\n", __func__,
> +                       (u32)(pll->pllcon));

Maybe you should print clk name instead of register?

>                 return 0;
>         }
>  
> @@ -61,13 +74,12 @@ static unsigned long npcm7xx_clk_pll_recalc_rate(struct clk_hw *hw,
>         return ret;
>  }
>  
> -static const struct clk_ops npcm7xx_clk_pll_ops = {
> +const struct clk_ops npcm7xx_clk_pll_ops = {

Why?

>         .recalc_rate = npcm7xx_clk_pll_recalc_rate,
>  };
>  
> -static struct clk_hw *
> -npcm7xx_clk_register_pll(void __iomem *pllcon, const char *name,
> -                        const char *parent_name, unsigned long flags)
> +static struct clk_hw *npcm7xx_clk_register_pll(void __iomem *pllcon,
> +               const char *name, const char *parent_name, unsigned long flags)
>  {
>         struct npcm7xx_clk_pll *pll;
>         struct clk_init_data init;
> @@ -78,7 +90,8 @@ npcm7xx_clk_register_pll(void __iomem *pllcon, const char *name,
>         if (!pll)
>                 return ERR_PTR(-ENOMEM);
>  
> -       pr_debug("%s reg, name=%s, p=%s\n", __func__, name, parent_name);
> +       pr_debug("%s reg, reg=0x%x, name=%s, p=%s\n",
> +               __func__, (unsigned int)pllcon, name, parent_name);

What's going on here? Why cast?

>  
>         init.name = name;
>         init.ops = &npcm7xx_clk_pll_ops;
> @@ -544,9 +557,11 @@ static void __init npcm7xx_clk_init(struct device_node *clk_np)
>         void __iomem *clk_base;
>         struct resource res;
>         struct clk_hw *hw;
> +       struct clk *clk;
>         int ret;
>         int i;
>  
> +       clk_base = NULL;

Why?

>         ret = of_address_to_resource(clk_np, 0, &res);
>         if (ret) {
>                 pr_err("%s: failed to get resource, ret %d\n", clk_np->name,
> @@ -560,14 +575,44 @@ static void __init npcm7xx_clk_init(struct device_node *clk_np)
>  
>         npcm7xx_clk_data = kzalloc(sizeof(*npcm7xx_clk_data->hws) *
>                 NPCM7XX_NUM_CLOCKS + sizeof(npcm7xx_clk_data), GFP_KERNEL);
> -       if (!npcm7xx_clk_data)
> +
> +       npcm7xx_clk_data->num = 0;

kzalloc already does that initialization to 0 for you.

> +
> +       if (!npcm7xx_clk_data->hws) {
> +               pr_err("Can't alloc npcm7xx_clk_data\n");

We don't need allocation error messages.

>                 goto npcm7xx_init_np_err;
> +       }
>  
>         npcm7xx_clk_data->num = NPCM7XX_NUM_CLOCKS;
>  
>         for (i = 0; i < NPCM7XX_NUM_CLOCKS; i++)
>                 npcm7xx_clk_data->hws[i] = ERR_PTR(-EPROBE_DEFER);
>  
> +       /* Read fixed clocks. These 3 clocks must be defined in DT */
> +       clk = of_clk_get_by_name(clk_np, NPCM7XX_CLK_S_REFCLK);
> +       if (IS_ERR(clk)) {
> +               pr_err("failed to find external REFCLK on device tree, err=%ld\n",
> +                       PTR_ERR(clk));
> +               clk_put(clk);
> +               goto npcm7xx_init_fail_no_clk_on_dt;
> +       }
> +
> +       clk = of_clk_get_by_name(clk_np, NPCM7XX_CLK_S_SYSBYPCK);
> +       if (IS_ERR(clk)) {
> +               pr_err("failed to find external SYSBYPCK on device tree, err=%ld\n",
> +                       PTR_ERR(clk));
> +               clk_put(clk);
> +               goto npcm7xx_init_fail_no_clk_on_dt;
> +       }
> +
> +       clk = of_clk_get_by_name(clk_np, NPCM7XX_CLK_S_MCBYPCK);
> +       if (IS_ERR(clk)) {
> +               pr_err("failed to find external MCBYPCK on device tree, err=%ld\n",
> +                       PTR_ERR(clk));
> +               clk_put(clk);
> +               goto npcm7xx_init_fail_no_clk_on_dt;
> +       }

I assume the DTS is not shipped?

> +
>         /* Register plls */
>         for (i = 0; i < ARRAY_SIZE(npcm7xx_plls); i++) {
>                 const struct npcm7xx_clk_pll_data *pll_data = &npcm7xx_plls[i];
> @@ -584,16 +629,16 @@ static void __init npcm7xx_clk_init(struct device_node *clk_np)
>         }
>  
>         /* Register fixed dividers */
> -       hw = clk_hw_register_fixed_factor(NULL, NPCM7XX_CLK_S_PLL1_DIV2,
> +       clk = clk_register_fixed_factor(NULL, NPCM7XX_CLK_S_PLL1_DIV2,

This is going backwards. Please use clk_hw APIs.

>                         NPCM7XX_CLK_S_PLL1, 0, 1, 2);
> -       if (IS_ERR(hw)) {
> +       if (IS_ERR(clk)) {
>                 pr_err("npcm7xx_clk: Can't register fixed div\n");
>                 goto npcm7xx_init_fail;
>         }
>  
> -       hw = clk_hw_register_fixed_factor(NULL, NPCM7XX_CLK_S_PLL2_DIV2,
> +       clk = clk_register_fixed_factor(NULL, NPCM7XX_CLK_S_PLL2_DIV2,
>                         NPCM7XX_CLK_S_PLL2, 0, 1, 2);
> -       if (IS_ERR(hw)) {
> +       if (IS_ERR(clk)) {
>                 pr_err("npcm7xx_clk: Can't register div2\n");
>                 goto npcm7xx_init_fail;
>         }
> @@ -646,11 +691,17 @@ static void __init npcm7xx_clk_init(struct device_node *clk_np)
>  
>         return;
>  
> +npcm7xx_init_fail_no_clk_on_dt:
> +       pr_err("see Documentation/devicetree/bindings/clock/");
> +       pr_err("nuvoton,npcm750-clk.txt  for details\n");
>  npcm7xx_init_fail:
> -       kfree(npcm7xx_clk_data->hws);
> +       if (npcm7xx_clk_data->num)
> +               kfree(npcm7xx_clk_data->hws);
>  npcm7xx_init_np_err:
> -       iounmap(clk_base);
> +       if (clk_base != NULL)
> +               iounmap(clk_base);
>  npcm7xx_init_error:
>         of_node_put(clk_np);
> +       pr_err("clk setup fail\n");

Is this hunk of changes related to the subject of this patch? I don't
think it is, so it just leads to more confusion.
Tali Perry Dec. 4, 2018, 3:49 p.m. | #2
Hi Stephan,

Thanks for all the comments!

This patch include one change so it's one commit.
This clock module includes 4 PLLs and then a tree of muxes and dividers.
All muxes and dividers are preset before Linux boots. The presetting can
change according to the board.
Linux drivers need to know what the frequencies are, but they can not
change it,
so this whole driver is intended as read only mechanism for clocks.

On the first version which was up-streamed the PLLs input clk value was
defined inside the driver.

After the review I was asked that the fixed clock will be on the DT. This
is this fix.


This patch was submitted, but not pushed to Linux:
https://www.mail-archive.com/linux-kernel@vger.kernel.org/msg1610776.html

Meanwhile first version was pushed to the Kernel, So recreate a patch that
is relative between the two patches.


More comments inline..



On Fri, Nov 30, 2018 at 2:23 AM Stephen Boyd <sboyd@kernel.org> wrote:

> Quoting tali.perry1@gmail.com (2018-11-11 05:47:12)
> > From: Tali Perry <tali.perry1@gmail.com>
> >
> > Nuvoton NPCM7XX Clock Controller
> > fix base address and of_clk_get_by_name error handling.
> >     Also update error messages to be more informative.
> >
> >     In case clk_base allocation is erronoeous the return value is null.
> >     Also fix handling of of_clk_get_by_name returns an error.
> >     Print a better error message pointing to the dt-binding documention.
> >
> > This patch is re-submitted since it was already pushed to main
> > (just the diff, without the full driver which is already in
> > master branch.)
> >
> >
> > Signed-off-by: Tali Perry <tali.perry1@gmail.com>
> > Reviewed-by: Rob Herring <robh@kernel.org>
> > Signed-off-by: Wei Yongjun <weiyongjun1@huawei.com>
> >
>
> I don't know what's going on with this patch. Is it something new? Can
> you break it up into logical changes and submit them with proper commit
> text? The signoff chain is also odd. Can you follow
> Documentation/process/submitting-patches.rst?
>
> > ---
> >  drivers/clk/clk-npcm7xx.c | 99
> +++++++++++++++++++++++++++++++++++------------
> >  1 file changed, 75 insertions(+), 24 deletions(-)
> >
> > diff --git a/drivers/clk/clk-npcm7xx.c b/drivers/clk/clk-npcm7xx.c
> > index 740af90a9508..91a937720f4e 100644
> > --- a/drivers/clk/clk-npcm7xx.c
> > +++ b/drivers/clk/clk-npcm7xx.c
> > @@ -7,17 +7,26 @@
> >   * Copyright (C) 2018 Nuvoton Technologies tali.perry@nuvoton.com
> >   */
> >
> > -#include <linux/module.h>
> > -#include <linux/clk-provider.h>
> > -#include <linux/io.h>
> > -#include <linux/kernel.h>
> > -#include <linux/of.h>
> > -#include <linux/of_address.h>
> > -#include <linux/slab.h>
> > -#include <linux/err.h>
> > -#include <linux/bitfield.h>
> > -
> > -#include <dt-bindings/clock/nuvoton,npcm7xx-clock.h>
> > +
> > +
> > +
> > + #include <linux/module.h>
> > + #include <linux/clk.h>
> > + #include <linux/clk-provider.h>
> > + #include <linux/device.h>
> > + #include <linux/io.h>
> > + #include <linux/kernel.h>
> > + #include <linux/of.h>
> > + #include <linux/of_device.h>
> > + #include <linux/of_platform.h>
> > + #include <linux/of_address.h>
> > + #include <linux/platform_device.h>
> > + #include <linux/slab.h>
> > + #include <linux/err.h>
> > + #include <linux/rational.h>
> > + #include <linux/bitfield.h>
> > + #include <dt-bindings/clock/nuvoton,npcm7xx-clock.h>
>
> Is any of this hunk necessary or relevant to the subject of this patch?
>
> > +
> >
> >  struct npcm7xx_clk_pll {
> > @@ -44,7 +56,8 @@ static unsigned long
> npcm7xx_clk_pll_recalc_rate(struct clk_hw *hw,
> >         u64 ret;
> >
> >         if (parent_rate == 0) {
> > -               pr_err("%s: parent rate is zero", __func__);
> > +               pr_err("%s: parent rate is zero. reg=%x\n", __func__,
> > +                       (u32)(pll->pllcon));
>
> Maybe you should print clk name instead of register?
>

Tali: There are only 4 pllcon registers. I don't mind if it's the address
and not the name.

>
> >                 return 0;
> >         }
> >
> > @@ -61,13 +74,12 @@ static unsigned long
> npcm7xx_clk_pll_recalc_rate(struct clk_hw *hw,
> >         return ret;
> >  }
> >
> > -static const struct clk_ops npcm7xx_clk_pll_ops = {
> > +const struct clk_ops npcm7xx_clk_pll_ops = {
>
> Why?
>

Tali: I will return the static.

>
> >         .recalc_rate = npcm7xx_clk_pll_recalc_rate,
> >  };
> >
> > -static struct clk_hw *
> > -npcm7xx_clk_register_pll(void __iomem *pllcon, const char *name,
> > -                        const char *parent_name, unsigned long flags)
> > +static struct clk_hw *npcm7xx_clk_register_pll(void __iomem *pllcon,
> > +               const char *name, const char *parent_name, unsigned long
> flags)
> >  {
> >         struct npcm7xx_clk_pll *pll;
> >         struct clk_init_data init;
> > @@ -78,7 +90,8 @@ npcm7xx_clk_register_pll(void __iomem *pllcon, const
> char *name,
> >         if (!pll)
> >                 return ERR_PTR(-ENOMEM);
> >
> > -       pr_debug("%s reg, name=%s, p=%s\n", __func__, name, parent_name);
> > +       pr_debug("%s reg, reg=0x%x, name=%s, p=%s\n",
> > +               __func__, (unsigned int)pllcon, name, parent_name);
>
> What's going on here? Why cast?
>
Tali: I will remove this print all together.

>
> >
> >         init.name = name;
> >         init.ops = &npcm7xx_clk_pll_ops;
> > @@ -544,9 +557,11 @@ static void __init npcm7xx_clk_init(struct
> device_node *clk_np)
> >         void __iomem *clk_base;
> >         struct resource res;
> >         struct clk_hw *hw;
> > +       struct clk *clk;
> >         int ret;
> >         int i;
> >
> > +       clk_base = NULL;
>
> Why?
>

Tali: to init it. If DT is badly defined the value will remain NULL.


>
> >         ret = of_address_to_resource(clk_np, 0, &res);
> >         if (ret) {
> >                 pr_err("%s: failed to get resource, ret %d\n",
> clk_np->name,
> > @@ -560,14 +575,44 @@ static void __init npcm7xx_clk_init(struct
> device_node *clk_np)
> >
> >         npcm7xx_clk_data = kzalloc(sizeof(*npcm7xx_clk_data->hws) *
> >                 NPCM7XX_NUM_CLOCKS + sizeof(npcm7xx_clk_data),
> GFP_KERNEL);
> > -       if (!npcm7xx_clk_data)
> > +
> > +       npcm7xx_clk_data->num = 0;
>
> kzalloc already does that initialization to 0 for you.
>
> > +
> > +       if (!npcm7xx_clk_data->hws) {
> > +               pr_err("Can't alloc npcm7xx_clk_data\n");
>
> We don't need allocation error messages.
>
> >                 goto npcm7xx_init_np_err;
> > +       }
> >
> >         npcm7xx_clk_data->num = NPCM7XX_NUM_CLOCKS;
> >
> >         for (i = 0; i < NPCM7XX_NUM_CLOCKS; i++)
> >                 npcm7xx_clk_data->hws[i] = ERR_PTR(-EPROBE_DEFER);
> >
> > +       /* Read fixed clocks. These 3 clocks must be defined in DT */
> > +       clk = of_clk_get_by_name(clk_np, NPCM7XX_CLK_S_REFCLK);
> > +       if (IS_ERR(clk)) {
> > +               pr_err("failed to find external REFCLK on device tree,
> err=%ld\n",
> > +                       PTR_ERR(clk));
> > +               clk_put(clk);
> > +               goto npcm7xx_init_fail_no_clk_on_dt;
> > +       }
> > +
> > +       clk = of_clk_get_by_name(clk_np, NPCM7XX_CLK_S_SYSBYPCK);
> > +       if (IS_ERR(clk)) {
> > +               pr_err("failed to find external SYSBYPCK on device tree,
> err=%ld\n",
> > +                       PTR_ERR(clk));
> > +               clk_put(clk);
> > +               goto npcm7xx_init_fail_no_clk_on_dt;
> > +       }
> > +
> > +       clk = of_clk_get_by_name(clk_np, NPCM7XX_CLK_S_MCBYPCK);
> > +       if (IS_ERR(clk)) {
> > +               pr_err("failed to find external MCBYPCK on device tree,
> err=%ld\n",
> > +                       PTR_ERR(clk));
> > +               clk_put(clk);
> > +               goto npcm7xx_init_fail_no_clk_on_dt;
> > +       }
>
> I assume the DTS is not shipped?
>

Tali: DTS for npcm is shipped in a separate patchset.

>
> > +
> >         /* Register plls */
> >         for (i = 0; i < ARRAY_SIZE(npcm7xx_plls); i++) {
> >                 const struct npcm7xx_clk_pll_data *pll_data =
> &npcm7xx_plls[i];
> > @@ -584,16 +629,16 @@ static void __init npcm7xx_clk_init(struct
> device_node *clk_np)
> >         }
> >
> >         /* Register fixed dividers */
> > -       hw = clk_hw_register_fixed_factor(NULL, NPCM7XX_CLK_S_PLL1_DIV2,
> > +       clk = clk_register_fixed_factor(NULL, NPCM7XX_CLK_S_PLL1_DIV2,
>
> This is going backwards. Please use clk_hw APIs.
>
Tali: Will fix.

>
> >                         NPCM7XX_CLK_S_PLL1, 0, 1, 2);
> > -       if (IS_ERR(hw)) {
> > +       if (IS_ERR(clk)) {
> >                 pr_err("npcm7xx_clk: Can't register fixed div\n");
> >                 goto npcm7xx_init_fail;
> >         }
> >
> > -       hw = clk_hw_register_fixed_factor(NULL, NPCM7XX_CLK_S_PLL2_DIV2,
> > +       clk = clk_register_fixed_factor(NULL, NPCM7XX_CLK_S_PLL2_DIV2,
> >                         NPCM7XX_CLK_S_PLL2, 0, 1, 2);
> > -       if (IS_ERR(hw)) {
> > +       if (IS_ERR(clk)) {
> >                 pr_err("npcm7xx_clk: Can't register div2\n");
> >                 goto npcm7xx_init_fail;
> >         }
> > @@ -646,11 +691,17 @@ static void __init npcm7xx_clk_init(struct
> device_node *clk_np)
> >
> >         return;
> >
> > +npcm7xx_init_fail_no_clk_on_dt:
> > +       pr_err("see Documentation/devicetree/bindings/clock/");
> > +       pr_err("nuvoton,npcm750-clk.txt  for details\n");
> >  npcm7xx_init_fail:
> > -       kfree(npcm7xx_clk_data->hws);
> > +       if (npcm7xx_clk_data->num)
> > +               kfree(npcm7xx_clk_data->hws);
> >  npcm7xx_init_np_err:
> > -       iounmap(clk_base);
> > +       if (clk_base != NULL)
> > +               iounmap(clk_base);
> >  npcm7xx_init_error:
> >         of_node_put(clk_np);
> > +       pr_err("clk setup fail\n");
>
> Is this hunk of changes related to the subject of this patch? I don't
> think it is, so it just leads to more confusion.
>

Tali: I added a goto option for the case that the DTS doesn't have the
reference clocks this module needs.
<div dir="ltr"><div dir="ltr"><div dir="ltr"><div class="gmail_default" style="font-family:monospace,monospace">Hi Stephan,</div><div class="gmail_default" style="font-family:monospace,monospace"><br></div><div class="gmail_default" style="font-family:monospace,monospace">Thanks for all the comments!</div><div class="gmail_default" style="font-family:monospace,monospace"><br></div><div class="gmail_default" style="font-family:monospace,monospace">This patch include one change so it&#39;s one commit. </div><div class="gmail_default" style="font-family:monospace,monospace">This clock module includes 4 PLLs and then a tree of muxes and dividers. </div><div class="gmail_default" style="font-family:monospace,monospace">All muxes and dividers are preset before Linux boots. The presetting can change according to the board. </div><div class="gmail_default" style="font-family:monospace,monospace">Linux drivers need to know what the frequencies are, but they can not change it, </div><div class="gmail_default" style="font-family:monospace,monospace">so this whole driver is intended as read only mechanism for clocks. </div><div class="gmail_default" style="font-family:monospace,monospace"><br></div><div class="gmail_default" style="font-family:monospace,monospace">On the first version which was up-streamed the PLLs input clk value was defined inside the driver.</div><div class="gmail_default" style="font-family:monospace,monospace"><br></div><div class="gmail_default" style="font-family:monospace,monospace">After the review I was asked that the fixed clock will be on the DT. This is this fix.</div><div class="gmail_default" style="font-family:monospace,monospace"><br></div><div class="gmail_default"><br></div><div class="gmail_default" style="font-family:monospace,monospace">This patch was submitted, but not pushed to Linux: </div><div class="gmail_default" style="font-family:monospace,monospace"><div class="gmail_default" style="font-family:Arial,Helvetica,sans-serif"><font face="monospace, monospace"><a href="https://www.mail-archive.com/linux-kernel@vger.kernel.org/msg1610776.html">https://www.mail-archive.com/linux-kernel@vger.kernel.org/msg1610776.html</a></font><br></div><div class="gmail_default" style="font-family:Arial,Helvetica,sans-serif"><font face="monospace, monospace"><br></font></div><div class="gmail_default" style="font-family:Arial,Helvetica,sans-serif"><font face="monospace, monospace">Meanwhile first version was pushed to the Kernel, So recreate a patch that is relative between the two patches.</font></div><div class="gmail_default" style="font-family:Arial,Helvetica,sans-serif"><br></div><div class="gmail_default" style="font-family:Arial,Helvetica,sans-serif"><br></div><div class="gmail_default" style="font-family:Arial,Helvetica,sans-serif">More comments inline..</div></div><div class="gmail_default" style="font-family:monospace,monospace"><br></div><div class="gmail_default" style="font-family:monospace,monospace"><br></div></div></div><br><div class="gmail_quote"><div dir="ltr">On Fri, Nov 30, 2018 at 2:23 AM Stephen Boyd &lt;<a href="mailto:sboyd@kernel.org" target="_blank">sboyd@kernel.org</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Quoting <a href="mailto:tali.perry1@gmail.com" target="_blank">tali.perry1@gmail.com</a> (2018-11-11 05:47:12)<br>
&gt; From: Tali Perry &lt;<a href="mailto:tali.perry1@gmail.com" target="_blank">tali.perry1@gmail.com</a>&gt;<br>
&gt; <br>
&gt; Nuvoton NPCM7XX Clock Controller<br>
&gt; fix base address and of_clk_get_by_name error handling.<br>
&gt;     Also update error messages to be more informative.<br>
&gt;     <br>
&gt;     In case clk_base allocation is erronoeous the return value is null.<br>
&gt;     Also fix handling of of_clk_get_by_name returns an error. <br>
&gt;     Print a better error message pointing to the dt-binding documention.<br>
&gt; <br>
&gt; This patch is re-submitted since it was already pushed to main <br>
&gt; (just the diff, without the full driver which is already in <br>
&gt; master branch.)<br>
&gt; <br>
&gt; <br>
&gt; Signed-off-by: Tali Perry &lt;<a href="mailto:tali.perry1@gmail.com" target="_blank">tali.perry1@gmail.com</a>&gt;<br>
&gt; Reviewed-by: Rob Herring &lt;<a href="mailto:robh@kernel.org" target="_blank">robh@kernel.org</a>&gt;<br>
&gt; Signed-off-by: Wei Yongjun &lt;<a href="mailto:weiyongjun1@huawei.com" target="_blank">weiyongjun1@huawei.com</a>&gt;<br>
&gt; <br>
<br>
I don&#39;t know what&#39;s going on with this patch. Is it something new? Can<br>
you break it up into logical changes and submit them with proper commit<br>
text? The signoff chain is also odd. Can you follow<br>
Documentation/process/submitting-patches.rst?<br>
<br>
&gt; ---<br>
&gt;  drivers/clk/clk-npcm7xx.c | 99 +++++++++++++++++++++++++++++++++++------------<br>
&gt;  1 file changed, 75 insertions(+), 24 deletions(-)<br>
&gt; <br>
&gt; diff --git a/drivers/clk/clk-npcm7xx.c b/drivers/clk/clk-npcm7xx.c<br>
&gt; index 740af90a9508..91a937720f4e 100644<br>
&gt; --- a/drivers/clk/clk-npcm7xx.c<br>
&gt; +++ b/drivers/clk/clk-npcm7xx.c<br>
&gt; @@ -7,17 +7,26 @@<br>
&gt;   * Copyright (C) 2018 Nuvoton Technologies <a href="mailto:tali.perry@nuvoton.com" target="_blank">tali.perry@nuvoton.com</a><br>
&gt;   */<br>
&gt;  <br>
&gt; -#include &lt;linux/module.h&gt;<br>
&gt; -#include &lt;linux/clk-provider.h&gt;<br>
&gt; -#include &lt;linux/io.h&gt;<br>
&gt; -#include &lt;linux/kernel.h&gt;<br>
&gt; -#include &lt;linux/of.h&gt;<br>
&gt; -#include &lt;linux/of_address.h&gt;<br>
&gt; -#include &lt;linux/slab.h&gt;<br>
&gt; -#include &lt;linux/err.h&gt;<br>
&gt; -#include &lt;linux/bitfield.h&gt;<br>
&gt; -<br>
&gt; -#include &lt;dt-bindings/clock/nuvoton,npcm7xx-clock.h&gt;<br>
&gt; +<br>
&gt; +<br>
&gt; +<br>
&gt; + #include &lt;linux/module.h&gt;<br>
&gt; + #include &lt;linux/clk.h&gt;<br>
&gt; + #include &lt;linux/clk-provider.h&gt;<br>
&gt; + #include &lt;linux/device.h&gt;<br>
&gt; + #include &lt;linux/io.h&gt;<br>
&gt; + #include &lt;linux/kernel.h&gt;<br>
&gt; + #include &lt;linux/of.h&gt;<br>
&gt; + #include &lt;linux/of_device.h&gt;<br>
&gt; + #include &lt;linux/of_platform.h&gt;<br>
&gt; + #include &lt;linux/of_address.h&gt;<br>
&gt; + #include &lt;linux/platform_device.h&gt;<br>
&gt; + #include &lt;linux/slab.h&gt;<br>
&gt; + #include &lt;linux/err.h&gt;<br>
&gt; + #include &lt;linux/rational.h&gt;<br>
&gt; + #include &lt;linux/bitfield.h&gt;<br>
&gt; + #include &lt;dt-bindings/clock/nuvoton,npcm7xx-clock.h&gt;<br>
<br>
Is any of this hunk necessary or relevant to the subject of this patch?<br>
<br>
&gt; +<br>
&gt;  <br>
&gt;  struct npcm7xx_clk_pll {<br>
&gt; @@ -44,7 +56,8 @@ static unsigned long npcm7xx_clk_pll_recalc_rate(struct clk_hw *hw,<br>
&gt;         u64 ret;<br>
&gt;  <br>
&gt;         if (parent_rate == 0) {<br>
&gt; -               pr_err(&quot;%s: parent rate is zero&quot;, __func__);<br>
&gt; +               pr_err(&quot;%s: parent rate is zero. reg=%x\n&quot;, __func__,<br>
&gt; +                       (u32)(pll-&gt;pllcon));<br>
<br>
Maybe you should print clk name instead of register?<br></blockquote><div><br></div><div class="gmail_default" style="font-family:monospace,monospace">Tali: There are only 4 pllcon registers. I don&#39;t mind if it&#39;s the address and not the name.</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
&gt;                 return 0;<br>
&gt;         }<br>
&gt;  <br>
&gt; @@ -61,13 +74,12 @@ static unsigned long npcm7xx_clk_pll_recalc_rate(struct clk_hw *hw,<br>
&gt;         return ret;<br>
&gt;  }<br>
&gt;  <br>
&gt; -static const struct clk_ops npcm7xx_clk_pll_ops = {<br>
&gt; +const struct clk_ops npcm7xx_clk_pll_ops = {<br>
<br>
Why?<br></blockquote><div><br></div><div class="gmail_default" style="font-family:monospace,monospace">Tali: I will return the static.</div><div class="gmail_default" style="font-family:monospace,monospace"></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
&gt;         .recalc_rate = npcm7xx_clk_pll_recalc_rate,<br>
&gt;  };<br>
&gt;  <br>
&gt; -static struct clk_hw *<br>
&gt; -npcm7xx_clk_register_pll(void __iomem *pllcon, const char *name,<br>
&gt; -                        const char *parent_name, unsigned long flags)<br>
&gt; +static struct clk_hw *npcm7xx_clk_register_pll(void __iomem *pllcon,<br>
&gt; +               const char *name, const char *parent_name, unsigned long flags)<br>
&gt;  {<br>
&gt;         struct npcm7xx_clk_pll *pll;<br>
&gt;         struct clk_init_data init;<br>
&gt; @@ -78,7 +90,8 @@ npcm7xx_clk_register_pll(void __iomem *pllcon, const char *name,<br>
&gt;         if (!pll)<br>
&gt;                 return ERR_PTR(-ENOMEM);<br>
&gt;  <br>
&gt; -       pr_debug(&quot;%s reg, name=%s, p=%s\n&quot;, __func__, name, parent_name);<br>
&gt; +       pr_debug(&quot;%s reg, reg=0x%x, name=%s, p=%s\n&quot;,<br>
&gt; +               __func__, (unsigned int)pllcon, name, parent_name);<br>
<br>
What&#39;s going on here? Why cast?<br></blockquote><div><span class="gmail_default" style="font-family:monospace,monospace">Tali: I will remove this print all together.</span> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
&gt;  <br>
&gt;         <a href="http://init.name" rel="noreferrer" target="_blank">init.name</a> = name;<br>
&gt;         init.ops = &amp;npcm7xx_clk_pll_ops;<br>
&gt; @@ -544,9 +557,11 @@ static void __init npcm7xx_clk_init(struct device_node *clk_np)<br>
&gt;         void __iomem *clk_base;<br>
&gt;         struct resource res;<br>
&gt;         struct clk_hw *hw;<br>
&gt; +       struct clk *clk;<br>
&gt;         int ret;<br>
&gt;         int i;<br>
&gt;  <br>
&gt; +       clk_base = NULL;<br>
<br>
Why?<br></blockquote><div> </div><div><span class="gmail_default" style="font-family:monospace,monospace">Tali: to init it. If DT is badly defined the value will remain NULL.</span></div><div><span class="gmail_default" style="font-family:monospace,monospace"></span> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
&gt;         ret = of_address_to_resource(clk_np, 0, &amp;res);<br>
&gt;         if (ret) {<br>
&gt;                 pr_err(&quot;%s: failed to get resource, ret %d\n&quot;, clk_np-&gt;name,<br>
&gt; @@ -560,14 +575,44 @@ static void __init npcm7xx_clk_init(struct device_node *clk_np)<br>
&gt;  <br>
&gt;         npcm7xx_clk_data = kzalloc(sizeof(*npcm7xx_clk_data-&gt;hws) *<br>
&gt;                 NPCM7XX_NUM_CLOCKS + sizeof(npcm7xx_clk_data), GFP_KERNEL);<br>
&gt; -       if (!npcm7xx_clk_data)<br>
&gt; +<br>
&gt; +       npcm7xx_clk_data-&gt;num = 0;<br>
<br>
kzalloc already does that initialization to 0 for you.<br>
<br>
&gt; +<br>
&gt; +       if (!npcm7xx_clk_data-&gt;hws) {<br>
&gt; +               pr_err(&quot;Can&#39;t alloc npcm7xx_clk_data\n&quot;);<br>
<br>
We don&#39;t need allocation error messages.<br>
<br>
&gt;                 goto npcm7xx_init_np_err;<br>
&gt; +       }<br>
&gt;  <br>
&gt;         npcm7xx_clk_data-&gt;num = NPCM7XX_NUM_CLOCKS;<br>
&gt;  <br>
&gt;         for (i = 0; i &lt; NPCM7XX_NUM_CLOCKS; i++)<br>
&gt;                 npcm7xx_clk_data-&gt;hws[i] = ERR_PTR(-EPROBE_DEFER);<br>
&gt;  <br>
&gt; +       /* Read fixed clocks. These 3 clocks must be defined in DT */<br>
&gt; +       clk = of_clk_get_by_name(clk_np, NPCM7XX_CLK_S_REFCLK);<br>
&gt; +       if (IS_ERR(clk)) {<br>
&gt; +               pr_err(&quot;failed to find external REFCLK on device tree, err=%ld\n&quot;,<br>
&gt; +                       PTR_ERR(clk));<br>
&gt; +               clk_put(clk);<br>
&gt; +               goto npcm7xx_init_fail_no_clk_on_dt;<br>
&gt; +       }<br>
&gt; +<br>
&gt; +       clk = of_clk_get_by_name(clk_np, NPCM7XX_CLK_S_SYSBYPCK);<br>
&gt; +       if (IS_ERR(clk)) {<br>
&gt; +               pr_err(&quot;failed to find external SYSBYPCK on device tree, err=%ld\n&quot;,<br>
&gt; +                       PTR_ERR(clk));<br>
&gt; +               clk_put(clk);<br>
&gt; +               goto npcm7xx_init_fail_no_clk_on_dt;<br>
&gt; +       }<br>
&gt; +<br>
&gt; +       clk = of_clk_get_by_name(clk_np, NPCM7XX_CLK_S_MCBYPCK);<br>
&gt; +       if (IS_ERR(clk)) {<br>
&gt; +               pr_err(&quot;failed to find external MCBYPCK on device tree, err=%ld\n&quot;,<br>
&gt; +                       PTR_ERR(clk));<br>
&gt; +               clk_put(clk);<br>
&gt; +               goto npcm7xx_init_fail_no_clk_on_dt;<br>
&gt; +       }<br>
<br>
I assume the DTS is not shipped?<br></blockquote><div><br></div><div class="gmail_default" style="font-family:monospace,monospace">Tali: DTS for npcm is shipped in a separate patchset.</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
&gt; +<br>
&gt;         /* Register plls */<br>
&gt;         for (i = 0; i &lt; ARRAY_SIZE(npcm7xx_plls); i++) {<br>
&gt;                 const struct npcm7xx_clk_pll_data *pll_data = &amp;npcm7xx_plls[i];<br>
&gt; @@ -584,16 +629,16 @@ static void __init npcm7xx_clk_init(struct device_node *clk_np)<br>
&gt;         }<br>
&gt;  <br>
&gt;         /* Register fixed dividers */<br>
&gt; -       hw = clk_hw_register_fixed_factor(NULL, NPCM7XX_CLK_S_PLL1_DIV2,<br>
&gt; +       clk = clk_register_fixed_factor(NULL, NPCM7XX_CLK_S_PLL1_DIV2,<br>
<br>
This is going backwards. Please use clk_hw APIs.<br></blockquote><div><span class="gmail_default" style="font-family:monospace,monospace">Tali: Will fix.</span> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
&gt;                         NPCM7XX_CLK_S_PLL1, 0, 1, 2);<br>
&gt; -       if (IS_ERR(hw)) {<br>
&gt; +       if (IS_ERR(clk)) {<br>
&gt;                 pr_err(&quot;npcm7xx_clk: Can&#39;t register fixed div\n&quot;);<br>
&gt;                 goto npcm7xx_init_fail;<br>
&gt;         }<br>
&gt;  <br>
&gt; -       hw = clk_hw_register_fixed_factor(NULL, NPCM7XX_CLK_S_PLL2_DIV2,<br>
&gt; +       clk = clk_register_fixed_factor(NULL, NPCM7XX_CLK_S_PLL2_DIV2,<br>
&gt;                         NPCM7XX_CLK_S_PLL2, 0, 1, 2);<br>
&gt; -       if (IS_ERR(hw)) {<br>
&gt; +       if (IS_ERR(clk)) {<br>
&gt;                 pr_err(&quot;npcm7xx_clk: Can&#39;t register div2\n&quot;);<br>
&gt;                 goto npcm7xx_init_fail;<br>
&gt;         }<br>
&gt; @@ -646,11 +691,17 @@ static void __init npcm7xx_clk_init(struct device_node *clk_np)<br>
&gt;  <br>
&gt;         return;<br>
&gt;  <br>
&gt; +npcm7xx_init_fail_no_clk_on_dt:<br>
&gt; +       pr_err(&quot;see Documentation/devicetree/bindings/clock/&quot;);<br>
&gt; +       pr_err(&quot;nuvoton,npcm750-clk.txt  for details\n&quot;);<br>
&gt;  npcm7xx_init_fail:<br>
&gt; -       kfree(npcm7xx_clk_data-&gt;hws);<br>
&gt; +       if (npcm7xx_clk_data-&gt;num)<br>
&gt; +               kfree(npcm7xx_clk_data-&gt;hws);<br>
&gt;  npcm7xx_init_np_err:<br>
&gt; -       iounmap(clk_base);<br>
&gt; +       if (clk_base != NULL)<br>
&gt; +               iounmap(clk_base);<br>
&gt;  npcm7xx_init_error:<br>
&gt;         of_node_put(clk_np);<br>
&gt; +       pr_err(&quot;clk setup fail\n&quot;);<br>
<br>
Is this hunk of changes related to the subject of this patch? I don&#39;t<br>
think it is, so it just leads to more confusion.<br></blockquote><div><br></div><div class="gmail_default" style="font-family:monospace,monospace">Tali: I added a goto option for the case that the DTS doesn&#39;t have the reference clocks this module needs.</div><div class="gmail_default" style="font-family:monospace,monospace"><br></div><div class="gmail_default" style="font-family:monospace,monospace"></div></div></div>

Patch

diff --git a/drivers/clk/clk-npcm7xx.c b/drivers/clk/clk-npcm7xx.c
index 740af90a9508..91a937720f4e 100644
--- a/drivers/clk/clk-npcm7xx.c
+++ b/drivers/clk/clk-npcm7xx.c
@@ -7,17 +7,26 @@ 
  * Copyright (C) 2018 Nuvoton Technologies tali.perry@nuvoton.com
  */
 
-#include <linux/module.h>
-#include <linux/clk-provider.h>
-#include <linux/io.h>
-#include <linux/kernel.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/slab.h>
-#include <linux/err.h>
-#include <linux/bitfield.h>
-
-#include <dt-bindings/clock/nuvoton,npcm7xx-clock.h>
+
+
+
+ #include <linux/module.h>
+ #include <linux/clk.h>
+ #include <linux/clk-provider.h>
+ #include <linux/device.h>
+ #include <linux/io.h>
+ #include <linux/kernel.h>
+ #include <linux/of.h>
+ #include <linux/of_device.h>
+ #include <linux/of_platform.h>
+ #include <linux/of_address.h>
+ #include <linux/platform_device.h>
+ #include <linux/slab.h>
+ #include <linux/err.h>
+ #include <linux/rational.h>
+ #include <linux/bitfield.h>
+ #include <dt-bindings/clock/nuvoton,npcm7xx-clock.h>
+
 
 struct npcm7xx_clk_pll {
 	struct clk_hw	hw;
@@ -27,6 +36,9 @@  struct npcm7xx_clk_pll {
 
 #define to_npcm7xx_clk_pll(_hw) container_of(_hw, struct npcm7xx_clk_pll, hw)
 
+static struct clk_hw *npcm7xx_clk_register_pll(void __iomem *pllcon,
+	const char *name, const char *parent_name, unsigned long flags);
+
 #define PLLCON_LOKI	BIT(31)
 #define PLLCON_LOKS	BIT(30)
 #define PLLCON_FBDV	GENMASK(27, 16)
@@ -44,7 +56,8 @@  static unsigned long npcm7xx_clk_pll_recalc_rate(struct clk_hw *hw,
 	u64 ret;
 
 	if (parent_rate == 0) {
-		pr_err("%s: parent rate is zero", __func__);
+		pr_err("%s: parent rate is zero. reg=%x\n", __func__,
+			(u32)(pll->pllcon));
 		return 0;
 	}
 
@@ -61,13 +74,12 @@  static unsigned long npcm7xx_clk_pll_recalc_rate(struct clk_hw *hw,
 	return ret;
 }
 
-static const struct clk_ops npcm7xx_clk_pll_ops = {
+const struct clk_ops npcm7xx_clk_pll_ops = {
 	.recalc_rate = npcm7xx_clk_pll_recalc_rate,
 };
 
-static struct clk_hw *
-npcm7xx_clk_register_pll(void __iomem *pllcon, const char *name,
-			 const char *parent_name, unsigned long flags)
+static struct clk_hw *npcm7xx_clk_register_pll(void __iomem *pllcon,
+		const char *name, const char *parent_name, unsigned long flags)
 {
 	struct npcm7xx_clk_pll *pll;
 	struct clk_init_data init;
@@ -78,7 +90,8 @@  npcm7xx_clk_register_pll(void __iomem *pllcon, const char *name,
 	if (!pll)
 		return ERR_PTR(-ENOMEM);
 
-	pr_debug("%s reg, name=%s, p=%s\n", __func__, name, parent_name);
+	pr_debug("%s reg, reg=0x%x, name=%s, p=%s\n",
+		__func__, (unsigned int)pllcon, name, parent_name);
 
 	init.name = name;
 	init.ops = &npcm7xx_clk_pll_ops;
@@ -544,9 +557,11 @@  static void __init npcm7xx_clk_init(struct device_node *clk_np)
 	void __iomem *clk_base;
 	struct resource res;
 	struct clk_hw *hw;
+	struct clk *clk;
 	int ret;
 	int i;
 
+	clk_base = NULL;
 	ret = of_address_to_resource(clk_np, 0, &res);
 	if (ret) {
 		pr_err("%s: failed to get resource, ret %d\n", clk_np->name,
@@ -560,14 +575,44 @@  static void __init npcm7xx_clk_init(struct device_node *clk_np)
 
 	npcm7xx_clk_data = kzalloc(sizeof(*npcm7xx_clk_data->hws) *
 		NPCM7XX_NUM_CLOCKS + sizeof(npcm7xx_clk_data), GFP_KERNEL);
-	if (!npcm7xx_clk_data)
+
+	npcm7xx_clk_data->num = 0;
+
+	if (!npcm7xx_clk_data->hws) {
+		pr_err("Can't alloc npcm7xx_clk_data\n");
 		goto npcm7xx_init_np_err;
+	}
 
 	npcm7xx_clk_data->num = NPCM7XX_NUM_CLOCKS;
 
 	for (i = 0; i < NPCM7XX_NUM_CLOCKS; i++)
 		npcm7xx_clk_data->hws[i] = ERR_PTR(-EPROBE_DEFER);
 
+	/* Read fixed clocks. These 3 clocks must be defined in DT */
+	clk = of_clk_get_by_name(clk_np, NPCM7XX_CLK_S_REFCLK);
+	if (IS_ERR(clk)) {
+		pr_err("failed to find external REFCLK on device tree, err=%ld\n",
+			PTR_ERR(clk));
+		clk_put(clk);
+		goto npcm7xx_init_fail_no_clk_on_dt;
+	}
+
+	clk = of_clk_get_by_name(clk_np, NPCM7XX_CLK_S_SYSBYPCK);
+	if (IS_ERR(clk)) {
+		pr_err("failed to find external SYSBYPCK on device tree, err=%ld\n",
+			PTR_ERR(clk));
+		clk_put(clk);
+		goto npcm7xx_init_fail_no_clk_on_dt;
+	}
+
+	clk = of_clk_get_by_name(clk_np, NPCM7XX_CLK_S_MCBYPCK);
+	if (IS_ERR(clk)) {
+		pr_err("failed to find external MCBYPCK on device tree, err=%ld\n",
+			PTR_ERR(clk));
+		clk_put(clk);
+		goto npcm7xx_init_fail_no_clk_on_dt;
+	}
+
 	/* Register plls */
 	for (i = 0; i < ARRAY_SIZE(npcm7xx_plls); i++) {
 		const struct npcm7xx_clk_pll_data *pll_data = &npcm7xx_plls[i];
@@ -584,16 +629,16 @@  static void __init npcm7xx_clk_init(struct device_node *clk_np)
 	}
 
 	/* Register fixed dividers */
-	hw = clk_hw_register_fixed_factor(NULL, NPCM7XX_CLK_S_PLL1_DIV2,
+	clk = clk_register_fixed_factor(NULL, NPCM7XX_CLK_S_PLL1_DIV2,
 			NPCM7XX_CLK_S_PLL1, 0, 1, 2);
-	if (IS_ERR(hw)) {
+	if (IS_ERR(clk)) {
 		pr_err("npcm7xx_clk: Can't register fixed div\n");
 		goto npcm7xx_init_fail;
 	}
 
-	hw = clk_hw_register_fixed_factor(NULL, NPCM7XX_CLK_S_PLL2_DIV2,
+	clk = clk_register_fixed_factor(NULL, NPCM7XX_CLK_S_PLL2_DIV2,
 			NPCM7XX_CLK_S_PLL2, 0, 1, 2);
-	if (IS_ERR(hw)) {
+	if (IS_ERR(clk)) {
 		pr_err("npcm7xx_clk: Can't register div2\n");
 		goto npcm7xx_init_fail;
 	}
@@ -646,11 +691,17 @@  static void __init npcm7xx_clk_init(struct device_node *clk_np)
 
 	return;
 
+npcm7xx_init_fail_no_clk_on_dt:
+	pr_err("see Documentation/devicetree/bindings/clock/");
+	pr_err("nuvoton,npcm750-clk.txt  for details\n");
 npcm7xx_init_fail:
-	kfree(npcm7xx_clk_data->hws);
+	if (npcm7xx_clk_data->num)
+		kfree(npcm7xx_clk_data->hws);
 npcm7xx_init_np_err:
-	iounmap(clk_base);
+	if (clk_base != NULL)
+		iounmap(clk_base);
 npcm7xx_init_error:
 	of_node_put(clk_np);
+	pr_err("clk setup fail\n");
 }
 CLK_OF_DECLARE(npcm7xx_clk_init, "nuvoton,npcm750-clk", npcm7xx_clk_init);