Re: [PATCH 07/14] clock: milbeaut: Add Milbeaut M10V clock control
Hi On 2018/12/28 9:39, Stephen Boyd wrote: Quoting Sugaya, Taichi (2018-12-25 17:35:27) Hi On 2018/11/30 17:31, Stephen Boyd wrote: + init.num_parents = parents; + init.parent_names = parent_names; + + mcm->cname = clk_name; + mcm->parent = 0; + mcm->hw.init = + + clk = clk_register(NULL, >hw); + if (IS_ERR(clk)) + goto err_clk; + + of_clk_add_provider(node, of_clk_src_simple_get, clk); + return; + +err_clk: + kfree(mcm); +err_mcm: + kfree(parent_names); +} +CLK_OF_DECLARE(m10v_clk_mux, "socionext,milbeaut-m10v-clk-mux", + m10v_clk_mux_setup); Any chance you can use a platform driver? Excuse me to re-ask you. Why do you recommend to use a platform driver? Is that current fad? Not exactly a fad. We've been doing it for some time now. From an older email on the list: Reasons (in no particular order): 1. We get a dev pointer to use with clk_hw_register() 2. We can handle probe defer if some resource is not available 3. Using device model gets us a hook into power management frameworks like runtime PM and system PM for things like suspend and hibernate 4. It encourages a single DT node clk controller style binding instead of a single node per clk style binding 5. We can use non-DT specific functions like devm_ioremap_resource() to map registers and acquire other resources, leading to more portable and generic code 6. We may be able to make the device driver a module, which will make distros happy if we don't have to compile in all these clk drivers to the resulting vmlinux Great thanks for answering. I strongly understand. #It takes a bit of time to send v2. Best Regards, Sugaya Taichi
Re: [PATCH 07/14] clock: milbeaut: Add Milbeaut M10V clock control
Quoting Sugaya, Taichi (2018-12-25 17:35:27) > Hi > > On 2018/11/30 17:31, Stephen Boyd wrote: > >> + init.num_parents = parents; > >> + init.parent_names = parent_names; > >> + > >> + mcm->cname = clk_name; > >> + mcm->parent = 0; > >> + mcm->hw.init = > >> + > >> + clk = clk_register(NULL, >hw); > >> + if (IS_ERR(clk)) > >> + goto err_clk; > >> + > >> + of_clk_add_provider(node, of_clk_src_simple_get, clk); > >> + return; > >> + > >> +err_clk: > >> + kfree(mcm); > >> +err_mcm: > >> + kfree(parent_names); > >> +} > >> +CLK_OF_DECLARE(m10v_clk_mux, "socionext,milbeaut-m10v-clk-mux", > >> + m10v_clk_mux_setup); > > > > Any chance you can use a platform driver? > > > > Excuse me to re-ask you. > Why do you recommend to use a platform driver? Is that current fad? Not exactly a fad. We've been doing it for some time now. From an older email on the list: Reasons (in no particular order): 1. We get a dev pointer to use with clk_hw_register() 2. We can handle probe defer if some resource is not available 3. Using device model gets us a hook into power management frameworks like runtime PM and system PM for things like suspend and hibernate 4. It encourages a single DT node clk controller style binding instead of a single node per clk style binding 5. We can use non-DT specific functions like devm_ioremap_resource() to map registers and acquire other resources, leading to more portable and generic code 6. We may be able to make the device driver a module, which will make distros happy if we don't have to compile in all these clk drivers to the resulting vmlinux
Re: [PATCH 07/14] clock: milbeaut: Add Milbeaut M10V clock control
Hi On 2018/11/30 17:31, Stephen Boyd wrote: + init.num_parents = parents; + init.parent_names = parent_names; + + mcm->cname = clk_name; + mcm->parent = 0; + mcm->hw.init = + + clk = clk_register(NULL, >hw); + if (IS_ERR(clk)) + goto err_clk; + + of_clk_add_provider(node, of_clk_src_simple_get, clk); + return; + +err_clk: + kfree(mcm); +err_mcm: + kfree(parent_names); +} +CLK_OF_DECLARE(m10v_clk_mux, "socionext,milbeaut-m10v-clk-mux", + m10v_clk_mux_setup); Any chance you can use a platform driver? Excuse me to re-ask you. Why do you recommend to use a platform driver? Is that current fad? Thanks Sugaya Taichi
Re: [PATCH 07/14] clock: milbeaut: Add Milbeaut M10V clock control
Hi On 2018/12/05 3:15, Stephen Boyd wrote: Quoting Sugaya, Taichi (2018-12-04 00:26:16) On 2018/11/30 17:31, Stephen Boyd wrote: Quoting Sugaya Taichi (2018-11-18 17:01:12) +void __init m10v_clk_mux_setup(struct device_node *node) +{ + const char *clk_name = node->name; + struct clk_init_data init; + const char **parent_names; + struct m10v_mux *mcm; + struct clk *clk; + int i, parents; + + if (!m10v_clk_iomap()) + return; + + of_property_read_string(node, "clock-output-names", _name); + + parents = of_clk_get_parent_count(node); + if (parents < 2) { + pr_err("%s: not a mux\n", clk_name); How is this possible? When the node has more than 1 clks... Or I am misunderstanding your question? This looks like code that's checking DT for correctness. We don't typically do that in the kernel because the kernel isn't a DT validator. That's all I'm saying. I think this comment is not useful if the driver design is done to specify parent linkages in C code instead of DT, so don't worry about this too much. I understand. Thank you for additional information. Sugaya Taichi
Re: [PATCH 07/14] clock: milbeaut: Add Milbeaut M10V clock control
Hi On 2018/12/05 3:15, Stephen Boyd wrote: Quoting Sugaya, Taichi (2018-12-04 00:26:16) On 2018/11/30 17:31, Stephen Boyd wrote: Quoting Sugaya Taichi (2018-11-18 17:01:12) +void __init m10v_clk_mux_setup(struct device_node *node) +{ + const char *clk_name = node->name; + struct clk_init_data init; + const char **parent_names; + struct m10v_mux *mcm; + struct clk *clk; + int i, parents; + + if (!m10v_clk_iomap()) + return; + + of_property_read_string(node, "clock-output-names", _name); + + parents = of_clk_get_parent_count(node); + if (parents < 2) { + pr_err("%s: not a mux\n", clk_name); How is this possible? When the node has more than 1 clks... Or I am misunderstanding your question? This looks like code that's checking DT for correctness. We don't typically do that in the kernel because the kernel isn't a DT validator. That's all I'm saying. I think this comment is not useful if the driver design is done to specify parent linkages in C code instead of DT, so don't worry about this too much. I understand. Thank you for additional information. Sugaya Taichi
Re: [PATCH 07/14] clock: milbeaut: Add Milbeaut M10V clock control
Quoting Masahiro Yamada (2018-12-04 20:26:06) > On Wed, Dec 5, 2018 at 3:14 AM Stephen Boyd wrote: > > > > Quoting Masahiro Yamada (2018-12-04 03:03:53) > > > Hi Stephen, > > > > > > > > > On Fri, Nov 30, 2018 at 5:31 PM Stephen Boyd wrote: > > > > > > > > Quoting Sugaya Taichi (2018-11-18 17:01:12) > > > > > Add Milbeaut M10V clock ( including PLL ) control. > > > > > > > > Please give some more details here. > > > > > > > > > > > > > > Signed-off-by: Sugaya Taichi > > > > > --- > > > > > drivers/clk/Makefile | 1 + > > > > > drivers/clk/clk-m10v.c | 671 > > > > > + > > > > > > > > And this is different from Uniphier? Maybe we need a socionext > > > > directory under drivers/clk/. > > > > > > > > > > > > This is always a difficult question, > > > and I do not have a strong opinion. > > > > > > > > > I am fine with moving the files to drivers/clk/socionext > > > although no file would be shared. > > > > > > > > > FYI > > > > > > UniPhier and Milbeaut are completely different platforms > > > developed/maintained by different teams. > > > > > > They happen to live in the same company now > > > just because Socionext merged the LSI business from Panasonic and Fujitsu. > > > > > > UniPhier originates in Panasonic, while Milbeaut in Fujitsu. > > > > > > > Thanks for the background info. I'd prefer to defer to however the dts > > files are getting split up into directories. If they're all put under > > arch/arm64/boot/dts/socionext/ then I would say combine the two clk > > drivers into a socionext directory. Otherwise, keep them split out. > > > If you want to align with the DT directory structure, > the answer is clear. > > > Milbeaut DT files will be put together with UniPhier ones > into socionext directory. > > > For arm64, DT directories are already sorted out by vendors. > > Even 32-bit ARM is going to that way. > > Rob Herring just posted a python script > to move all DT files in arch/arm/boot/dts/ > into vendor subdirectories. > > > Please let me know if you want me to > move drivers/clk/uniphier/* to drivers/clk/socionext/*. > Maybe the dts needs to be split up instead? Looks like the gpio drivers are in a uniphier directory and there is some precedence to keep the "taken over" company name when vendors are merged into other vendors. Maybe that's how things have happened here? It would be nice to be consistent, but I leave the decision up to you to figure out if that really matters to you. I'll be fine either way.
Re: [PATCH 07/14] clock: milbeaut: Add Milbeaut M10V clock control
Quoting Masahiro Yamada (2018-12-04 20:26:06) > On Wed, Dec 5, 2018 at 3:14 AM Stephen Boyd wrote: > > > > Quoting Masahiro Yamada (2018-12-04 03:03:53) > > > Hi Stephen, > > > > > > > > > On Fri, Nov 30, 2018 at 5:31 PM Stephen Boyd wrote: > > > > > > > > Quoting Sugaya Taichi (2018-11-18 17:01:12) > > > > > Add Milbeaut M10V clock ( including PLL ) control. > > > > > > > > Please give some more details here. > > > > > > > > > > > > > > Signed-off-by: Sugaya Taichi > > > > > --- > > > > > drivers/clk/Makefile | 1 + > > > > > drivers/clk/clk-m10v.c | 671 > > > > > + > > > > > > > > And this is different from Uniphier? Maybe we need a socionext > > > > directory under drivers/clk/. > > > > > > > > > > > > This is always a difficult question, > > > and I do not have a strong opinion. > > > > > > > > > I am fine with moving the files to drivers/clk/socionext > > > although no file would be shared. > > > > > > > > > FYI > > > > > > UniPhier and Milbeaut are completely different platforms > > > developed/maintained by different teams. > > > > > > They happen to live in the same company now > > > just because Socionext merged the LSI business from Panasonic and Fujitsu. > > > > > > UniPhier originates in Panasonic, while Milbeaut in Fujitsu. > > > > > > > Thanks for the background info. I'd prefer to defer to however the dts > > files are getting split up into directories. If they're all put under > > arch/arm64/boot/dts/socionext/ then I would say combine the two clk > > drivers into a socionext directory. Otherwise, keep them split out. > > > If you want to align with the DT directory structure, > the answer is clear. > > > Milbeaut DT files will be put together with UniPhier ones > into socionext directory. > > > For arm64, DT directories are already sorted out by vendors. > > Even 32-bit ARM is going to that way. > > Rob Herring just posted a python script > to move all DT files in arch/arm/boot/dts/ > into vendor subdirectories. > > > Please let me know if you want me to > move drivers/clk/uniphier/* to drivers/clk/socionext/*. > Maybe the dts needs to be split up instead? Looks like the gpio drivers are in a uniphier directory and there is some precedence to keep the "taken over" company name when vendors are merged into other vendors. Maybe that's how things have happened here? It would be nice to be consistent, but I leave the decision up to you to figure out if that really matters to you. I'll be fine either way.
Re: [PATCH 07/14] clock: milbeaut: Add Milbeaut M10V clock control
On Wed, Dec 5, 2018 at 3:14 AM Stephen Boyd wrote: > > Quoting Masahiro Yamada (2018-12-04 03:03:53) > > Hi Stephen, > > > > > > On Fri, Nov 30, 2018 at 5:31 PM Stephen Boyd wrote: > > > > > > Quoting Sugaya Taichi (2018-11-18 17:01:12) > > > > Add Milbeaut M10V clock ( including PLL ) control. > > > > > > Please give some more details here. > > > > > > > > > > > Signed-off-by: Sugaya Taichi > > > > --- > > > > drivers/clk/Makefile | 1 + > > > > drivers/clk/clk-m10v.c | 671 > > > > + > > > > > > And this is different from Uniphier? Maybe we need a socionext > > > directory under drivers/clk/. > > > > > > > > This is always a difficult question, > > and I do not have a strong opinion. > > > > > > I am fine with moving the files to drivers/clk/socionext > > although no file would be shared. > > > > > > FYI > > > > UniPhier and Milbeaut are completely different platforms > > developed/maintained by different teams. > > > > They happen to live in the same company now > > just because Socionext merged the LSI business from Panasonic and Fujitsu. > > > > UniPhier originates in Panasonic, while Milbeaut in Fujitsu. > > > > Thanks for the background info. I'd prefer to defer to however the dts > files are getting split up into directories. If they're all put under > arch/arm64/boot/dts/socionext/ then I would say combine the two clk > drivers into a socionext directory. Otherwise, keep them split out. If you want to align with the DT directory structure, the answer is clear. Milbeaut DT files will be put together with UniPhier ones into socionext directory. For arm64, DT directories are already sorted out by vendors. Even 32-bit ARM is going to that way. Rob Herring just posted a python script to move all DT files in arch/arm/boot/dts/ into vendor subdirectories. Please let me know if you want me to move drivers/clk/uniphier/* to drivers/clk/socionext/*. -- Best Regards Masahiro Yamada
Re: [PATCH 07/14] clock: milbeaut: Add Milbeaut M10V clock control
On Wed, Dec 5, 2018 at 3:14 AM Stephen Boyd wrote: > > Quoting Masahiro Yamada (2018-12-04 03:03:53) > > Hi Stephen, > > > > > > On Fri, Nov 30, 2018 at 5:31 PM Stephen Boyd wrote: > > > > > > Quoting Sugaya Taichi (2018-11-18 17:01:12) > > > > Add Milbeaut M10V clock ( including PLL ) control. > > > > > > Please give some more details here. > > > > > > > > > > > Signed-off-by: Sugaya Taichi > > > > --- > > > > drivers/clk/Makefile | 1 + > > > > drivers/clk/clk-m10v.c | 671 > > > > + > > > > > > And this is different from Uniphier? Maybe we need a socionext > > > directory under drivers/clk/. > > > > > > > > This is always a difficult question, > > and I do not have a strong opinion. > > > > > > I am fine with moving the files to drivers/clk/socionext > > although no file would be shared. > > > > > > FYI > > > > UniPhier and Milbeaut are completely different platforms > > developed/maintained by different teams. > > > > They happen to live in the same company now > > just because Socionext merged the LSI business from Panasonic and Fujitsu. > > > > UniPhier originates in Panasonic, while Milbeaut in Fujitsu. > > > > Thanks for the background info. I'd prefer to defer to however the dts > files are getting split up into directories. If they're all put under > arch/arm64/boot/dts/socionext/ then I would say combine the two clk > drivers into a socionext directory. Otherwise, keep them split out. If you want to align with the DT directory structure, the answer is clear. Milbeaut DT files will be put together with UniPhier ones into socionext directory. For arm64, DT directories are already sorted out by vendors. Even 32-bit ARM is going to that way. Rob Herring just posted a python script to move all DT files in arch/arm/boot/dts/ into vendor subdirectories. Please let me know if you want me to move drivers/clk/uniphier/* to drivers/clk/socionext/*. -- Best Regards Masahiro Yamada
Re: [PATCH 07/14] clock: milbeaut: Add Milbeaut M10V clock control
Quoting Sugaya, Taichi (2018-12-04 00:26:16) > On 2018/11/30 17:31, Stephen Boyd wrote: > > Quoting Sugaya Taichi (2018-11-18 17:01:12) > >> +void __init m10v_clk_mux_setup(struct device_node *node) > >> +{ > >> + const char *clk_name = node->name; > >> + struct clk_init_data init; > >> + const char **parent_names; > >> + struct m10v_mux *mcm; > >> + struct clk *clk; > >> + int i, parents; > >> + > >> + if (!m10v_clk_iomap()) > >> + return; > >> + > >> + of_property_read_string(node, "clock-output-names", _name); > >> + > >> + parents = of_clk_get_parent_count(node); > >> + if (parents < 2) { > >> + pr_err("%s: not a mux\n", clk_name); > > > > How is this possible? > > When the node has more than 1 clks... > Or I am misunderstanding your question? This looks like code that's checking DT for correctness. We don't typically do that in the kernel because the kernel isn't a DT validator. That's all I'm saying. I think this comment is not useful if the driver design is done to specify parent linkages in C code instead of DT, so don't worry about this too much.
Re: [PATCH 07/14] clock: milbeaut: Add Milbeaut M10V clock control
Quoting Sugaya, Taichi (2018-12-04 00:26:16) > On 2018/11/30 17:31, Stephen Boyd wrote: > > Quoting Sugaya Taichi (2018-11-18 17:01:12) > >> +void __init m10v_clk_mux_setup(struct device_node *node) > >> +{ > >> + const char *clk_name = node->name; > >> + struct clk_init_data init; > >> + const char **parent_names; > >> + struct m10v_mux *mcm; > >> + struct clk *clk; > >> + int i, parents; > >> + > >> + if (!m10v_clk_iomap()) > >> + return; > >> + > >> + of_property_read_string(node, "clock-output-names", _name); > >> + > >> + parents = of_clk_get_parent_count(node); > >> + if (parents < 2) { > >> + pr_err("%s: not a mux\n", clk_name); > > > > How is this possible? > > When the node has more than 1 clks... > Or I am misunderstanding your question? This looks like code that's checking DT for correctness. We don't typically do that in the kernel because the kernel isn't a DT validator. That's all I'm saying. I think this comment is not useful if the driver design is done to specify parent linkages in C code instead of DT, so don't worry about this too much.
Re: [PATCH 07/14] clock: milbeaut: Add Milbeaut M10V clock control
Quoting Masahiro Yamada (2018-12-04 03:03:53) > Hi Stephen, > > > On Fri, Nov 30, 2018 at 5:31 PM Stephen Boyd wrote: > > > > Quoting Sugaya Taichi (2018-11-18 17:01:12) > > > Add Milbeaut M10V clock ( including PLL ) control. > > > > Please give some more details here. > > > > > > > > Signed-off-by: Sugaya Taichi > > > --- > > > drivers/clk/Makefile | 1 + > > > drivers/clk/clk-m10v.c | 671 > > > + > > > > And this is different from Uniphier? Maybe we need a socionext > > directory under drivers/clk/. > > > > This is always a difficult question, > and I do not have a strong opinion. > > > I am fine with moving the files to drivers/clk/socionext > although no file would be shared. > > > FYI > > UniPhier and Milbeaut are completely different platforms > developed/maintained by different teams. > > They happen to live in the same company now > just because Socionext merged the LSI business from Panasonic and Fujitsu. > > UniPhier originates in Panasonic, while Milbeaut in Fujitsu. > Thanks for the background info. I'd prefer to defer to however the dts files are getting split up into directories. If they're all put under arch/arm64/boot/dts/socionext/ then I would say combine the two clk drivers into a socionext directory. Otherwise, keep them split out.
Re: [PATCH 07/14] clock: milbeaut: Add Milbeaut M10V clock control
Quoting Masahiro Yamada (2018-12-04 03:03:53) > Hi Stephen, > > > On Fri, Nov 30, 2018 at 5:31 PM Stephen Boyd wrote: > > > > Quoting Sugaya Taichi (2018-11-18 17:01:12) > > > Add Milbeaut M10V clock ( including PLL ) control. > > > > Please give some more details here. > > > > > > > > Signed-off-by: Sugaya Taichi > > > --- > > > drivers/clk/Makefile | 1 + > > > drivers/clk/clk-m10v.c | 671 > > > + > > > > And this is different from Uniphier? Maybe we need a socionext > > directory under drivers/clk/. > > > > This is always a difficult question, > and I do not have a strong opinion. > > > I am fine with moving the files to drivers/clk/socionext > although no file would be shared. > > > FYI > > UniPhier and Milbeaut are completely different platforms > developed/maintained by different teams. > > They happen to live in the same company now > just because Socionext merged the LSI business from Panasonic and Fujitsu. > > UniPhier originates in Panasonic, while Milbeaut in Fujitsu. > Thanks for the background info. I'd prefer to defer to however the dts files are getting split up into directories. If they're all put under arch/arm64/boot/dts/socionext/ then I would say combine the two clk drivers into a socionext directory. Otherwise, keep them split out.
Re: [PATCH 07/14] clock: milbeaut: Add Milbeaut M10V clock control
Hi Stephen, On Fri, Nov 30, 2018 at 5:31 PM Stephen Boyd wrote: > > Quoting Sugaya Taichi (2018-11-18 17:01:12) > > Add Milbeaut M10V clock ( including PLL ) control. > > Please give some more details here. > > > > > Signed-off-by: Sugaya Taichi > > --- > > drivers/clk/Makefile | 1 + > > drivers/clk/clk-m10v.c | 671 > > + > > And this is different from Uniphier? Maybe we need a socionext > directory under drivers/clk/. This is always a difficult question, and I do not have a strong opinion. I am fine with moving the files to drivers/clk/socionext although no file would be shared. FYI UniPhier and Milbeaut are completely different platforms developed/maintained by different teams. They happen to live in the same company now just because Socionext merged the LSI business from Panasonic and Fujitsu. UniPhier originates in Panasonic, while Milbeaut in Fujitsu. Thanks. -- Best Regards Masahiro Yamada
Re: [PATCH 07/14] clock: milbeaut: Add Milbeaut M10V clock control
Hi Stephen, On Fri, Nov 30, 2018 at 5:31 PM Stephen Boyd wrote: > > Quoting Sugaya Taichi (2018-11-18 17:01:12) > > Add Milbeaut M10V clock ( including PLL ) control. > > Please give some more details here. > > > > > Signed-off-by: Sugaya Taichi > > --- > > drivers/clk/Makefile | 1 + > > drivers/clk/clk-m10v.c | 671 > > + > > And this is different from Uniphier? Maybe we need a socionext > directory under drivers/clk/. This is always a difficult question, and I do not have a strong opinion. I am fine with moving the files to drivers/clk/socionext although no file would be shared. FYI UniPhier and Milbeaut are completely different platforms developed/maintained by different teams. They happen to live in the same company now just because Socionext merged the LSI business from Panasonic and Fujitsu. UniPhier originates in Panasonic, while Milbeaut in Fujitsu. Thanks. -- Best Regards Masahiro Yamada
Re: [PATCH 07/14] clock: milbeaut: Add Milbeaut M10V clock control
Hi, Thank you for your comments. On 2018/11/30 17:31, Stephen Boyd wrote: Quoting Sugaya Taichi (2018-11-18 17:01:12) Add Milbeaut M10V clock ( including PLL ) control. Please give some more details here. OK, add more description. Signed-off-by: Sugaya Taichi --- drivers/clk/Makefile | 1 + drivers/clk/clk-m10v.c | 671 + And this is different from Uniphier? Maybe we need a socionext directory under drivers/clk/. Yes, M10V is a one of the Milbeaut series ( not Uniphier ). Anyway, I will talk to Uniphier team about creating a socionext directory. 2 files changed, 672 insertions(+) create mode 100644 drivers/clk/clk-m10v.c diff --git a/drivers/clk/clk-m10v.c b/drivers/clk/clk-m10v.c new file mode 100644 index 000..aa92a69 --- /dev/null +++ b/drivers/clk/clk-m10v.c @@ -0,0 +1,671 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2018 Socionext Inc. + * Copyright (C) 2016 Linaro Ltd. + * + */ + +#include +#include Is this include used? I will check and drop if they are not used. +#include +#include +#include +#include +#include +#include + +#define CLKSEL10x0 +#define CLKSEL(n) (((n) - 1) * 4 + CLKSEL1) + +#define PLLCNT10x30 +#define PLLCNT(n) (((n) - 1) * 4 + PLLCNT1) + +#define CLKSTOP1 0x54 +#define CLKSTOP(n) (((n) - 1) * 4 + CLKSTOP1) + +#define CRSWR 0x8c +#define CRRRS 0x90 +#define CRRSM 0x94 + +#define to_m10v_mux(_hw) container_of(_hw, struct m10v_mux, hw) +#define to_m10v_gate(_hw) container_of(_hw, struct m10v_gate, hw) +#define to_m10v_div(_hw) container_of(_hw, struct m10v_div, hw) +#define to_m10v_pll(_hw) container_of(_hw, struct m10v_pll, hw) + +static void __iomem *clk_base; +static struct device_node *np_top; +static DEFINE_SPINLOCK(crglock); Please make more specific names for these global variables by prefixing with m10v_. Also consider getting rid of the iomem and np_top globals entirely and associate those with clks differently. I got it. + +static __init void __iomem *m10v_clk_iomap(void) +{ + if (clk_base) + return clk_base; + + np_top = of_find_compatible_node(NULL, NULL, + "socionext,milbeaut-m10v-clk-regs"); + if (!np_top) { + pr_err("%s: CLK iomap failed!\n", __func__); We haven't iomapped yet though. Yes. + return NULL; + } + + clk_base = of_iomap(np_top, 0); + of_node_put(np_top); Would be nicer to use platform_device APIs instead of OF ones. OK, use platform_device APIs. + + return clk_base; +} + +struct m10v_mux { + struct clk_hw hw; + const char *cname; + u32 parent; +}; + +static u8 m10v_mux_get_parent(struct clk_hw *hw) +{ + struct m10v_mux *mcm = to_m10v_mux(hw); + struct clk_hw *parent; + int i; + + i = clk_hw_get_num_parents(hw); + while (i--) { + parent = clk_hw_get_parent_by_index(hw, i); + if (clk_hw_get_rate(parent)) + break; + } + + if (i < 0) { + pr_info("%s:%s no parent?!\n", + __func__, mcm->cname); + i = 0; + } + + return i; +} + +static int m10v_mux_set_parent(struct clk_hw *hw, u8 index) +{ + struct m10v_mux *mcm = to_m10v_mux(hw); + + mcm->parent = index; + return 0; +} + +static const struct clk_ops m10v_mux_ops = { + .get_parent = m10v_mux_get_parent, + .set_parent = m10v_mux_set_parent, + .determine_rate = __clk_mux_determine_rate, +}; + +void __init m10v_clk_mux_setup(struct device_node *node) +{ + const char *clk_name = node->name; + struct clk_init_data init; + const char **parent_names; + struct m10v_mux *mcm; + struct clk *clk; + int i, parents; + + if (!m10v_clk_iomap()) + return; + + of_property_read_string(node, "clock-output-names", _name); + + parents = of_clk_get_parent_count(node); + if (parents < 2) { + pr_err("%s: not a mux\n", clk_name); How is this possible? When the node has more than 1 clks... Or I am misunderstanding your question? + return; + } + + parent_names = kzalloc((sizeof(char *) * parents), GFP_KERNEL); + if (!parent_names) + return; + + for (i = 0; i < parents; i++) + parent_names[i] = of_clk_get_parent_name(node, i); This is of_clk_parent_fill(). OK, use it instead. + + mcm = kzalloc(sizeof(*mcm), GFP_KERNEL); + if (!mcm) + goto err_mcm; + + init.name = clk_name; + init.ops = _mux_ops; + init.flags = CLK_IS_BASIC | CLK_SET_RATE_PARENT; Please don't use CLK_IS_BASIC unless you need it. OK, confirm it. + init.num_parents = parents; + init.parent_names =
Re: [PATCH 07/14] clock: milbeaut: Add Milbeaut M10V clock control
Hi, Thank you for your comments. On 2018/11/30 17:31, Stephen Boyd wrote: Quoting Sugaya Taichi (2018-11-18 17:01:12) Add Milbeaut M10V clock ( including PLL ) control. Please give some more details here. OK, add more description. Signed-off-by: Sugaya Taichi --- drivers/clk/Makefile | 1 + drivers/clk/clk-m10v.c | 671 + And this is different from Uniphier? Maybe we need a socionext directory under drivers/clk/. Yes, M10V is a one of the Milbeaut series ( not Uniphier ). Anyway, I will talk to Uniphier team about creating a socionext directory. 2 files changed, 672 insertions(+) create mode 100644 drivers/clk/clk-m10v.c diff --git a/drivers/clk/clk-m10v.c b/drivers/clk/clk-m10v.c new file mode 100644 index 000..aa92a69 --- /dev/null +++ b/drivers/clk/clk-m10v.c @@ -0,0 +1,671 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2018 Socionext Inc. + * Copyright (C) 2016 Linaro Ltd. + * + */ + +#include +#include Is this include used? I will check and drop if they are not used. +#include +#include +#include +#include +#include +#include + +#define CLKSEL10x0 +#define CLKSEL(n) (((n) - 1) * 4 + CLKSEL1) + +#define PLLCNT10x30 +#define PLLCNT(n) (((n) - 1) * 4 + PLLCNT1) + +#define CLKSTOP1 0x54 +#define CLKSTOP(n) (((n) - 1) * 4 + CLKSTOP1) + +#define CRSWR 0x8c +#define CRRRS 0x90 +#define CRRSM 0x94 + +#define to_m10v_mux(_hw) container_of(_hw, struct m10v_mux, hw) +#define to_m10v_gate(_hw) container_of(_hw, struct m10v_gate, hw) +#define to_m10v_div(_hw) container_of(_hw, struct m10v_div, hw) +#define to_m10v_pll(_hw) container_of(_hw, struct m10v_pll, hw) + +static void __iomem *clk_base; +static struct device_node *np_top; +static DEFINE_SPINLOCK(crglock); Please make more specific names for these global variables by prefixing with m10v_. Also consider getting rid of the iomem and np_top globals entirely and associate those with clks differently. I got it. + +static __init void __iomem *m10v_clk_iomap(void) +{ + if (clk_base) + return clk_base; + + np_top = of_find_compatible_node(NULL, NULL, + "socionext,milbeaut-m10v-clk-regs"); + if (!np_top) { + pr_err("%s: CLK iomap failed!\n", __func__); We haven't iomapped yet though. Yes. + return NULL; + } + + clk_base = of_iomap(np_top, 0); + of_node_put(np_top); Would be nicer to use platform_device APIs instead of OF ones. OK, use platform_device APIs. + + return clk_base; +} + +struct m10v_mux { + struct clk_hw hw; + const char *cname; + u32 parent; +}; + +static u8 m10v_mux_get_parent(struct clk_hw *hw) +{ + struct m10v_mux *mcm = to_m10v_mux(hw); + struct clk_hw *parent; + int i; + + i = clk_hw_get_num_parents(hw); + while (i--) { + parent = clk_hw_get_parent_by_index(hw, i); + if (clk_hw_get_rate(parent)) + break; + } + + if (i < 0) { + pr_info("%s:%s no parent?!\n", + __func__, mcm->cname); + i = 0; + } + + return i; +} + +static int m10v_mux_set_parent(struct clk_hw *hw, u8 index) +{ + struct m10v_mux *mcm = to_m10v_mux(hw); + + mcm->parent = index; + return 0; +} + +static const struct clk_ops m10v_mux_ops = { + .get_parent = m10v_mux_get_parent, + .set_parent = m10v_mux_set_parent, + .determine_rate = __clk_mux_determine_rate, +}; + +void __init m10v_clk_mux_setup(struct device_node *node) +{ + const char *clk_name = node->name; + struct clk_init_data init; + const char **parent_names; + struct m10v_mux *mcm; + struct clk *clk; + int i, parents; + + if (!m10v_clk_iomap()) + return; + + of_property_read_string(node, "clock-output-names", _name); + + parents = of_clk_get_parent_count(node); + if (parents < 2) { + pr_err("%s: not a mux\n", clk_name); How is this possible? When the node has more than 1 clks... Or I am misunderstanding your question? + return; + } + + parent_names = kzalloc((sizeof(char *) * parents), GFP_KERNEL); + if (!parent_names) + return; + + for (i = 0; i < parents; i++) + parent_names[i] = of_clk_get_parent_name(node, i); This is of_clk_parent_fill(). OK, use it instead. + + mcm = kzalloc(sizeof(*mcm), GFP_KERNEL); + if (!mcm) + goto err_mcm; + + init.name = clk_name; + init.ops = _mux_ops; + init.flags = CLK_IS_BASIC | CLK_SET_RATE_PARENT; Please don't use CLK_IS_BASIC unless you need it. OK, confirm it. + init.num_parents = parents; + init.parent_names =
Re: [PATCH 07/14] clock: milbeaut: Add Milbeaut M10V clock control
Quoting Sugaya Taichi (2018-11-18 17:01:12) > Add Milbeaut M10V clock ( including PLL ) control. Please give some more details here. > > Signed-off-by: Sugaya Taichi > --- > drivers/clk/Makefile | 1 + > drivers/clk/clk-m10v.c | 671 > + And this is different from Uniphier? Maybe we need a socionext directory under drivers/clk/. > 2 files changed, 672 insertions(+) > create mode 100644 drivers/clk/clk-m10v.c > > diff --git a/drivers/clk/clk-m10v.c b/drivers/clk/clk-m10v.c > new file mode 100644 > index 000..aa92a69 > --- /dev/null > +++ b/drivers/clk/clk-m10v.c > @@ -0,0 +1,671 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Copyright (C) 2018 Socionext Inc. > + * Copyright (C) 2016 Linaro Ltd. > + * > + */ > + > +#include > +#include Is this include used? > +#include > +#include > +#include > +#include > +#include > +#include > + > +#define CLKSEL10x0 > +#define CLKSEL(n) (((n) - 1) * 4 + CLKSEL1) > + > +#define PLLCNT10x30 > +#define PLLCNT(n) (((n) - 1) * 4 + PLLCNT1) > + > +#define CLKSTOP1 0x54 > +#define CLKSTOP(n) (((n) - 1) * 4 + CLKSTOP1) > + > +#define CRSWR 0x8c > +#define CRRRS 0x90 > +#define CRRSM 0x94 > + > +#define to_m10v_mux(_hw) container_of(_hw, struct m10v_mux, hw) > +#define to_m10v_gate(_hw) container_of(_hw, struct m10v_gate, hw) > +#define to_m10v_div(_hw) container_of(_hw, struct m10v_div, hw) > +#define to_m10v_pll(_hw) container_of(_hw, struct m10v_pll, hw) > + > +static void __iomem *clk_base; > +static struct device_node *np_top; > +static DEFINE_SPINLOCK(crglock); Please make more specific names for these global variables by prefixing with m10v_. Also consider getting rid of the iomem and np_top globals entirely and associate those with clks differently. > + > +static __init void __iomem *m10v_clk_iomap(void) > +{ > + if (clk_base) > + return clk_base; > + > + np_top = of_find_compatible_node(NULL, NULL, > + "socionext,milbeaut-m10v-clk-regs"); > + if (!np_top) { > + pr_err("%s: CLK iomap failed!\n", __func__); We haven't iomapped yet though. > + return NULL; > + } > + > + clk_base = of_iomap(np_top, 0); > + of_node_put(np_top); Would be nicer to use platform_device APIs instead of OF ones. > + > + return clk_base; > +} > + > +struct m10v_mux { > + struct clk_hw hw; > + const char *cname; > + u32 parent; > +}; > + > +static u8 m10v_mux_get_parent(struct clk_hw *hw) > +{ > + struct m10v_mux *mcm = to_m10v_mux(hw); > + struct clk_hw *parent; > + int i; > + > + i = clk_hw_get_num_parents(hw); > + while (i--) { > + parent = clk_hw_get_parent_by_index(hw, i); > + if (clk_hw_get_rate(parent)) > + break; > + } > + > + if (i < 0) { > + pr_info("%s:%s no parent?!\n", > + __func__, mcm->cname); > + i = 0; > + } > + > + return i; > +} > + > +static int m10v_mux_set_parent(struct clk_hw *hw, u8 index) > +{ > + struct m10v_mux *mcm = to_m10v_mux(hw); > + > + mcm->parent = index; > + return 0; > +} > + > +static const struct clk_ops m10v_mux_ops = { > + .get_parent = m10v_mux_get_parent, > + .set_parent = m10v_mux_set_parent, > + .determine_rate = __clk_mux_determine_rate, > +}; > + > +void __init m10v_clk_mux_setup(struct device_node *node) > +{ > + const char *clk_name = node->name; > + struct clk_init_data init; > + const char **parent_names; > + struct m10v_mux *mcm; > + struct clk *clk; > + int i, parents; > + > + if (!m10v_clk_iomap()) > + return; > + > + of_property_read_string(node, "clock-output-names", _name); > + > + parents = of_clk_get_parent_count(node); > + if (parents < 2) { > + pr_err("%s: not a mux\n", clk_name); How is this possible? > + return; > + } > + > + parent_names = kzalloc((sizeof(char *) * parents), GFP_KERNEL); > + if (!parent_names) > + return; > + > + for (i = 0; i < parents; i++) > + parent_names[i] = of_clk_get_parent_name(node, i); This is of_clk_parent_fill(). > + > + mcm = kzalloc(sizeof(*mcm), GFP_KERNEL); > + if (!mcm) > + goto err_mcm; > + > + init.name = clk_name; > + init.ops = _mux_ops; > + init.flags = CLK_IS_BASIC | CLK_SET_RATE_PARENT; Please don't use CLK_IS_BASIC unless you need it. > + init.num_parents = parents; > + init.parent_names = parent_names; > + > + mcm->cname = clk_name; > + mcm->parent = 0; > + mcm->hw.init = > + > + clk = clk_register(NULL, >hw); > + if (IS_ERR(clk)) > + goto
Re: [PATCH 07/14] clock: milbeaut: Add Milbeaut M10V clock control
Quoting Sugaya Taichi (2018-11-18 17:01:12) > Add Milbeaut M10V clock ( including PLL ) control. Please give some more details here. > > Signed-off-by: Sugaya Taichi > --- > drivers/clk/Makefile | 1 + > drivers/clk/clk-m10v.c | 671 > + And this is different from Uniphier? Maybe we need a socionext directory under drivers/clk/. > 2 files changed, 672 insertions(+) > create mode 100644 drivers/clk/clk-m10v.c > > diff --git a/drivers/clk/clk-m10v.c b/drivers/clk/clk-m10v.c > new file mode 100644 > index 000..aa92a69 > --- /dev/null > +++ b/drivers/clk/clk-m10v.c > @@ -0,0 +1,671 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Copyright (C) 2018 Socionext Inc. > + * Copyright (C) 2016 Linaro Ltd. > + * > + */ > + > +#include > +#include Is this include used? > +#include > +#include > +#include > +#include > +#include > +#include > + > +#define CLKSEL10x0 > +#define CLKSEL(n) (((n) - 1) * 4 + CLKSEL1) > + > +#define PLLCNT10x30 > +#define PLLCNT(n) (((n) - 1) * 4 + PLLCNT1) > + > +#define CLKSTOP1 0x54 > +#define CLKSTOP(n) (((n) - 1) * 4 + CLKSTOP1) > + > +#define CRSWR 0x8c > +#define CRRRS 0x90 > +#define CRRSM 0x94 > + > +#define to_m10v_mux(_hw) container_of(_hw, struct m10v_mux, hw) > +#define to_m10v_gate(_hw) container_of(_hw, struct m10v_gate, hw) > +#define to_m10v_div(_hw) container_of(_hw, struct m10v_div, hw) > +#define to_m10v_pll(_hw) container_of(_hw, struct m10v_pll, hw) > + > +static void __iomem *clk_base; > +static struct device_node *np_top; > +static DEFINE_SPINLOCK(crglock); Please make more specific names for these global variables by prefixing with m10v_. Also consider getting rid of the iomem and np_top globals entirely and associate those with clks differently. > + > +static __init void __iomem *m10v_clk_iomap(void) > +{ > + if (clk_base) > + return clk_base; > + > + np_top = of_find_compatible_node(NULL, NULL, > + "socionext,milbeaut-m10v-clk-regs"); > + if (!np_top) { > + pr_err("%s: CLK iomap failed!\n", __func__); We haven't iomapped yet though. > + return NULL; > + } > + > + clk_base = of_iomap(np_top, 0); > + of_node_put(np_top); Would be nicer to use platform_device APIs instead of OF ones. > + > + return clk_base; > +} > + > +struct m10v_mux { > + struct clk_hw hw; > + const char *cname; > + u32 parent; > +}; > + > +static u8 m10v_mux_get_parent(struct clk_hw *hw) > +{ > + struct m10v_mux *mcm = to_m10v_mux(hw); > + struct clk_hw *parent; > + int i; > + > + i = clk_hw_get_num_parents(hw); > + while (i--) { > + parent = clk_hw_get_parent_by_index(hw, i); > + if (clk_hw_get_rate(parent)) > + break; > + } > + > + if (i < 0) { > + pr_info("%s:%s no parent?!\n", > + __func__, mcm->cname); > + i = 0; > + } > + > + return i; > +} > + > +static int m10v_mux_set_parent(struct clk_hw *hw, u8 index) > +{ > + struct m10v_mux *mcm = to_m10v_mux(hw); > + > + mcm->parent = index; > + return 0; > +} > + > +static const struct clk_ops m10v_mux_ops = { > + .get_parent = m10v_mux_get_parent, > + .set_parent = m10v_mux_set_parent, > + .determine_rate = __clk_mux_determine_rate, > +}; > + > +void __init m10v_clk_mux_setup(struct device_node *node) > +{ > + const char *clk_name = node->name; > + struct clk_init_data init; > + const char **parent_names; > + struct m10v_mux *mcm; > + struct clk *clk; > + int i, parents; > + > + if (!m10v_clk_iomap()) > + return; > + > + of_property_read_string(node, "clock-output-names", _name); > + > + parents = of_clk_get_parent_count(node); > + if (parents < 2) { > + pr_err("%s: not a mux\n", clk_name); How is this possible? > + return; > + } > + > + parent_names = kzalloc((sizeof(char *) * parents), GFP_KERNEL); > + if (!parent_names) > + return; > + > + for (i = 0; i < parents; i++) > + parent_names[i] = of_clk_get_parent_name(node, i); This is of_clk_parent_fill(). > + > + mcm = kzalloc(sizeof(*mcm), GFP_KERNEL); > + if (!mcm) > + goto err_mcm; > + > + init.name = clk_name; > + init.ops = _mux_ops; > + init.flags = CLK_IS_BASIC | CLK_SET_RATE_PARENT; Please don't use CLK_IS_BASIC unless you need it. > + init.num_parents = parents; > + init.parent_names = parent_names; > + > + mcm->cname = clk_name; > + mcm->parent = 0; > + mcm->hw.init = > + > + clk = clk_register(NULL, >hw); > + if (IS_ERR(clk)) > + goto
[PATCH 07/14] clock: milbeaut: Add Milbeaut M10V clock control
Add Milbeaut M10V clock ( including PLL ) control. Signed-off-by: Sugaya Taichi --- drivers/clk/Makefile | 1 + drivers/clk/clk-m10v.c | 671 + 2 files changed, 672 insertions(+) create mode 100644 drivers/clk/clk-m10v.c diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index 72be7a3..da5b282 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -30,6 +30,7 @@ obj-$(CONFIG_COMMON_CLK_GEMINI) += clk-gemini.o obj-$(CONFIG_COMMON_CLK_ASPEED)+= clk-aspeed.o obj-$(CONFIG_ARCH_HIGHBANK)+= clk-highbank.o obj-$(CONFIG_CLK_HSDK) += clk-hsdk-pll.o +obj-$(CONFIG_ARCH_MILBEAUT_M10V) += clk-m10v.o obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o obj-$(CONFIG_COMMON_CLK_MAX9485) += clk-max9485.o obj-$(CONFIG_ARCH_MOXART) += clk-moxart.o diff --git a/drivers/clk/clk-m10v.c b/drivers/clk/clk-m10v.c new file mode 100644 index 000..aa92a69 --- /dev/null +++ b/drivers/clk/clk-m10v.c @@ -0,0 +1,671 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2018 Socionext Inc. + * Copyright (C) 2016 Linaro Ltd. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define CLKSEL10x0 +#define CLKSEL(n) (((n) - 1) * 4 + CLKSEL1) + +#define PLLCNT10x30 +#define PLLCNT(n) (((n) - 1) * 4 + PLLCNT1) + +#define CLKSTOP1 0x54 +#define CLKSTOP(n) (((n) - 1) * 4 + CLKSTOP1) + +#define CRSWR 0x8c +#define CRRRS 0x90 +#define CRRSM 0x94 + +#define to_m10v_mux(_hw) container_of(_hw, struct m10v_mux, hw) +#define to_m10v_gate(_hw) container_of(_hw, struct m10v_gate, hw) +#define to_m10v_div(_hw) container_of(_hw, struct m10v_div, hw) +#define to_m10v_pll(_hw) container_of(_hw, struct m10v_pll, hw) + +static void __iomem *clk_base; +static struct device_node *np_top; +static DEFINE_SPINLOCK(crglock); + +static __init void __iomem *m10v_clk_iomap(void) +{ + if (clk_base) + return clk_base; + + np_top = of_find_compatible_node(NULL, NULL, + "socionext,milbeaut-m10v-clk-regs"); + if (!np_top) { + pr_err("%s: CLK iomap failed!\n", __func__); + return NULL; + } + + clk_base = of_iomap(np_top, 0); + of_node_put(np_top); + + return clk_base; +} + +struct m10v_mux { + struct clk_hw hw; + const char *cname; + u32 parent; +}; + +static u8 m10v_mux_get_parent(struct clk_hw *hw) +{ + struct m10v_mux *mcm = to_m10v_mux(hw); + struct clk_hw *parent; + int i; + + i = clk_hw_get_num_parents(hw); + while (i--) { + parent = clk_hw_get_parent_by_index(hw, i); + if (clk_hw_get_rate(parent)) + break; + } + + if (i < 0) { + pr_info("%s:%s no parent?!\n", + __func__, mcm->cname); + i = 0; + } + + return i; +} + +static int m10v_mux_set_parent(struct clk_hw *hw, u8 index) +{ + struct m10v_mux *mcm = to_m10v_mux(hw); + + mcm->parent = index; + return 0; +} + +static const struct clk_ops m10v_mux_ops = { + .get_parent = m10v_mux_get_parent, + .set_parent = m10v_mux_set_parent, + .determine_rate = __clk_mux_determine_rate, +}; + +void __init m10v_clk_mux_setup(struct device_node *node) +{ + const char *clk_name = node->name; + struct clk_init_data init; + const char **parent_names; + struct m10v_mux *mcm; + struct clk *clk; + int i, parents; + + if (!m10v_clk_iomap()) + return; + + of_property_read_string(node, "clock-output-names", _name); + + parents = of_clk_get_parent_count(node); + if (parents < 2) { + pr_err("%s: not a mux\n", clk_name); + return; + } + + parent_names = kzalloc((sizeof(char *) * parents), GFP_KERNEL); + if (!parent_names) + return; + + for (i = 0; i < parents; i++) + parent_names[i] = of_clk_get_parent_name(node, i); + + mcm = kzalloc(sizeof(*mcm), GFP_KERNEL); + if (!mcm) + goto err_mcm; + + init.name = clk_name; + init.ops = _mux_ops; + init.flags = CLK_IS_BASIC | CLK_SET_RATE_PARENT; + init.num_parents = parents; + init.parent_names = parent_names; + + mcm->cname = clk_name; + mcm->parent = 0; + mcm->hw.init = + + clk = clk_register(NULL, >hw); + if (IS_ERR(clk)) + goto err_clk; + + of_clk_add_provider(node, of_clk_src_simple_get, clk); + return; + +err_clk: + kfree(mcm); +err_mcm: + kfree(parent_names); +} +CLK_OF_DECLARE(m10v_clk_mux, "socionext,milbeaut-m10v-clk-mux", + m10v_clk_mux_setup); + +struct m10v_pll { +
[PATCH 07/14] clock: milbeaut: Add Milbeaut M10V clock control
Add Milbeaut M10V clock ( including PLL ) control. Signed-off-by: Sugaya Taichi --- drivers/clk/Makefile | 1 + drivers/clk/clk-m10v.c | 671 + 2 files changed, 672 insertions(+) create mode 100644 drivers/clk/clk-m10v.c diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index 72be7a3..da5b282 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -30,6 +30,7 @@ obj-$(CONFIG_COMMON_CLK_GEMINI) += clk-gemini.o obj-$(CONFIG_COMMON_CLK_ASPEED)+= clk-aspeed.o obj-$(CONFIG_ARCH_HIGHBANK)+= clk-highbank.o obj-$(CONFIG_CLK_HSDK) += clk-hsdk-pll.o +obj-$(CONFIG_ARCH_MILBEAUT_M10V) += clk-m10v.o obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o obj-$(CONFIG_COMMON_CLK_MAX9485) += clk-max9485.o obj-$(CONFIG_ARCH_MOXART) += clk-moxart.o diff --git a/drivers/clk/clk-m10v.c b/drivers/clk/clk-m10v.c new file mode 100644 index 000..aa92a69 --- /dev/null +++ b/drivers/clk/clk-m10v.c @@ -0,0 +1,671 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2018 Socionext Inc. + * Copyright (C) 2016 Linaro Ltd. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define CLKSEL10x0 +#define CLKSEL(n) (((n) - 1) * 4 + CLKSEL1) + +#define PLLCNT10x30 +#define PLLCNT(n) (((n) - 1) * 4 + PLLCNT1) + +#define CLKSTOP1 0x54 +#define CLKSTOP(n) (((n) - 1) * 4 + CLKSTOP1) + +#define CRSWR 0x8c +#define CRRRS 0x90 +#define CRRSM 0x94 + +#define to_m10v_mux(_hw) container_of(_hw, struct m10v_mux, hw) +#define to_m10v_gate(_hw) container_of(_hw, struct m10v_gate, hw) +#define to_m10v_div(_hw) container_of(_hw, struct m10v_div, hw) +#define to_m10v_pll(_hw) container_of(_hw, struct m10v_pll, hw) + +static void __iomem *clk_base; +static struct device_node *np_top; +static DEFINE_SPINLOCK(crglock); + +static __init void __iomem *m10v_clk_iomap(void) +{ + if (clk_base) + return clk_base; + + np_top = of_find_compatible_node(NULL, NULL, + "socionext,milbeaut-m10v-clk-regs"); + if (!np_top) { + pr_err("%s: CLK iomap failed!\n", __func__); + return NULL; + } + + clk_base = of_iomap(np_top, 0); + of_node_put(np_top); + + return clk_base; +} + +struct m10v_mux { + struct clk_hw hw; + const char *cname; + u32 parent; +}; + +static u8 m10v_mux_get_parent(struct clk_hw *hw) +{ + struct m10v_mux *mcm = to_m10v_mux(hw); + struct clk_hw *parent; + int i; + + i = clk_hw_get_num_parents(hw); + while (i--) { + parent = clk_hw_get_parent_by_index(hw, i); + if (clk_hw_get_rate(parent)) + break; + } + + if (i < 0) { + pr_info("%s:%s no parent?!\n", + __func__, mcm->cname); + i = 0; + } + + return i; +} + +static int m10v_mux_set_parent(struct clk_hw *hw, u8 index) +{ + struct m10v_mux *mcm = to_m10v_mux(hw); + + mcm->parent = index; + return 0; +} + +static const struct clk_ops m10v_mux_ops = { + .get_parent = m10v_mux_get_parent, + .set_parent = m10v_mux_set_parent, + .determine_rate = __clk_mux_determine_rate, +}; + +void __init m10v_clk_mux_setup(struct device_node *node) +{ + const char *clk_name = node->name; + struct clk_init_data init; + const char **parent_names; + struct m10v_mux *mcm; + struct clk *clk; + int i, parents; + + if (!m10v_clk_iomap()) + return; + + of_property_read_string(node, "clock-output-names", _name); + + parents = of_clk_get_parent_count(node); + if (parents < 2) { + pr_err("%s: not a mux\n", clk_name); + return; + } + + parent_names = kzalloc((sizeof(char *) * parents), GFP_KERNEL); + if (!parent_names) + return; + + for (i = 0; i < parents; i++) + parent_names[i] = of_clk_get_parent_name(node, i); + + mcm = kzalloc(sizeof(*mcm), GFP_KERNEL); + if (!mcm) + goto err_mcm; + + init.name = clk_name; + init.ops = _mux_ops; + init.flags = CLK_IS_BASIC | CLK_SET_RATE_PARENT; + init.num_parents = parents; + init.parent_names = parent_names; + + mcm->cname = clk_name; + mcm->parent = 0; + mcm->hw.init = + + clk = clk_register(NULL, >hw); + if (IS_ERR(clk)) + goto err_clk; + + of_clk_add_provider(node, of_clk_src_simple_get, clk); + return; + +err_clk: + kfree(mcm); +err_mcm: + kfree(parent_names); +} +CLK_OF_DECLARE(m10v_clk_mux, "socionext,milbeaut-m10v-clk-mux", + m10v_clk_mux_setup); + +struct m10v_pll { +