[PATCH 7/7] clk: add highbank clock support
Shawn Guo
shawn.guo at linaro.org
Tue Apr 10 12:06:42 EST 2012
On Tue, Mar 13, 2012 at 06:22:27PM -0500, Rob Herring wrote:
> From: Rob Herring <rob.herring at calxeda.com>
>
> This adds real clock support to Calxeda Highbank SOC using the common
> clock infrastructure.
>
> Signed-off-by: Rob Herring <rob.herring at calxeda.com>
> ---
> arch/arm/Kconfig | 1 +
> arch/arm/boot/dts/highbank.dts | 76 +++++++++
> arch/arm/mach-highbank/Makefile | 2 +-
> arch/arm/mach-highbank/clock.c | 62 -------
> arch/arm/mach-highbank/highbank.c | 16 ++
> drivers/clk/Makefile | 2 +
> drivers/clk/clk-highbank.c | 335 +++++++++++++++++++++++++++++++++++++
> 7 files changed, 431 insertions(+), 63 deletions(-)
> delete mode 100644 arch/arm/mach-highbank/clock.c
> create mode 100644 drivers/clk/clk-highbank.c
>
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index a48aecc..2019548 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -346,6 +346,7 @@ config ARCH_HIGHBANK
> select ARM_TIMER_SP804
> select CACHE_L2X0
> select CLKDEV_LOOKUP
> + select COMMON_CLK
> select CPU_V7
> select GENERIC_CLOCKEVENTS
> select HAVE_ARM_SCU
> diff --git a/arch/arm/boot/dts/highbank.dts b/arch/arm/boot/dts/highbank.dts
> index 305635b..06194d5 100644
> --- a/arch/arm/boot/dts/highbank.dts
> +++ b/arch/arm/boot/dts/highbank.dts
> @@ -24,6 +24,7 @@
> compatible = "calxeda,highbank";
> #address-cells = <1>;
> #size-cells = <1>;
> + clock-ranges;
>
> cpus {
> #address-cells = <1>;
> @@ -75,12 +76,14 @@
> compatible = "arm,smp-twd";
> reg = <0xfff10600 0x20>;
> interrupts = <1 13 0xf04>;
> + clocks = <&a9periphclk>;
> };
>
> watchdog at fff10620 {
> compatible = "arm,cortex-a9-wdt";
> reg = <0xfff10620 0x20>;
> interrupts = <1 14 0xf04>;
> + clocks = <&a9periphclk>;
> };
>
> intc: interrupt-controller at fff11000 {
> @@ -117,12 +120,14 @@
> compatible = "calxeda,hb-sdhci";
> reg = <0xffe0e000 0x1000>;
> interrupts = <0 90 4>;
> + clocks = <&eclk>;
> };
>
> ipc at fff20000 {
> compatible = "arm,pl320", "arm,primecell";
> reg = <0xfff20000 0x1000>;
> interrupts = <0 7 4>;
> + clocks = <&pclk>;
> };
>
> gpioe: gpio at fff30000 {
> @@ -131,6 +136,7 @@
> gpio-controller;
> reg = <0xfff30000 0x1000>;
> interrupts = <0 14 4>;
> + clocks = <&pclk>;
> };
>
> gpiof: gpio at fff31000 {
> @@ -139,6 +145,7 @@
> gpio-controller;
> reg = <0xfff31000 0x1000>;
> interrupts = <0 15 4>;
> + clocks = <&pclk>;
> };
>
> gpiog: gpio at fff32000 {
> @@ -147,6 +154,7 @@
> gpio-controller;
> reg = <0xfff32000 0x1000>;
> interrupts = <0 16 4>;
> + clocks = <&pclk>;
> };
>
> gpioh: gpio at fff33000 {
> @@ -155,24 +163,30 @@
> gpio-controller;
> reg = <0xfff33000 0x1000>;
> interrupts = <0 17 4>;
> + clocks = <&pclk>;
> };
>
> timer {
> compatible = "arm,sp804", "arm,primecell";
> reg = <0xfff34000 0x1000>;
> interrupts = <0 18 4>;
> + clocks = <&pclk>, <&pclk>;
> + clock-names = "apb_pclk", "bus";
> };
>
> rtc at fff35000 {
> compatible = "arm,pl031", "arm,primecell";
> reg = <0xfff35000 0x1000>;
> interrupts = <0 19 4>;
> + clocks = <&pclk>;
> };
>
> serial at fff36000 {
> compatible = "arm,pl011", "arm,primecell";
> reg = <0xfff36000 0x1000>;
> interrupts = <0 20 4>;
> + clocks = <&pclk>, <&pclk>;
> + clock-names = "apb_pclk", "bus";
> };
>
> smic at fff3a000 {
> @@ -187,12 +201,74 @@
> sregs at fff3c000 {
> compatible = "calxeda,hb-sregs";
> reg = <0xfff3c000 0x1000>;
> +
> + clocks {
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + osc: oscillator {
> + #clock-cells = <0>;
> + compatible = "fixed-clock";
> + clock-frequency = <33333000>;
> + };
> +
> + ddrpll: ddrpll {
> + #clock-cells = <0>;
> + compatible = "calxeda,hb-pll-clock";
Where are all these "calxeda,*-clock' compatible documented?
> + clocks = <&osc>;
> + reg = <0x108>;
> + };
> +
> + a9pll: a9pll {
> + #clock-cells = <0>;
> + compatible = "calxeda,hb-pll-clock";
> + clocks = <&osc>;
> + reg = <0x100>;
> + };
> +
> + a9periphclk: a9periphclk {
> + #clock-cells = <0>;
> + compatible = "calxeda,hb-a9periph-clock";
> + clocks = <&a9pll>;
> + reg = <0x104>;
> + clock-divider = <4>;
Where is this "clock-divider" binding documented?
> + };
> +
> + a9bclk: a9bclk {
> + #clock-cells = <0>;
> + compatible = "calxeda,hb-a9bus-clock";
> + clocks = <&a9pll>;
> + reg = <0x104>;
> + clock-divider = <4>;
> + };
> +
> + emmcpll: emmcpll {
> + #clock-cells = <0>;
> + compatible = "calxeda,hb-pll-clock";
> + clocks = <&osc>;
> + reg = <0x10C>;
> + };
> +
> + eclk: eclk {
> + #clock-cells = <0>;
> + compatible = "calxeda,hb-emmc-clock";
> + clocks = <&emmcpll>;
> + reg = <0x114>;
> + };
> +
> + pclk: pclk {
> + #clock-cells = <0>;
> + compatible = "fixed-clock";
> + clock-frequency = <150000000>;
> + };
> + };
> };
>
> dma at fff3d000 {
> compatible = "arm,pl330", "arm,primecell";
> reg = <0xfff3d000 0x1000>;
> interrupts = <0 92 4>;
> + clocks = <&pclk>;
> };
>
> ethernet at fff50000 {
> diff --git a/arch/arm/mach-highbank/Makefile b/arch/arm/mach-highbank/Makefile
> index 986958a..8bf3868 100644
> --- a/arch/arm/mach-highbank/Makefile
> +++ b/arch/arm/mach-highbank/Makefile
> @@ -1,4 +1,4 @@
> -obj-y := clock.o highbank.o system.o
> +obj-y := highbank.o system.o
> obj-$(CONFIG_DEBUG_HIGHBANK_UART) += lluart.o
> obj-$(CONFIG_SMP) += platsmp.o
> obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
> diff --git a/arch/arm/mach-highbank/clock.c b/arch/arm/mach-highbank/clock.c
> deleted file mode 100644
> index c25a2ae..0000000
> --- a/arch/arm/mach-highbank/clock.c
> +++ /dev/null
> @@ -1,62 +0,0 @@
> -/*
> - * Copyright 2011 Calxeda, Inc.
> - *
> - * This program is free software; you can redistribute it and/or modify it
> - * under the terms and conditions of the GNU General Public License,
> - * version 2, as published by the Free Software Foundation.
> - *
> - * This program is distributed in the hope it will be useful, but WITHOUT
> - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
> - * more details.
> - *
> - * You should have received a copy of the GNU General Public License along with
> - * this program. If not, see <http://www.gnu.org/licenses/>.
> - */
> -#include <linux/module.h>
> -#include <linux/kernel.h>
> -#include <linux/errno.h>
> -#include <linux/clk.h>
> -#include <linux/clkdev.h>
> -
> -struct clk {
> - unsigned long rate;
> -};
> -
> -int clk_enable(struct clk *clk)
> -{
> - return 0;
> -}
> -
> -void clk_disable(struct clk *clk)
> -{}
> -
> -unsigned long clk_get_rate(struct clk *clk)
> -{
> - return clk->rate;
> -}
> -
> -long clk_round_rate(struct clk *clk, unsigned long rate)
> -{
> - return clk->rate;
> -}
> -
> -int clk_set_rate(struct clk *clk, unsigned long rate)
> -{
> - return 0;
> -}
> -
> -static struct clk eclk = { .rate = 200000000 };
> -static struct clk pclk = { .rate = 150000000 };
> -
> -static struct clk_lookup lookups[] = {
> - { .clk = &pclk, .con_id = "apb_pclk", },
> - { .clk = &pclk, .dev_id = "sp804", },
> - { .clk = &eclk, .dev_id = "ffe0e000.sdhci", },
> - { .clk = &pclk, .dev_id = "fff36000.serial", },
> -};
> -
> -void __init highbank_clocks_init(void)
> -{
> - clkdev_add_table(lookups, ARRAY_SIZE(lookups));
> -}
> diff --git a/arch/arm/mach-highbank/highbank.c b/arch/arm/mach-highbank/highbank.c
> index 8394d51..5c0cdaa 100644
> --- a/arch/arm/mach-highbank/highbank.c
> +++ b/arch/arm/mach-highbank/highbank.c
> @@ -23,6 +23,7 @@
> #include <linux/of_platform.h>
> #include <linux/of_address.h>
> #include <linux/smp.h>
> +#include <linux/of_clk.h>
>
> #include <asm/cacheflush.h>
> #include <asm/smp_plat.h>
> @@ -91,6 +92,16 @@ static void __init highbank_init_irq(void)
> l2x0_of_init(0, ~0UL);
> }
>
> +static struct clk_lookup lookups[] = {
> + {
> + .dev_id = "sp804",
> + .con_id = NULL,
> + }, {
> + .dev_id = "smp_twd",
> + .con_id = NULL,
> + }
> +};
> +
> static void __init highbank_timer_init(void)
> {
> int irq;
> @@ -108,6 +119,11 @@ static void __init highbank_timer_init(void)
> irq = irq_of_parse_and_map(np, 0);
>
> highbank_clocks_init();
> + lookups[0].clk = of_clk_get(np, 0);
> +
> + np = of_find_compatible_node(NULL, NULL, "arm,smp-twd");
> + lookups[1].clk = of_clk_get(np, 0);
> + clkdev_add_table(lookups, ARRAY_SIZE(lookups));
>
> sp804_clocksource_init(timer_base + 0x20, "timer1");
> sp804_clockevents_init(timer_base, irq, "timer0");
> diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
> index 1f736bc..70c713f 100644
> --- a/drivers/clk/Makefile
> +++ b/drivers/clk/Makefile
> @@ -2,3 +2,5 @@
> obj-$(CONFIG_CLKDEV_LOOKUP) += clkdev.o
> obj-$(CONFIG_COMMON_CLK) += clk.o clk-fixed-rate.o clk-gate.o \
> clk-mux.o clk-divider.o
> +
> +obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o
> diff --git a/drivers/clk/clk-highbank.c b/drivers/clk/clk-highbank.c
> new file mode 100644
> index 0000000..722fc67
> --- /dev/null
> +++ b/drivers/clk/clk-highbank.c
> @@ -0,0 +1,335 @@
> +/*
> + * Copyright 2011-2012 Calxeda, Inc.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
> + * more details.
> + *
> + * You should have received a copy of the GNU General Public License along with
> + * this program. If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/slab.h>
> +#include <linux/errno.h>
> +#include <linux/clk-provider.h>
> +#include <linux/io.h>
> +#include <linux/of.h>
> +#include <linux/of_clk.h>
> +
> +extern void __iomem *sregs_base;
> +
> +#define HB_PLL_LOCK_500 0x20000000
> +#define HB_PLL_LOCK 0x10000000
> +#define HB_PLL_DIVF_SHIFT 20
> +#define HB_PLL_DIVF_MASK 0x0ff00000
> +#define HB_PLL_DIVQ_SHIFT 16
> +#define HB_PLL_DIVQ_MASK 0x00070000
> +#define HB_PLL_DIVR_SHIFT 8
> +#define HB_PLL_DIVR_MASK 0x00001f00
> +#define HB_PLL_RANGE_SHIFT 4
> +#define HB_PLL_RANGE_MASK 0x00000070
> +#define HB_PLL_BYPASS 0x00000008
> +#define HB_PLL_RESET 0x00000004
> +#define HB_PLL_EXT_BYPASS 0x00000002
> +#define HB_PLL_EXT_ENA 0x00000001
> +
> +#define HB_PLL_VCO_MIN_FREQ 2133000000
> +#define HB_PLL_MAX_FREQ HB_PLL_VCO_MIN_FREQ
> +#define HB_PLL_MIN_FREQ (HB_PLL_VCO_MIN_FREQ / 64)
> +
> +#define HB_A9_BCLK_DIV_MASK 0x00000006
> +#define HB_A9_BCLK_DIV_SHIFT 1
> +
> +struct hb_clk {
> + struct clk_hw hw;
> + void __iomem *reg;
> + char *parent_name;
> +};
> +#define to_hb_clk(p) container_of(p, struct hb_clk, hw)
> +
> +static int clk_pll_prepare(struct clk_hw *clk)
> + {
> + struct hb_clk *hbclk = to_hb_clk(clk);
> + u32 reg;
> +
> + reg = readl(hbclk->reg);
> + reg &= ~HB_PLL_RESET;
> + writel(reg, hbclk->reg);
> +
> + while ((readl(hbclk->reg) & HB_PLL_LOCK) == 0)
> + ;
> + while ((readl(hbclk->reg) & HB_PLL_LOCK_500) == 0)
> + ;
> +
> + return 0;
> +}
> +
> +static void clk_pll_unprepare(struct clk_hw *clk)
> +{
> + struct hb_clk *hbclk = to_hb_clk(clk);
> + u32 reg;
> +
> + reg = readl(hbclk->reg);
> + reg |= HB_PLL_RESET;
> + writel(reg, hbclk->reg);
> +}
> +
> +static int clk_pll_enable(struct clk_hw *clk)
> +{
> + struct hb_clk *hbclk = to_hb_clk(clk);
> + u32 reg;
> +
> + reg = readl(hbclk->reg);
> + reg |= HB_PLL_EXT_ENA;
> + writel(reg, hbclk->reg);
> +
> + return 0;
> +}
> +
> +static void clk_pll_disable(struct clk_hw *clk)
> +{
> + struct hb_clk *hbclk = to_hb_clk(clk);
> + u32 reg;
> +
> + reg = readl(hbclk->reg);
> + reg &= ~HB_PLL_EXT_ENA;
> + writel(reg, hbclk->reg);
> +}
> +
> +static unsigned long clk_pll_recalc_rate(struct clk_hw *clk,
> + unsigned long parent_rate)
> +{
> + struct hb_clk *hbclk = to_hb_clk(clk);
> + unsigned long divf, divq, vco_freq, reg;
> +
> + reg = readl(hbclk->reg);
> + if (reg & HB_PLL_EXT_BYPASS)
> + return parent_rate;
> +
> + divf = (reg & HB_PLL_DIVF_MASK) >> HB_PLL_DIVF_SHIFT;
> + divq = (reg & HB_PLL_DIVQ_MASK) >> HB_PLL_DIVQ_SHIFT;
> + vco_freq = parent_rate * (divf + 1);
> +
> + return vco_freq / (1 << divq);
> +}
> +
> +static void clk_pll_calc(unsigned long rate, unsigned long ref_freq,
> + u32 *pdivq, u32 *pdivf)
> +{
> + u32 divq, divf;
> + unsigned long vco_freq;
> +
> + if (rate < HB_PLL_MIN_FREQ)
> + rate = HB_PLL_MIN_FREQ;
> + if (rate > HB_PLL_MAX_FREQ)
> + rate = HB_PLL_MAX_FREQ;
> +
> + for (divq = 1; divq <= 6; divq++) {
> + if ((rate * (1 << divq)) >= HB_PLL_VCO_MIN_FREQ)
> + break;
> + }
> +
> + vco_freq = rate * (1 << divq);
> + divf = (vco_freq + (ref_freq / 2)) / ref_freq;
> + divf--;
> +
> + *pdivq = divq;
> + *pdivf = divf;
> +}
> +
> +static long clk_pll_round_rate(struct clk_hw *clk, unsigned long rate,
> + unsigned long *unused)
> +{
> + u32 divq, divf;
> + unsigned long ref_freq = clk_get_rate(clk_get_parent(clk->clk));
> +
> + clk_pll_calc(rate, ref_freq, &divq, &divf);
> +
> + return (ref_freq * (divf + 1)) / (1 << divq);
> +}
> +
> +static int clk_pll_set_rate(struct clk_hw *clk, unsigned long rate)
> +{
> + struct hb_clk *hbclk = to_hb_clk(clk);
> + unsigned long parent_rate;
> + u32 divq, divf;
> + u32 reg;
> +
> + parent_rate = clk_get_rate(clk_get_parent(clk->clk));
> + clk_pll_calc(rate, parent_rate, &divq, &divf);
> +
> + reg = readl(hbclk->reg);
> + if (divf != ((reg & HB_PLL_DIVF_MASK) >> HB_PLL_DIVF_SHIFT)) {
> + /* Need to re-lock PLL, so put it into bypass mode */
> + reg |= HB_PLL_EXT_BYPASS;
> + writel(reg | HB_PLL_EXT_BYPASS, hbclk->reg);
> +
> + reg &= ~(HB_PLL_DIVF_MASK | HB_PLL_DIVQ_MASK);
> + reg |= (divf << HB_PLL_DIVF_SHIFT) | (divq << HB_PLL_DIVQ_SHIFT);
> + writel(reg | HB_PLL_RESET, hbclk->reg);
> + writel(reg, hbclk->reg);
> +
> + while ((readl(hbclk->reg) & HB_PLL_LOCK) == 0)
> + ;
> + while ((readl(hbclk->reg) & HB_PLL_LOCK_500) == 0)
> + ;
> + reg |= HB_PLL_EXT_ENA;
> + reg &= ~HB_PLL_EXT_BYPASS;
> + } else {
> + reg &= ~HB_PLL_DIVQ_MASK;
> + reg |= divq << HB_PLL_DIVQ_SHIFT;
> + }
> + writel(reg, hbclk->reg);
> +
> + return 0;
> +}
> +
> +static const struct clk_ops clk_pll_ops = {
> + .prepare = clk_pll_prepare,
> + .unprepare = clk_pll_unprepare,
> + .enable = clk_pll_enable,
> + .disable = clk_pll_disable,
> + .recalc_rate = clk_pll_recalc_rate,
> + .round_rate = clk_pll_round_rate,
> + .set_rate = clk_pll_set_rate,
> +};
> +
> +static unsigned long clk_cpu_periphclk_recalc_rate(struct clk_hw *clk,
> + unsigned long parent_rate)
> +{
> + return parent_rate / 2;
> +}
> +
> +static const struct clk_ops a9periphclk_ops = {
> + .recalc_rate = clk_cpu_periphclk_recalc_rate,
> +};
> +
This basically is a clk-fixed-factor added by Sascha.
> +static unsigned long clk_cpu_a9bclk_recalc_rate(struct clk_hw *clk,
> + unsigned long parent_rate)
> +{
> + struct hb_clk *hbclk = to_hb_clk(clk);
> + u32 div = (readl(hbclk->reg) & HB_A9_BCLK_DIV_MASK) >> HB_A9_BCLK_DIV_SHIFT;
> +
> + return parent_rate / (div + 2);
> +}
> +
> +static const struct clk_ops a9bclk_ops = {
> + .recalc_rate = clk_cpu_a9bclk_recalc_rate,
Since there is a divider for the clock, the ops should have .round_rate
and .set_rate, no?
> +};
> +
> +static unsigned long clk_periclk_recalc_rate(struct clk_hw *clk,
> + unsigned long parent_rate)
> +{
> + struct hb_clk *hbclk = to_hb_clk(clk);
> + u32 div;
> +
> + div = readl(hbclk->reg);
> + div++;
> + div *= 2;
> +
> + return parent_rate / div;
> +}
> +
> +static long clk_periclk_round_rate(struct clk_hw *clk, unsigned long rate,
> + unsigned long *unused)
> +{
> + unsigned long parent_rate = clk_get_rate(clk_get_parent(clk->clk));
> + u32 div;
> +
> + div = parent_rate / rate;
> + div++;
> + div &= ~0x1;
> +
> + return parent_rate / div;
> +}
> +
> +static int clk_periclk_set_rate(struct clk_hw *clk, unsigned long rate)
> +{
> + struct hb_clk *hbclk = to_hb_clk(clk);
> + u32 div;
> +
> + div = clk_get_rate(clk_get_parent(clk->clk)) / rate;
> + if (div & 0x1)
> + return -EINVAL;
> +
> + writel(div >> 1, hbclk->reg);
> + return 0;
> +}
> +
> +static const struct clk_ops periclk_ops = {
> + .recalc_rate = clk_periclk_recalc_rate,
> + .round_rate = clk_periclk_round_rate,
> + .set_rate = clk_periclk_set_rate,
> +};
> +
> +static void __init hb_clk_init(struct device_node *node, const struct clk_ops *ops)
> +{
> + u32 reg;
> + struct clk *clk;
> + struct hb_clk *hb_clk;
> + const char *clk_name = node->name;
> + int rc;
> +
> + rc = of_property_read_u32(node, "reg", ®);
> + if (WARN_ON(rc))
> + return;
> +
> + hb_clk = kzalloc(sizeof(*hb_clk), GFP_KERNEL);
> + if (WARN_ON(!hb_clk))
> + return;
> +
> + hb_clk->reg = sregs_base + reg;
> +
> + of_property_read_string(node, "clock-outputs", &clk_name);
> +
> + hb_clk->parent_name = of_clk_get_parent_name(node, 0);
> +
> + printk("registering clk %s, parent = %s\n", clk_name, hb_clk->parent_name);
> + clk = clk_register(NULL, clk_name, ops, &hb_clk->hw,
> + &hb_clk->parent_name, 1, 0);
> + if (WARN_ON(!clk)) {
> + kfree(hb_clk);
> + return;
> + }
> + rc = of_clk_add_provider(node, NULL, clk);
> +}
> +
> +static void __init hb_pll_init(struct device_node *node)
> +{
> + hb_clk_init(node, &clk_pll_ops);
> +}
> +
> +static void __init hb_a9periph_init(struct device_node *node)
> +{
> + hb_clk_init(node, &a9periphclk_ops);
> +}
> +
> +static void __init hb_a9bus_init(struct device_node *node)
> +{
> + hb_clk_init(node, &a9bclk_ops);
> +}
> +
> +static void __init hb_emmc_init(struct device_node *node)
> +{
> + hb_clk_init(node, &periclk_ops);
> +}
> +
> +static const __initconst struct of_device_id clk_match[] = {
> + { .compatible = "fixed-clock", .data = of_fixed_clk_setup, },
> + { .compatible = "calxeda,hb-pll-clock", .data = hb_pll_init, },
> + { .compatible = "calxeda,hb-a9periph-clock", .data = hb_a9periph_init, },
> + { .compatible = "calxeda,hb-a9bus-clock", .data = hb_a9bus_init, },
> + { .compatible = "calxeda,hb-emmc-clock", .data = hb_emmc_init, },
So that's the difference between your clock and mine. You do not reuse
any basic clk, except clk_fixed_rate, while my clocks are all about
basic clk except pll. That's why you need a long list of SoC specific
binding, while I do not. All I need is the binding for those basic
clks.
Regards,
Shawn
> + {}
> +};
> +
> +void __init highbank_clocks_init(void)
> +{
> + of_clk_init(clk_match);
> +}
More information about the devicetree-discuss
mailing list