162061d35SAlexandre Belloni // SPDX-License-Identifier: GPL-2.0
262061d35SAlexandre Belloni #include <linux/clk-provider.h>
362061d35SAlexandre Belloni #include <linux/clk/at91_pmc.h>
462061d35SAlexandre Belloni #include <linux/of.h>
562061d35SAlexandre Belloni #include <linux/mfd/syscon.h>
662061d35SAlexandre Belloni #include <linux/regmap.h>
762061d35SAlexandre Belloni #include <linux/slab.h>
862061d35SAlexandre Belloni
962061d35SAlexandre Belloni #include "pmc.h"
1062061d35SAlexandre Belloni
1162061d35SAlexandre Belloni #define MASTER_SOURCE_MAX 4
1262061d35SAlexandre Belloni
1362061d35SAlexandre Belloni #define PERIPHERAL_AT91RM9200 0
1462061d35SAlexandre Belloni #define PERIPHERAL_AT91SAM9X5 1
1562061d35SAlexandre Belloni
1662061d35SAlexandre Belloni #define PERIPHERAL_MAX 64
1762061d35SAlexandre Belloni
1862061d35SAlexandre Belloni #define PERIPHERAL_ID_MIN 2
1962061d35SAlexandre Belloni
2062061d35SAlexandre Belloni #define PROG_SOURCE_MAX 5
2162061d35SAlexandre Belloni #define PROG_ID_MAX 7
2262061d35SAlexandre Belloni
2362061d35SAlexandre Belloni #define SYSTEM_MAX_ID 31
2462061d35SAlexandre Belloni
2564c9247bSClaudiu Beznea #define GCK_INDEX_DT_AUDIO_PLL 5
2664c9247bSClaudiu Beznea
277a110b91SClaudiu Beznea static DEFINE_SPINLOCK(mck_lock);
287a110b91SClaudiu Beznea
2962061d35SAlexandre Belloni #ifdef CONFIG_HAVE_AT91_AUDIO_PLL
of_sama5d2_clk_audio_pll_frac_setup(struct device_node * np)3062061d35SAlexandre Belloni static void __init of_sama5d2_clk_audio_pll_frac_setup(struct device_node *np)
3162061d35SAlexandre Belloni {
3262061d35SAlexandre Belloni struct clk_hw *hw;
3362061d35SAlexandre Belloni const char *name = np->name;
3462061d35SAlexandre Belloni const char *parent_name;
3562061d35SAlexandre Belloni struct regmap *regmap;
36b3ff02c5SLiang He struct device_node *parent_np;
3762061d35SAlexandre Belloni
38b3ff02c5SLiang He parent_np = of_get_parent(np);
39b3ff02c5SLiang He regmap = syscon_node_to_regmap(parent_np);
40b3ff02c5SLiang He of_node_put(parent_np);
4162061d35SAlexandre Belloni if (IS_ERR(regmap))
4262061d35SAlexandre Belloni return;
4362061d35SAlexandre Belloni
4462061d35SAlexandre Belloni parent_name = of_clk_get_parent_name(np, 0);
4562061d35SAlexandre Belloni
4662061d35SAlexandre Belloni hw = at91_clk_register_audio_pll_frac(regmap, name, parent_name);
4762061d35SAlexandre Belloni if (IS_ERR(hw))
4862061d35SAlexandre Belloni return;
4962061d35SAlexandre Belloni
5062061d35SAlexandre Belloni of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
5162061d35SAlexandre Belloni }
5262061d35SAlexandre Belloni CLK_OF_DECLARE(of_sama5d2_clk_audio_pll_frac_setup,
5362061d35SAlexandre Belloni "atmel,sama5d2-clk-audio-pll-frac",
5462061d35SAlexandre Belloni of_sama5d2_clk_audio_pll_frac_setup);
5562061d35SAlexandre Belloni
of_sama5d2_clk_audio_pll_pad_setup(struct device_node * np)5662061d35SAlexandre Belloni static void __init of_sama5d2_clk_audio_pll_pad_setup(struct device_node *np)
5762061d35SAlexandre Belloni {
5862061d35SAlexandre Belloni struct clk_hw *hw;
5962061d35SAlexandre Belloni const char *name = np->name;
6062061d35SAlexandre Belloni const char *parent_name;
6162061d35SAlexandre Belloni struct regmap *regmap;
62b3ff02c5SLiang He struct device_node *parent_np;
6362061d35SAlexandre Belloni
64b3ff02c5SLiang He parent_np = of_get_parent(np);
65b3ff02c5SLiang He regmap = syscon_node_to_regmap(parent_np);
66b3ff02c5SLiang He of_node_put(parent_np);
6762061d35SAlexandre Belloni if (IS_ERR(regmap))
6862061d35SAlexandre Belloni return;
6962061d35SAlexandre Belloni
7062061d35SAlexandre Belloni parent_name = of_clk_get_parent_name(np, 0);
7162061d35SAlexandre Belloni
7262061d35SAlexandre Belloni hw = at91_clk_register_audio_pll_pad(regmap, name, parent_name);
7362061d35SAlexandre Belloni if (IS_ERR(hw))
7462061d35SAlexandre Belloni return;
7562061d35SAlexandre Belloni
7662061d35SAlexandre Belloni of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
7762061d35SAlexandre Belloni }
7862061d35SAlexandre Belloni CLK_OF_DECLARE(of_sama5d2_clk_audio_pll_pad_setup,
7962061d35SAlexandre Belloni "atmel,sama5d2-clk-audio-pll-pad",
8062061d35SAlexandre Belloni of_sama5d2_clk_audio_pll_pad_setup);
8162061d35SAlexandre Belloni
of_sama5d2_clk_audio_pll_pmc_setup(struct device_node * np)8262061d35SAlexandre Belloni static void __init of_sama5d2_clk_audio_pll_pmc_setup(struct device_node *np)
8362061d35SAlexandre Belloni {
8462061d35SAlexandre Belloni struct clk_hw *hw;
8562061d35SAlexandre Belloni const char *name = np->name;
8662061d35SAlexandre Belloni const char *parent_name;
8762061d35SAlexandre Belloni struct regmap *regmap;
88b3ff02c5SLiang He struct device_node *parent_np;
8962061d35SAlexandre Belloni
90b3ff02c5SLiang He parent_np = of_get_parent(np);
91b3ff02c5SLiang He regmap = syscon_node_to_regmap(parent_np);
92b3ff02c5SLiang He of_node_put(parent_np);
9362061d35SAlexandre Belloni if (IS_ERR(regmap))
9462061d35SAlexandre Belloni return;
9562061d35SAlexandre Belloni
9662061d35SAlexandre Belloni parent_name = of_clk_get_parent_name(np, 0);
9762061d35SAlexandre Belloni
9862061d35SAlexandre Belloni hw = at91_clk_register_audio_pll_pmc(regmap, name, parent_name);
9962061d35SAlexandre Belloni if (IS_ERR(hw))
10062061d35SAlexandre Belloni return;
10162061d35SAlexandre Belloni
10262061d35SAlexandre Belloni of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
10362061d35SAlexandre Belloni }
10462061d35SAlexandre Belloni CLK_OF_DECLARE(of_sama5d2_clk_audio_pll_pmc_setup,
10562061d35SAlexandre Belloni "atmel,sama5d2-clk-audio-pll-pmc",
10662061d35SAlexandre Belloni of_sama5d2_clk_audio_pll_pmc_setup);
10762061d35SAlexandre Belloni #endif /* CONFIG_HAVE_AT91_AUDIO_PLL */
10862061d35SAlexandre Belloni
109cb4f4949SAlexandre Belloni static const struct clk_pcr_layout dt_pcr_layout = {
110cb4f4949SAlexandre Belloni .offset = 0x10c,
111cb4f4949SAlexandre Belloni .cmd = BIT(12),
112cb4f4949SAlexandre Belloni .pid_mask = GENMASK(5, 0),
113cb4f4949SAlexandre Belloni .div_mask = GENMASK(17, 16),
114cb4f4949SAlexandre Belloni .gckcss_mask = GENMASK(10, 8),
115cb4f4949SAlexandre Belloni };
116cb4f4949SAlexandre Belloni
11762061d35SAlexandre Belloni #ifdef CONFIG_HAVE_AT91_GENERATED_CLK
11862061d35SAlexandre Belloni #define GENERATED_SOURCE_MAX 6
11962061d35SAlexandre Belloni
12062061d35SAlexandre Belloni #define GCK_ID_I2S0 54
12162061d35SAlexandre Belloni #define GCK_ID_I2S1 55
12262061d35SAlexandre Belloni #define GCK_ID_CLASSD 59
12362061d35SAlexandre Belloni
of_sama5d2_clk_generated_setup(struct device_node * np)12462061d35SAlexandre Belloni static void __init of_sama5d2_clk_generated_setup(struct device_node *np)
12562061d35SAlexandre Belloni {
12662061d35SAlexandre Belloni int num;
12762061d35SAlexandre Belloni u32 id;
12862061d35SAlexandre Belloni const char *name;
12962061d35SAlexandre Belloni struct clk_hw *hw;
13062061d35SAlexandre Belloni unsigned int num_parents;
13162061d35SAlexandre Belloni const char *parent_names[GENERATED_SOURCE_MAX];
132b3ff02c5SLiang He struct device_node *gcknp, *parent_np;
13362061d35SAlexandre Belloni struct clk_range range = CLK_RANGE(0, 0);
13462061d35SAlexandre Belloni struct regmap *regmap;
13562061d35SAlexandre Belloni
13662061d35SAlexandre Belloni num_parents = of_clk_get_parent_count(np);
13762061d35SAlexandre Belloni if (num_parents == 0 || num_parents > GENERATED_SOURCE_MAX)
13862061d35SAlexandre Belloni return;
13962061d35SAlexandre Belloni
14062061d35SAlexandre Belloni of_clk_parent_fill(np, parent_names, num_parents);
14162061d35SAlexandre Belloni
14262061d35SAlexandre Belloni num = of_get_child_count(np);
14362061d35SAlexandre Belloni if (!num || num > PERIPHERAL_MAX)
14462061d35SAlexandre Belloni return;
14562061d35SAlexandre Belloni
146b3ff02c5SLiang He parent_np = of_get_parent(np);
147b3ff02c5SLiang He regmap = syscon_node_to_regmap(parent_np);
148b3ff02c5SLiang He of_node_put(parent_np);
14962061d35SAlexandre Belloni if (IS_ERR(regmap))
15062061d35SAlexandre Belloni return;
15162061d35SAlexandre Belloni
15262061d35SAlexandre Belloni for_each_child_of_node(np, gcknp) {
15364c9247bSClaudiu Beznea int chg_pid = INT_MIN;
15462061d35SAlexandre Belloni
15562061d35SAlexandre Belloni if (of_property_read_u32(gcknp, "reg", &id))
15662061d35SAlexandre Belloni continue;
15762061d35SAlexandre Belloni
15862061d35SAlexandre Belloni if (id < PERIPHERAL_ID_MIN || id >= PERIPHERAL_MAX)
15962061d35SAlexandre Belloni continue;
16062061d35SAlexandre Belloni
16162061d35SAlexandre Belloni if (of_property_read_string(np, "clock-output-names", &name))
16262061d35SAlexandre Belloni name = gcknp->name;
16362061d35SAlexandre Belloni
16462061d35SAlexandre Belloni of_at91_get_clk_range(gcknp, "atmel,clk-output-range",
16562061d35SAlexandre Belloni &range);
16662061d35SAlexandre Belloni
16762061d35SAlexandre Belloni if (of_device_is_compatible(np, "atmel,sama5d2-clk-generated") &&
16862061d35SAlexandre Belloni (id == GCK_ID_I2S0 || id == GCK_ID_I2S1 ||
16962061d35SAlexandre Belloni id == GCK_ID_CLASSD))
17064c9247bSClaudiu Beznea chg_pid = GCK_INDEX_DT_AUDIO_PLL;
17162061d35SAlexandre Belloni
172e4cfb823SAlexandre Belloni hw = at91_clk_register_generated(regmap, &pmc_pcr_lock,
173e4cfb823SAlexandre Belloni &dt_pcr_layout, name,
17400bd581bSClaudiu Beznea parent_names, NULL, NULL,
17522a1dfe9SClaudiu Beznea num_parents, id, &range,
17622a1dfe9SClaudiu Beznea chg_pid);
17762061d35SAlexandre Belloni if (IS_ERR(hw))
17862061d35SAlexandre Belloni continue;
17962061d35SAlexandre Belloni
18062061d35SAlexandre Belloni of_clk_add_hw_provider(gcknp, of_clk_hw_simple_get, hw);
18162061d35SAlexandre Belloni }
18262061d35SAlexandre Belloni }
18362061d35SAlexandre Belloni CLK_OF_DECLARE(of_sama5d2_clk_generated_setup, "atmel,sama5d2-clk-generated",
18462061d35SAlexandre Belloni of_sama5d2_clk_generated_setup);
18562061d35SAlexandre Belloni #endif /* CONFIG_HAVE_AT91_GENERATED_CLK */
18662061d35SAlexandre Belloni
18762061d35SAlexandre Belloni #ifdef CONFIG_HAVE_AT91_H32MX
of_sama5d4_clk_h32mx_setup(struct device_node * np)18862061d35SAlexandre Belloni static void __init of_sama5d4_clk_h32mx_setup(struct device_node *np)
18962061d35SAlexandre Belloni {
19062061d35SAlexandre Belloni struct clk_hw *hw;
19162061d35SAlexandre Belloni const char *name = np->name;
19262061d35SAlexandre Belloni const char *parent_name;
19362061d35SAlexandre Belloni struct regmap *regmap;
194b3ff02c5SLiang He struct device_node *parent_np;
19562061d35SAlexandre Belloni
196b3ff02c5SLiang He parent_np = of_get_parent(np);
197b3ff02c5SLiang He regmap = syscon_node_to_regmap(parent_np);
198b3ff02c5SLiang He of_node_put(parent_np);
19962061d35SAlexandre Belloni if (IS_ERR(regmap))
20062061d35SAlexandre Belloni return;
20162061d35SAlexandre Belloni
20262061d35SAlexandre Belloni parent_name = of_clk_get_parent_name(np, 0);
20362061d35SAlexandre Belloni
20462061d35SAlexandre Belloni hw = at91_clk_register_h32mx(regmap, name, parent_name);
20562061d35SAlexandre Belloni if (IS_ERR(hw))
20662061d35SAlexandre Belloni return;
20762061d35SAlexandre Belloni
20862061d35SAlexandre Belloni of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
20962061d35SAlexandre Belloni }
21062061d35SAlexandre Belloni CLK_OF_DECLARE(of_sama5d4_clk_h32mx_setup, "atmel,sama5d4-clk-h32mx",
21162061d35SAlexandre Belloni of_sama5d4_clk_h32mx_setup);
21262061d35SAlexandre Belloni #endif /* CONFIG_HAVE_AT91_H32MX */
21362061d35SAlexandre Belloni
21462061d35SAlexandre Belloni #ifdef CONFIG_HAVE_AT91_I2S_MUX_CLK
21562061d35SAlexandre Belloni #define I2S_BUS_NR 2
21662061d35SAlexandre Belloni
of_sama5d2_clk_i2s_mux_setup(struct device_node * np)21762061d35SAlexandre Belloni static void __init of_sama5d2_clk_i2s_mux_setup(struct device_node *np)
21862061d35SAlexandre Belloni {
21962061d35SAlexandre Belloni struct regmap *regmap_sfr;
22062061d35SAlexandre Belloni u8 bus_id;
22162061d35SAlexandre Belloni const char *parent_names[2];
22262061d35SAlexandre Belloni struct device_node *i2s_mux_np;
22362061d35SAlexandre Belloni struct clk_hw *hw;
22462061d35SAlexandre Belloni int ret;
22562061d35SAlexandre Belloni
22662061d35SAlexandre Belloni regmap_sfr = syscon_regmap_lookup_by_compatible("atmel,sama5d2-sfr");
22762061d35SAlexandre Belloni if (IS_ERR(regmap_sfr))
22862061d35SAlexandre Belloni return;
22962061d35SAlexandre Belloni
23062061d35SAlexandre Belloni for_each_child_of_node(np, i2s_mux_np) {
23162061d35SAlexandre Belloni if (of_property_read_u8(i2s_mux_np, "reg", &bus_id))
23262061d35SAlexandre Belloni continue;
23362061d35SAlexandre Belloni
23462061d35SAlexandre Belloni if (bus_id > I2S_BUS_NR)
23562061d35SAlexandre Belloni continue;
23662061d35SAlexandre Belloni
23762061d35SAlexandre Belloni ret = of_clk_parent_fill(i2s_mux_np, parent_names, 2);
23862061d35SAlexandre Belloni if (ret != 2)
23962061d35SAlexandre Belloni continue;
24062061d35SAlexandre Belloni
24162061d35SAlexandre Belloni hw = at91_clk_i2s_mux_register(regmap_sfr, i2s_mux_np->name,
24262061d35SAlexandre Belloni parent_names, 2, bus_id);
24362061d35SAlexandre Belloni if (IS_ERR(hw))
24462061d35SAlexandre Belloni continue;
24562061d35SAlexandre Belloni
24662061d35SAlexandre Belloni of_clk_add_hw_provider(i2s_mux_np, of_clk_hw_simple_get, hw);
24762061d35SAlexandre Belloni }
24862061d35SAlexandre Belloni }
24962061d35SAlexandre Belloni CLK_OF_DECLARE(sama5d2_clk_i2s_mux, "atmel,sama5d2-clk-i2s-mux",
25062061d35SAlexandre Belloni of_sama5d2_clk_i2s_mux_setup);
25162061d35SAlexandre Belloni #endif /* CONFIG_HAVE_AT91_I2S_MUX_CLK */
25262061d35SAlexandre Belloni
of_at91rm9200_clk_main_osc_setup(struct device_node * np)25362061d35SAlexandre Belloni static void __init of_at91rm9200_clk_main_osc_setup(struct device_node *np)
25462061d35SAlexandre Belloni {
25562061d35SAlexandre Belloni struct clk_hw *hw;
25662061d35SAlexandre Belloni const char *name = np->name;
25762061d35SAlexandre Belloni const char *parent_name;
25862061d35SAlexandre Belloni struct regmap *regmap;
25962061d35SAlexandre Belloni bool bypass;
260b3ff02c5SLiang He struct device_node *parent_np;
26162061d35SAlexandre Belloni
26262061d35SAlexandre Belloni of_property_read_string(np, "clock-output-names", &name);
26362061d35SAlexandre Belloni bypass = of_property_read_bool(np, "atmel,osc-bypass");
26462061d35SAlexandre Belloni parent_name = of_clk_get_parent_name(np, 0);
26562061d35SAlexandre Belloni
266b3ff02c5SLiang He parent_np = of_get_parent(np);
267b3ff02c5SLiang He regmap = syscon_node_to_regmap(parent_np);
268b3ff02c5SLiang He of_node_put(parent_np);
26962061d35SAlexandre Belloni if (IS_ERR(regmap))
27062061d35SAlexandre Belloni return;
27162061d35SAlexandre Belloni
272b5105e37SClaudiu Beznea hw = at91_clk_register_main_osc(regmap, name, parent_name, NULL, bypass);
27362061d35SAlexandre Belloni if (IS_ERR(hw))
27462061d35SAlexandre Belloni return;
27562061d35SAlexandre Belloni
27662061d35SAlexandre Belloni of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
27762061d35SAlexandre Belloni }
27862061d35SAlexandre Belloni CLK_OF_DECLARE(at91rm9200_clk_main_osc, "atmel,at91rm9200-clk-main-osc",
27962061d35SAlexandre Belloni of_at91rm9200_clk_main_osc_setup);
28062061d35SAlexandre Belloni
of_at91sam9x5_clk_main_rc_osc_setup(struct device_node * np)28162061d35SAlexandre Belloni static void __init of_at91sam9x5_clk_main_rc_osc_setup(struct device_node *np)
28262061d35SAlexandre Belloni {
28362061d35SAlexandre Belloni struct clk_hw *hw;
28462061d35SAlexandre Belloni u32 frequency = 0;
28562061d35SAlexandre Belloni u32 accuracy = 0;
28662061d35SAlexandre Belloni const char *name = np->name;
28762061d35SAlexandre Belloni struct regmap *regmap;
288b3ff02c5SLiang He struct device_node *parent_np;
28962061d35SAlexandre Belloni
29062061d35SAlexandre Belloni of_property_read_string(np, "clock-output-names", &name);
29162061d35SAlexandre Belloni of_property_read_u32(np, "clock-frequency", &frequency);
29262061d35SAlexandre Belloni of_property_read_u32(np, "clock-accuracy", &accuracy);
29362061d35SAlexandre Belloni
294b3ff02c5SLiang He parent_np = of_get_parent(np);
295b3ff02c5SLiang He regmap = syscon_node_to_regmap(parent_np);
296b3ff02c5SLiang He of_node_put(parent_np);
29762061d35SAlexandre Belloni if (IS_ERR(regmap))
29862061d35SAlexandre Belloni return;
29962061d35SAlexandre Belloni
30062061d35SAlexandre Belloni hw = at91_clk_register_main_rc_osc(regmap, name, frequency, accuracy);
30162061d35SAlexandre Belloni if (IS_ERR(hw))
30262061d35SAlexandre Belloni return;
30362061d35SAlexandre Belloni
30462061d35SAlexandre Belloni of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
30562061d35SAlexandre Belloni }
30662061d35SAlexandre Belloni CLK_OF_DECLARE(at91sam9x5_clk_main_rc_osc, "atmel,at91sam9x5-clk-main-rc-osc",
30762061d35SAlexandre Belloni of_at91sam9x5_clk_main_rc_osc_setup);
30862061d35SAlexandre Belloni
of_at91rm9200_clk_main_setup(struct device_node * np)30962061d35SAlexandre Belloni static void __init of_at91rm9200_clk_main_setup(struct device_node *np)
31062061d35SAlexandre Belloni {
31162061d35SAlexandre Belloni struct clk_hw *hw;
31262061d35SAlexandre Belloni const char *parent_name;
31362061d35SAlexandre Belloni const char *name = np->name;
31462061d35SAlexandre Belloni struct regmap *regmap;
315b3ff02c5SLiang He struct device_node *parent_np;
31662061d35SAlexandre Belloni
31762061d35SAlexandre Belloni parent_name = of_clk_get_parent_name(np, 0);
31862061d35SAlexandre Belloni of_property_read_string(np, "clock-output-names", &name);
31962061d35SAlexandre Belloni
320b3ff02c5SLiang He parent_np = of_get_parent(np);
321b3ff02c5SLiang He regmap = syscon_node_to_regmap(parent_np);
322b3ff02c5SLiang He of_node_put(parent_np);
32362061d35SAlexandre Belloni if (IS_ERR(regmap))
32462061d35SAlexandre Belloni return;
32562061d35SAlexandre Belloni
326b5105e37SClaudiu Beznea hw = at91_clk_register_rm9200_main(regmap, name, parent_name, NULL);
32762061d35SAlexandre Belloni if (IS_ERR(hw))
32862061d35SAlexandre Belloni return;
32962061d35SAlexandre Belloni
33062061d35SAlexandre Belloni of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
33162061d35SAlexandre Belloni }
33262061d35SAlexandre Belloni CLK_OF_DECLARE(at91rm9200_clk_main, "atmel,at91rm9200-clk-main",
33362061d35SAlexandre Belloni of_at91rm9200_clk_main_setup);
33462061d35SAlexandre Belloni
of_at91sam9x5_clk_main_setup(struct device_node * np)33562061d35SAlexandre Belloni static void __init of_at91sam9x5_clk_main_setup(struct device_node *np)
33662061d35SAlexandre Belloni {
33762061d35SAlexandre Belloni struct clk_hw *hw;
33862061d35SAlexandre Belloni const char *parent_names[2];
33962061d35SAlexandre Belloni unsigned int num_parents;
34062061d35SAlexandre Belloni const char *name = np->name;
34162061d35SAlexandre Belloni struct regmap *regmap;
342b3ff02c5SLiang He struct device_node *parent_np;
34362061d35SAlexandre Belloni
34462061d35SAlexandre Belloni num_parents = of_clk_get_parent_count(np);
34562061d35SAlexandre Belloni if (num_parents == 0 || num_parents > 2)
34662061d35SAlexandre Belloni return;
34762061d35SAlexandre Belloni
34862061d35SAlexandre Belloni of_clk_parent_fill(np, parent_names, num_parents);
349b3ff02c5SLiang He parent_np = of_get_parent(np);
350b3ff02c5SLiang He regmap = syscon_node_to_regmap(parent_np);
351b3ff02c5SLiang He of_node_put(parent_np);
35262061d35SAlexandre Belloni if (IS_ERR(regmap))
35362061d35SAlexandre Belloni return;
35462061d35SAlexandre Belloni
35562061d35SAlexandre Belloni of_property_read_string(np, "clock-output-names", &name);
35662061d35SAlexandre Belloni
357b5105e37SClaudiu Beznea hw = at91_clk_register_sam9x5_main(regmap, name, parent_names, NULL,
35862061d35SAlexandre Belloni num_parents);
35962061d35SAlexandre Belloni if (IS_ERR(hw))
36062061d35SAlexandre Belloni return;
36162061d35SAlexandre Belloni
36262061d35SAlexandre Belloni of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
36362061d35SAlexandre Belloni }
36462061d35SAlexandre Belloni CLK_OF_DECLARE(at91sam9x5_clk_main, "atmel,at91sam9x5-clk-main",
36562061d35SAlexandre Belloni of_at91sam9x5_clk_main_setup);
36662061d35SAlexandre Belloni
36762061d35SAlexandre Belloni static struct clk_master_characteristics * __init
of_at91_clk_master_get_characteristics(struct device_node * np)36862061d35SAlexandre Belloni of_at91_clk_master_get_characteristics(struct device_node *np)
36962061d35SAlexandre Belloni {
37062061d35SAlexandre Belloni struct clk_master_characteristics *characteristics;
37162061d35SAlexandre Belloni
37262061d35SAlexandre Belloni characteristics = kzalloc(sizeof(*characteristics), GFP_KERNEL);
37362061d35SAlexandre Belloni if (!characteristics)
37462061d35SAlexandre Belloni return NULL;
37562061d35SAlexandre Belloni
37662061d35SAlexandre Belloni if (of_at91_get_clk_range(np, "atmel,clk-output-range", &characteristics->output))
37762061d35SAlexandre Belloni goto out_free_characteristics;
37862061d35SAlexandre Belloni
37962061d35SAlexandre Belloni of_property_read_u32_array(np, "atmel,clk-divisors",
38062061d35SAlexandre Belloni characteristics->divisors, 4);
38162061d35SAlexandre Belloni
38262061d35SAlexandre Belloni characteristics->have_div3_pres =
38362061d35SAlexandre Belloni of_property_read_bool(np, "atmel,master-clk-have-div3-pres");
38462061d35SAlexandre Belloni
38562061d35SAlexandre Belloni return characteristics;
38662061d35SAlexandre Belloni
38762061d35SAlexandre Belloni out_free_characteristics:
38862061d35SAlexandre Belloni kfree(characteristics);
38962061d35SAlexandre Belloni return NULL;
39062061d35SAlexandre Belloni }
39162061d35SAlexandre Belloni
39262061d35SAlexandre Belloni static void __init
of_at91_clk_master_setup(struct device_node * np,const struct clk_master_layout * layout)39362061d35SAlexandre Belloni of_at91_clk_master_setup(struct device_node *np,
39462061d35SAlexandre Belloni const struct clk_master_layout *layout)
39562061d35SAlexandre Belloni {
39662061d35SAlexandre Belloni struct clk_hw *hw;
39762061d35SAlexandre Belloni unsigned int num_parents;
39862061d35SAlexandre Belloni const char *parent_names[MASTER_SOURCE_MAX];
39962061d35SAlexandre Belloni const char *name = np->name;
40062061d35SAlexandre Belloni struct clk_master_characteristics *characteristics;
40162061d35SAlexandre Belloni struct regmap *regmap;
402b3ff02c5SLiang He struct device_node *parent_np;
40362061d35SAlexandre Belloni
40462061d35SAlexandre Belloni num_parents = of_clk_get_parent_count(np);
40562061d35SAlexandre Belloni if (num_parents == 0 || num_parents > MASTER_SOURCE_MAX)
40662061d35SAlexandre Belloni return;
40762061d35SAlexandre Belloni
40862061d35SAlexandre Belloni of_clk_parent_fill(np, parent_names, num_parents);
40962061d35SAlexandre Belloni
41062061d35SAlexandre Belloni of_property_read_string(np, "clock-output-names", &name);
41162061d35SAlexandre Belloni
41262061d35SAlexandre Belloni characteristics = of_at91_clk_master_get_characteristics(np);
41362061d35SAlexandre Belloni if (!characteristics)
41462061d35SAlexandre Belloni return;
41562061d35SAlexandre Belloni
416b3ff02c5SLiang He parent_np = of_get_parent(np);
417b3ff02c5SLiang He regmap = syscon_node_to_regmap(parent_np);
418b3ff02c5SLiang He of_node_put(parent_np);
41962061d35SAlexandre Belloni if (IS_ERR(regmap))
42062061d35SAlexandre Belloni return;
42162061d35SAlexandre Belloni
4227a110b91SClaudiu Beznea hw = at91_clk_register_master_pres(regmap, "masterck_pres", num_parents,
423171e502cSClaudiu Beznea parent_names, NULL, layout,
4248e842f02SClaudiu Beznea characteristics, &mck_lock);
4257a110b91SClaudiu Beznea if (IS_ERR(hw))
4267a110b91SClaudiu Beznea goto out_free_characteristics;
4277a110b91SClaudiu Beznea
428171e502cSClaudiu Beznea hw = at91_clk_register_master_div(regmap, name, "masterck_pres", NULL,
4297a110b91SClaudiu Beznea layout, characteristics,
4307029db09SClaudiu Beznea &mck_lock, CLK_SET_RATE_GATE, 0);
43162061d35SAlexandre Belloni if (IS_ERR(hw))
43262061d35SAlexandre Belloni goto out_free_characteristics;
43362061d35SAlexandre Belloni
43462061d35SAlexandre Belloni of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
43562061d35SAlexandre Belloni return;
43662061d35SAlexandre Belloni
43762061d35SAlexandre Belloni out_free_characteristics:
43862061d35SAlexandre Belloni kfree(characteristics);
43962061d35SAlexandre Belloni }
44062061d35SAlexandre Belloni
of_at91rm9200_clk_master_setup(struct device_node * np)44162061d35SAlexandre Belloni static void __init of_at91rm9200_clk_master_setup(struct device_node *np)
44262061d35SAlexandre Belloni {
44362061d35SAlexandre Belloni of_at91_clk_master_setup(np, &at91rm9200_master_layout);
44462061d35SAlexandre Belloni }
44562061d35SAlexandre Belloni CLK_OF_DECLARE(at91rm9200_clk_master, "atmel,at91rm9200-clk-master",
44662061d35SAlexandre Belloni of_at91rm9200_clk_master_setup);
44762061d35SAlexandre Belloni
of_at91sam9x5_clk_master_setup(struct device_node * np)44862061d35SAlexandre Belloni static void __init of_at91sam9x5_clk_master_setup(struct device_node *np)
44962061d35SAlexandre Belloni {
45062061d35SAlexandre Belloni of_at91_clk_master_setup(np, &at91sam9x5_master_layout);
45162061d35SAlexandre Belloni }
45262061d35SAlexandre Belloni CLK_OF_DECLARE(at91sam9x5_clk_master, "atmel,at91sam9x5-clk-master",
45362061d35SAlexandre Belloni of_at91sam9x5_clk_master_setup);
45462061d35SAlexandre Belloni
45562061d35SAlexandre Belloni static void __init
of_at91_clk_periph_setup(struct device_node * np,u8 type)45662061d35SAlexandre Belloni of_at91_clk_periph_setup(struct device_node *np, u8 type)
45762061d35SAlexandre Belloni {
45862061d35SAlexandre Belloni int num;
45962061d35SAlexandre Belloni u32 id;
46062061d35SAlexandre Belloni struct clk_hw *hw;
46162061d35SAlexandre Belloni const char *parent_name;
46262061d35SAlexandre Belloni const char *name;
46362061d35SAlexandre Belloni struct device_node *periphclknp;
46462061d35SAlexandre Belloni struct regmap *regmap;
465b3ff02c5SLiang He struct device_node *parent_np;
46662061d35SAlexandre Belloni
46762061d35SAlexandre Belloni parent_name = of_clk_get_parent_name(np, 0);
46862061d35SAlexandre Belloni if (!parent_name)
46962061d35SAlexandre Belloni return;
47062061d35SAlexandre Belloni
47162061d35SAlexandre Belloni num = of_get_child_count(np);
47262061d35SAlexandre Belloni if (!num || num > PERIPHERAL_MAX)
47362061d35SAlexandre Belloni return;
47462061d35SAlexandre Belloni
475b3ff02c5SLiang He parent_np = of_get_parent(np);
476b3ff02c5SLiang He regmap = syscon_node_to_regmap(parent_np);
477b3ff02c5SLiang He of_node_put(parent_np);
47862061d35SAlexandre Belloni if (IS_ERR(regmap))
47962061d35SAlexandre Belloni return;
48062061d35SAlexandre Belloni
48162061d35SAlexandre Belloni for_each_child_of_node(np, periphclknp) {
48262061d35SAlexandre Belloni if (of_property_read_u32(periphclknp, "reg", &id))
48362061d35SAlexandre Belloni continue;
48462061d35SAlexandre Belloni
48562061d35SAlexandre Belloni if (id >= PERIPHERAL_MAX)
48662061d35SAlexandre Belloni continue;
48762061d35SAlexandre Belloni
48862061d35SAlexandre Belloni if (of_property_read_string(np, "clock-output-names", &name))
48962061d35SAlexandre Belloni name = periphclknp->name;
49062061d35SAlexandre Belloni
49162061d35SAlexandre Belloni if (type == PERIPHERAL_AT91RM9200) {
49262061d35SAlexandre Belloni hw = at91_clk_register_peripheral(regmap, name,
493c2f2ca0bSClaudiu Beznea parent_name, NULL, id);
49462061d35SAlexandre Belloni } else {
49562061d35SAlexandre Belloni struct clk_range range = CLK_RANGE(0, 0);
49668b3b6f1SClaudiu Beznea unsigned long flags = 0;
49762061d35SAlexandre Belloni
49862061d35SAlexandre Belloni of_at91_get_clk_range(periphclknp,
49962061d35SAlexandre Belloni "atmel,clk-output-range",
50062061d35SAlexandre Belloni &range);
50162061d35SAlexandre Belloni
50268b3b6f1SClaudiu Beznea /*
50368b3b6f1SClaudiu Beznea * mpddr_clk feed DDR controller and is enabled by
50468b3b6f1SClaudiu Beznea * bootloader thus we need to keep it enabled in case
50568b3b6f1SClaudiu Beznea * there is no Linux consumer for it.
50668b3b6f1SClaudiu Beznea */
50768b3b6f1SClaudiu Beznea if (!strcmp(periphclknp->name, "mpddr_clk"))
50868b3b6f1SClaudiu Beznea flags = CLK_IS_CRITICAL;
50968b3b6f1SClaudiu Beznea
51062061d35SAlexandre Belloni hw = at91_clk_register_sam9x5_peripheral(regmap,
51162061d35SAlexandre Belloni &pmc_pcr_lock,
512cb4f4949SAlexandre Belloni &dt_pcr_layout,
51362061d35SAlexandre Belloni name,
51462061d35SAlexandre Belloni parent_name,
515c2f2ca0bSClaudiu Beznea NULL,
516b4c115c7SClaudiu Beznea id, &range,
51768b3b6f1SClaudiu Beznea INT_MIN,
51868b3b6f1SClaudiu Beznea flags);
51962061d35SAlexandre Belloni }
52062061d35SAlexandre Belloni
52162061d35SAlexandre Belloni if (IS_ERR(hw))
52262061d35SAlexandre Belloni continue;
52362061d35SAlexandre Belloni
52462061d35SAlexandre Belloni of_clk_add_hw_provider(periphclknp, of_clk_hw_simple_get, hw);
52562061d35SAlexandre Belloni }
52662061d35SAlexandre Belloni }
52762061d35SAlexandre Belloni
of_at91rm9200_clk_periph_setup(struct device_node * np)52862061d35SAlexandre Belloni static void __init of_at91rm9200_clk_periph_setup(struct device_node *np)
52962061d35SAlexandre Belloni {
53062061d35SAlexandre Belloni of_at91_clk_periph_setup(np, PERIPHERAL_AT91RM9200);
53162061d35SAlexandre Belloni }
53262061d35SAlexandre Belloni CLK_OF_DECLARE(at91rm9200_clk_periph, "atmel,at91rm9200-clk-peripheral",
53362061d35SAlexandre Belloni of_at91rm9200_clk_periph_setup);
53462061d35SAlexandre Belloni
of_at91sam9x5_clk_periph_setup(struct device_node * np)53562061d35SAlexandre Belloni static void __init of_at91sam9x5_clk_periph_setup(struct device_node *np)
53662061d35SAlexandre Belloni {
53762061d35SAlexandre Belloni of_at91_clk_periph_setup(np, PERIPHERAL_AT91SAM9X5);
53862061d35SAlexandre Belloni }
53962061d35SAlexandre Belloni CLK_OF_DECLARE(at91sam9x5_clk_periph, "atmel,at91sam9x5-clk-peripheral",
54062061d35SAlexandre Belloni of_at91sam9x5_clk_periph_setup);
54162061d35SAlexandre Belloni
54262061d35SAlexandre Belloni static struct clk_pll_characteristics * __init
of_at91_clk_pll_get_characteristics(struct device_node * np)54362061d35SAlexandre Belloni of_at91_clk_pll_get_characteristics(struct device_node *np)
54462061d35SAlexandre Belloni {
54562061d35SAlexandre Belloni int i;
54662061d35SAlexandre Belloni int offset;
54762061d35SAlexandre Belloni u32 tmp;
54862061d35SAlexandre Belloni int num_output;
54962061d35SAlexandre Belloni u32 num_cells;
55062061d35SAlexandre Belloni struct clk_range input;
55162061d35SAlexandre Belloni struct clk_range *output;
55262061d35SAlexandre Belloni u8 *out = NULL;
55362061d35SAlexandre Belloni u16 *icpll = NULL;
55462061d35SAlexandre Belloni struct clk_pll_characteristics *characteristics;
55562061d35SAlexandre Belloni
55662061d35SAlexandre Belloni if (of_at91_get_clk_range(np, "atmel,clk-input-range", &input))
55762061d35SAlexandre Belloni return NULL;
55862061d35SAlexandre Belloni
55962061d35SAlexandre Belloni if (of_property_read_u32(np, "#atmel,pll-clk-output-range-cells",
56062061d35SAlexandre Belloni &num_cells))
56162061d35SAlexandre Belloni return NULL;
56262061d35SAlexandre Belloni
56362061d35SAlexandre Belloni if (num_cells < 2 || num_cells > 4)
56462061d35SAlexandre Belloni return NULL;
56562061d35SAlexandre Belloni
56662061d35SAlexandre Belloni if (!of_get_property(np, "atmel,pll-clk-output-ranges", &tmp))
56762061d35SAlexandre Belloni return NULL;
56862061d35SAlexandre Belloni num_output = tmp / (sizeof(u32) * num_cells);
56962061d35SAlexandre Belloni
57062061d35SAlexandre Belloni characteristics = kzalloc(sizeof(*characteristics), GFP_KERNEL);
57162061d35SAlexandre Belloni if (!characteristics)
57262061d35SAlexandre Belloni return NULL;
57362061d35SAlexandre Belloni
57462061d35SAlexandre Belloni output = kcalloc(num_output, sizeof(*output), GFP_KERNEL);
57562061d35SAlexandre Belloni if (!output)
57662061d35SAlexandre Belloni goto out_free_characteristics;
57762061d35SAlexandre Belloni
57862061d35SAlexandre Belloni if (num_cells > 2) {
57962061d35SAlexandre Belloni out = kcalloc(num_output, sizeof(*out), GFP_KERNEL);
58062061d35SAlexandre Belloni if (!out)
58162061d35SAlexandre Belloni goto out_free_output;
58262061d35SAlexandre Belloni }
58362061d35SAlexandre Belloni
58462061d35SAlexandre Belloni if (num_cells > 3) {
58562061d35SAlexandre Belloni icpll = kcalloc(num_output, sizeof(*icpll), GFP_KERNEL);
58662061d35SAlexandre Belloni if (!icpll)
58762061d35SAlexandre Belloni goto out_free_output;
58862061d35SAlexandre Belloni }
58962061d35SAlexandre Belloni
59062061d35SAlexandre Belloni for (i = 0; i < num_output; i++) {
59162061d35SAlexandre Belloni offset = i * num_cells;
59262061d35SAlexandre Belloni if (of_property_read_u32_index(np,
59362061d35SAlexandre Belloni "atmel,pll-clk-output-ranges",
59462061d35SAlexandre Belloni offset, &tmp))
59562061d35SAlexandre Belloni goto out_free_output;
59662061d35SAlexandre Belloni output[i].min = tmp;
59762061d35SAlexandre Belloni if (of_property_read_u32_index(np,
59862061d35SAlexandre Belloni "atmel,pll-clk-output-ranges",
59962061d35SAlexandre Belloni offset + 1, &tmp))
60062061d35SAlexandre Belloni goto out_free_output;
60162061d35SAlexandre Belloni output[i].max = tmp;
60262061d35SAlexandre Belloni
60362061d35SAlexandre Belloni if (num_cells == 2)
60462061d35SAlexandre Belloni continue;
60562061d35SAlexandre Belloni
60662061d35SAlexandre Belloni if (of_property_read_u32_index(np,
60762061d35SAlexandre Belloni "atmel,pll-clk-output-ranges",
60862061d35SAlexandre Belloni offset + 2, &tmp))
60962061d35SAlexandre Belloni goto out_free_output;
61062061d35SAlexandre Belloni out[i] = tmp;
61162061d35SAlexandre Belloni
61262061d35SAlexandre Belloni if (num_cells == 3)
61362061d35SAlexandre Belloni continue;
61462061d35SAlexandre Belloni
61562061d35SAlexandre Belloni if (of_property_read_u32_index(np,
61662061d35SAlexandre Belloni "atmel,pll-clk-output-ranges",
61762061d35SAlexandre Belloni offset + 3, &tmp))
61862061d35SAlexandre Belloni goto out_free_output;
61962061d35SAlexandre Belloni icpll[i] = tmp;
62062061d35SAlexandre Belloni }
62162061d35SAlexandre Belloni
62262061d35SAlexandre Belloni characteristics->input = input;
62362061d35SAlexandre Belloni characteristics->num_output = num_output;
62462061d35SAlexandre Belloni characteristics->output = output;
62562061d35SAlexandre Belloni characteristics->out = out;
62662061d35SAlexandre Belloni characteristics->icpll = icpll;
62762061d35SAlexandre Belloni return characteristics;
62862061d35SAlexandre Belloni
62962061d35SAlexandre Belloni out_free_output:
63062061d35SAlexandre Belloni kfree(icpll);
63162061d35SAlexandre Belloni kfree(out);
63262061d35SAlexandre Belloni kfree(output);
63362061d35SAlexandre Belloni out_free_characteristics:
63462061d35SAlexandre Belloni kfree(characteristics);
63562061d35SAlexandre Belloni return NULL;
63662061d35SAlexandre Belloni }
63762061d35SAlexandre Belloni
63862061d35SAlexandre Belloni static void __init
of_at91_clk_pll_setup(struct device_node * np,const struct clk_pll_layout * layout)63962061d35SAlexandre Belloni of_at91_clk_pll_setup(struct device_node *np,
64062061d35SAlexandre Belloni const struct clk_pll_layout *layout)
64162061d35SAlexandre Belloni {
64262061d35SAlexandre Belloni u32 id;
64362061d35SAlexandre Belloni struct clk_hw *hw;
64462061d35SAlexandre Belloni struct regmap *regmap;
64562061d35SAlexandre Belloni const char *parent_name;
64662061d35SAlexandre Belloni const char *name = np->name;
647b3ff02c5SLiang He struct device_node *parent_np;
64862061d35SAlexandre Belloni struct clk_pll_characteristics *characteristics;
64962061d35SAlexandre Belloni
65062061d35SAlexandre Belloni if (of_property_read_u32(np, "reg", &id))
65162061d35SAlexandre Belloni return;
65262061d35SAlexandre Belloni
65362061d35SAlexandre Belloni parent_name = of_clk_get_parent_name(np, 0);
65462061d35SAlexandre Belloni
65562061d35SAlexandre Belloni of_property_read_string(np, "clock-output-names", &name);
65662061d35SAlexandre Belloni
657b3ff02c5SLiang He parent_np = of_get_parent(np);
658b3ff02c5SLiang He regmap = syscon_node_to_regmap(parent_np);
659b3ff02c5SLiang He of_node_put(parent_np);
66062061d35SAlexandre Belloni if (IS_ERR(regmap))
66162061d35SAlexandre Belloni return;
66262061d35SAlexandre Belloni
66362061d35SAlexandre Belloni characteristics = of_at91_clk_pll_get_characteristics(np);
66462061d35SAlexandre Belloni if (!characteristics)
66562061d35SAlexandre Belloni return;
66662061d35SAlexandre Belloni
66762061d35SAlexandre Belloni hw = at91_clk_register_pll(regmap, name, parent_name, id, layout,
66862061d35SAlexandre Belloni characteristics);
66962061d35SAlexandre Belloni if (IS_ERR(hw))
67062061d35SAlexandre Belloni goto out_free_characteristics;
67162061d35SAlexandre Belloni
67262061d35SAlexandre Belloni of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
67362061d35SAlexandre Belloni return;
67462061d35SAlexandre Belloni
67562061d35SAlexandre Belloni out_free_characteristics:
67662061d35SAlexandre Belloni kfree(characteristics);
67762061d35SAlexandre Belloni }
67862061d35SAlexandre Belloni
of_at91rm9200_clk_pll_setup(struct device_node * np)67962061d35SAlexandre Belloni static void __init of_at91rm9200_clk_pll_setup(struct device_node *np)
68062061d35SAlexandre Belloni {
68162061d35SAlexandre Belloni of_at91_clk_pll_setup(np, &at91rm9200_pll_layout);
68262061d35SAlexandre Belloni }
68362061d35SAlexandre Belloni CLK_OF_DECLARE(at91rm9200_clk_pll, "atmel,at91rm9200-clk-pll",
68462061d35SAlexandre Belloni of_at91rm9200_clk_pll_setup);
68562061d35SAlexandre Belloni
of_at91sam9g45_clk_pll_setup(struct device_node * np)68662061d35SAlexandre Belloni static void __init of_at91sam9g45_clk_pll_setup(struct device_node *np)
68762061d35SAlexandre Belloni {
68862061d35SAlexandre Belloni of_at91_clk_pll_setup(np, &at91sam9g45_pll_layout);
68962061d35SAlexandre Belloni }
69062061d35SAlexandre Belloni CLK_OF_DECLARE(at91sam9g45_clk_pll, "atmel,at91sam9g45-clk-pll",
69162061d35SAlexandre Belloni of_at91sam9g45_clk_pll_setup);
69262061d35SAlexandre Belloni
of_at91sam9g20_clk_pllb_setup(struct device_node * np)69362061d35SAlexandre Belloni static void __init of_at91sam9g20_clk_pllb_setup(struct device_node *np)
69462061d35SAlexandre Belloni {
69562061d35SAlexandre Belloni of_at91_clk_pll_setup(np, &at91sam9g20_pllb_layout);
69662061d35SAlexandre Belloni }
69762061d35SAlexandre Belloni CLK_OF_DECLARE(at91sam9g20_clk_pllb, "atmel,at91sam9g20-clk-pllb",
69862061d35SAlexandre Belloni of_at91sam9g20_clk_pllb_setup);
69962061d35SAlexandre Belloni
of_sama5d3_clk_pll_setup(struct device_node * np)70062061d35SAlexandre Belloni static void __init of_sama5d3_clk_pll_setup(struct device_node *np)
70162061d35SAlexandre Belloni {
70262061d35SAlexandre Belloni of_at91_clk_pll_setup(np, &sama5d3_pll_layout);
70362061d35SAlexandre Belloni }
70462061d35SAlexandre Belloni CLK_OF_DECLARE(sama5d3_clk_pll, "atmel,sama5d3-clk-pll",
70562061d35SAlexandre Belloni of_sama5d3_clk_pll_setup);
70662061d35SAlexandre Belloni
70762061d35SAlexandre Belloni static void __init
of_at91sam9x5_clk_plldiv_setup(struct device_node * np)70862061d35SAlexandre Belloni of_at91sam9x5_clk_plldiv_setup(struct device_node *np)
70962061d35SAlexandre Belloni {
71062061d35SAlexandre Belloni struct clk_hw *hw;
71162061d35SAlexandre Belloni const char *parent_name;
71262061d35SAlexandre Belloni const char *name = np->name;
71362061d35SAlexandre Belloni struct regmap *regmap;
714b3ff02c5SLiang He struct device_node *parent_np;
71562061d35SAlexandre Belloni
71662061d35SAlexandre Belloni parent_name = of_clk_get_parent_name(np, 0);
71762061d35SAlexandre Belloni
71862061d35SAlexandre Belloni of_property_read_string(np, "clock-output-names", &name);
71962061d35SAlexandre Belloni
720b3ff02c5SLiang He parent_np = of_get_parent(np);
721b3ff02c5SLiang He regmap = syscon_node_to_regmap(parent_np);
722b3ff02c5SLiang He of_node_put(parent_np);
72362061d35SAlexandre Belloni if (IS_ERR(regmap))
72462061d35SAlexandre Belloni return;
72562061d35SAlexandre Belloni
72662061d35SAlexandre Belloni hw = at91_clk_register_plldiv(regmap, name, parent_name);
72762061d35SAlexandre Belloni if (IS_ERR(hw))
72862061d35SAlexandre Belloni return;
72962061d35SAlexandre Belloni
73062061d35SAlexandre Belloni of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
73162061d35SAlexandre Belloni }
73262061d35SAlexandre Belloni CLK_OF_DECLARE(at91sam9x5_clk_plldiv, "atmel,at91sam9x5-clk-plldiv",
73362061d35SAlexandre Belloni of_at91sam9x5_clk_plldiv_setup);
73462061d35SAlexandre Belloni
73562061d35SAlexandre Belloni static void __init
of_at91_clk_prog_setup(struct device_node * np,const struct clk_programmable_layout * layout,u32 * mux_table)73662061d35SAlexandre Belloni of_at91_clk_prog_setup(struct device_node *np,
737c57aaaa2SClaudiu Beznea const struct clk_programmable_layout *layout,
738c57aaaa2SClaudiu Beznea u32 *mux_table)
73962061d35SAlexandre Belloni {
74062061d35SAlexandre Belloni int num;
74162061d35SAlexandre Belloni u32 id;
74262061d35SAlexandre Belloni struct clk_hw *hw;
74362061d35SAlexandre Belloni unsigned int num_parents;
74462061d35SAlexandre Belloni const char *parent_names[PROG_SOURCE_MAX];
74562061d35SAlexandre Belloni const char *name;
746b3ff02c5SLiang He struct device_node *progclknp, *parent_np;
74762061d35SAlexandre Belloni struct regmap *regmap;
74862061d35SAlexandre Belloni
74962061d35SAlexandre Belloni num_parents = of_clk_get_parent_count(np);
75062061d35SAlexandre Belloni if (num_parents == 0 || num_parents > PROG_SOURCE_MAX)
75162061d35SAlexandre Belloni return;
75262061d35SAlexandre Belloni
75362061d35SAlexandre Belloni of_clk_parent_fill(np, parent_names, num_parents);
75462061d35SAlexandre Belloni
75562061d35SAlexandre Belloni num = of_get_child_count(np);
75662061d35SAlexandre Belloni if (!num || num > (PROG_ID_MAX + 1))
75762061d35SAlexandre Belloni return;
75862061d35SAlexandre Belloni
759b3ff02c5SLiang He parent_np = of_get_parent(np);
760b3ff02c5SLiang He regmap = syscon_node_to_regmap(parent_np);
761b3ff02c5SLiang He of_node_put(parent_np);
76262061d35SAlexandre Belloni if (IS_ERR(regmap))
76362061d35SAlexandre Belloni return;
76462061d35SAlexandre Belloni
76562061d35SAlexandre Belloni for_each_child_of_node(np, progclknp) {
76662061d35SAlexandre Belloni if (of_property_read_u32(progclknp, "reg", &id))
76762061d35SAlexandre Belloni continue;
76862061d35SAlexandre Belloni
76962061d35SAlexandre Belloni if (of_property_read_string(np, "clock-output-names", &name))
77062061d35SAlexandre Belloni name = progclknp->name;
77162061d35SAlexandre Belloni
77262061d35SAlexandre Belloni hw = at91_clk_register_programmable(regmap, name,
7731a2669dfSClaudiu Beznea parent_names, NULL, num_parents,
774c57aaaa2SClaudiu Beznea id, layout, mux_table);
77562061d35SAlexandre Belloni if (IS_ERR(hw))
77662061d35SAlexandre Belloni continue;
77762061d35SAlexandre Belloni
77862061d35SAlexandre Belloni of_clk_add_hw_provider(progclknp, of_clk_hw_simple_get, hw);
77962061d35SAlexandre Belloni }
78062061d35SAlexandre Belloni }
78162061d35SAlexandre Belloni
of_at91rm9200_clk_prog_setup(struct device_node * np)78262061d35SAlexandre Belloni static void __init of_at91rm9200_clk_prog_setup(struct device_node *np)
78362061d35SAlexandre Belloni {
784c57aaaa2SClaudiu Beznea of_at91_clk_prog_setup(np, &at91rm9200_programmable_layout, NULL);
78562061d35SAlexandre Belloni }
78662061d35SAlexandre Belloni CLK_OF_DECLARE(at91rm9200_clk_prog, "atmel,at91rm9200-clk-programmable",
78762061d35SAlexandre Belloni of_at91rm9200_clk_prog_setup);
78862061d35SAlexandre Belloni
of_at91sam9g45_clk_prog_setup(struct device_node * np)78962061d35SAlexandre Belloni static void __init of_at91sam9g45_clk_prog_setup(struct device_node *np)
79062061d35SAlexandre Belloni {
791c57aaaa2SClaudiu Beznea of_at91_clk_prog_setup(np, &at91sam9g45_programmable_layout, NULL);
79262061d35SAlexandre Belloni }
79362061d35SAlexandre Belloni CLK_OF_DECLARE(at91sam9g45_clk_prog, "atmel,at91sam9g45-clk-programmable",
79462061d35SAlexandre Belloni of_at91sam9g45_clk_prog_setup);
79562061d35SAlexandre Belloni
of_at91sam9x5_clk_prog_setup(struct device_node * np)79662061d35SAlexandre Belloni static void __init of_at91sam9x5_clk_prog_setup(struct device_node *np)
79762061d35SAlexandre Belloni {
798c57aaaa2SClaudiu Beznea of_at91_clk_prog_setup(np, &at91sam9x5_programmable_layout, NULL);
79962061d35SAlexandre Belloni }
80062061d35SAlexandre Belloni CLK_OF_DECLARE(at91sam9x5_clk_prog, "atmel,at91sam9x5-clk-programmable",
80162061d35SAlexandre Belloni of_at91sam9x5_clk_prog_setup);
80262061d35SAlexandre Belloni
of_at91sam9260_clk_slow_setup(struct device_node * np)80362061d35SAlexandre Belloni static void __init of_at91sam9260_clk_slow_setup(struct device_node *np)
80462061d35SAlexandre Belloni {
80562061d35SAlexandre Belloni struct clk_hw *hw;
80662061d35SAlexandre Belloni const char *parent_names[2];
80762061d35SAlexandre Belloni unsigned int num_parents;
80862061d35SAlexandre Belloni const char *name = np->name;
80962061d35SAlexandre Belloni struct regmap *regmap;
810b3ff02c5SLiang He struct device_node *parent_np;
81162061d35SAlexandre Belloni
81262061d35SAlexandre Belloni num_parents = of_clk_get_parent_count(np);
81362061d35SAlexandre Belloni if (num_parents != 2)
81462061d35SAlexandre Belloni return;
81562061d35SAlexandre Belloni
81662061d35SAlexandre Belloni of_clk_parent_fill(np, parent_names, num_parents);
817b3ff02c5SLiang He parent_np = of_get_parent(np);
818b3ff02c5SLiang He regmap = syscon_node_to_regmap(parent_np);
819b3ff02c5SLiang He of_node_put(parent_np);
82062061d35SAlexandre Belloni if (IS_ERR(regmap))
82162061d35SAlexandre Belloni return;
82262061d35SAlexandre Belloni
82362061d35SAlexandre Belloni of_property_read_string(np, "clock-output-names", &name);
82462061d35SAlexandre Belloni
82562061d35SAlexandre Belloni hw = at91_clk_register_sam9260_slow(regmap, name, parent_names,
82662061d35SAlexandre Belloni num_parents);
82762061d35SAlexandre Belloni if (IS_ERR(hw))
82862061d35SAlexandre Belloni return;
82962061d35SAlexandre Belloni
83062061d35SAlexandre Belloni of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
83162061d35SAlexandre Belloni }
83262061d35SAlexandre Belloni CLK_OF_DECLARE(at91sam9260_clk_slow, "atmel,at91sam9260-clk-slow",
83362061d35SAlexandre Belloni of_at91sam9260_clk_slow_setup);
83462061d35SAlexandre Belloni
83562061d35SAlexandre Belloni #ifdef CONFIG_HAVE_AT91_SMD
83662061d35SAlexandre Belloni #define SMD_SOURCE_MAX 2
83762061d35SAlexandre Belloni
of_at91sam9x5_clk_smd_setup(struct device_node * np)83862061d35SAlexandre Belloni static void __init of_at91sam9x5_clk_smd_setup(struct device_node *np)
83962061d35SAlexandre Belloni {
84062061d35SAlexandre Belloni struct clk_hw *hw;
84162061d35SAlexandre Belloni unsigned int num_parents;
84262061d35SAlexandre Belloni const char *parent_names[SMD_SOURCE_MAX];
84362061d35SAlexandre Belloni const char *name = np->name;
84462061d35SAlexandre Belloni struct regmap *regmap;
845b3ff02c5SLiang He struct device_node *parent_np;
84662061d35SAlexandre Belloni
84762061d35SAlexandre Belloni num_parents = of_clk_get_parent_count(np);
84862061d35SAlexandre Belloni if (num_parents == 0 || num_parents > SMD_SOURCE_MAX)
84962061d35SAlexandre Belloni return;
85062061d35SAlexandre Belloni
85162061d35SAlexandre Belloni of_clk_parent_fill(np, parent_names, num_parents);
85262061d35SAlexandre Belloni
85362061d35SAlexandre Belloni of_property_read_string(np, "clock-output-names", &name);
85462061d35SAlexandre Belloni
855b3ff02c5SLiang He parent_np = of_get_parent(np);
856b3ff02c5SLiang He regmap = syscon_node_to_regmap(parent_np);
857b3ff02c5SLiang He of_node_put(parent_np);
85862061d35SAlexandre Belloni if (IS_ERR(regmap))
85962061d35SAlexandre Belloni return;
86062061d35SAlexandre Belloni
86162061d35SAlexandre Belloni hw = at91sam9x5_clk_register_smd(regmap, name, parent_names,
86262061d35SAlexandre Belloni num_parents);
86362061d35SAlexandre Belloni if (IS_ERR(hw))
86462061d35SAlexandre Belloni return;
86562061d35SAlexandre Belloni
86662061d35SAlexandre Belloni of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
86762061d35SAlexandre Belloni }
86862061d35SAlexandre Belloni CLK_OF_DECLARE(at91sam9x5_clk_smd, "atmel,at91sam9x5-clk-smd",
86962061d35SAlexandre Belloni of_at91sam9x5_clk_smd_setup);
87062061d35SAlexandre Belloni #endif /* CONFIG_HAVE_AT91_SMD */
87162061d35SAlexandre Belloni
of_at91rm9200_clk_sys_setup(struct device_node * np)87262061d35SAlexandre Belloni static void __init of_at91rm9200_clk_sys_setup(struct device_node *np)
87362061d35SAlexandre Belloni {
87462061d35SAlexandre Belloni int num;
87562061d35SAlexandre Belloni u32 id;
87662061d35SAlexandre Belloni struct clk_hw *hw;
87762061d35SAlexandre Belloni const char *name;
878b3ff02c5SLiang He struct device_node *sysclknp, *parent_np;
87962061d35SAlexandre Belloni const char *parent_name;
88062061d35SAlexandre Belloni struct regmap *regmap;
88162061d35SAlexandre Belloni
88262061d35SAlexandre Belloni num = of_get_child_count(np);
88362061d35SAlexandre Belloni if (num > (SYSTEM_MAX_ID + 1))
88462061d35SAlexandre Belloni return;
88562061d35SAlexandre Belloni
886b3ff02c5SLiang He parent_np = of_get_parent(np);
887b3ff02c5SLiang He regmap = syscon_node_to_regmap(parent_np);
888b3ff02c5SLiang He of_node_put(parent_np);
88962061d35SAlexandre Belloni if (IS_ERR(regmap))
89062061d35SAlexandre Belloni return;
89162061d35SAlexandre Belloni
89262061d35SAlexandre Belloni for_each_child_of_node(np, sysclknp) {
89368b3b6f1SClaudiu Beznea unsigned long flags = 0;
89468b3b6f1SClaudiu Beznea
89562061d35SAlexandre Belloni if (of_property_read_u32(sysclknp, "reg", &id))
89662061d35SAlexandre Belloni continue;
89762061d35SAlexandre Belloni
89862061d35SAlexandre Belloni if (of_property_read_string(np, "clock-output-names", &name))
89962061d35SAlexandre Belloni name = sysclknp->name;
90062061d35SAlexandre Belloni
90162061d35SAlexandre Belloni parent_name = of_clk_get_parent_name(sysclknp, 0);
90262061d35SAlexandre Belloni
90368b3b6f1SClaudiu Beznea /*
90468b3b6f1SClaudiu Beznea * ddrck feeds DDR controller and is enabled by bootloader thus
90568b3b6f1SClaudiu Beznea * we need to keep it enabled in case there is no Linux consumer
90668b3b6f1SClaudiu Beznea * for it.
90768b3b6f1SClaudiu Beznea */
90868b3b6f1SClaudiu Beznea if (!strcmp(sysclknp->name, "ddrck"))
90968b3b6f1SClaudiu Beznea flags = CLK_IS_CRITICAL;
91068b3b6f1SClaudiu Beznea
9111a537f62SClaudiu Beznea hw = at91_clk_register_system(regmap, name, parent_name, NULL,
9121a537f62SClaudiu Beznea id, flags);
91362061d35SAlexandre Belloni if (IS_ERR(hw))
91462061d35SAlexandre Belloni continue;
91562061d35SAlexandre Belloni
91662061d35SAlexandre Belloni of_clk_add_hw_provider(sysclknp, of_clk_hw_simple_get, hw);
91762061d35SAlexandre Belloni }
91862061d35SAlexandre Belloni }
91962061d35SAlexandre Belloni CLK_OF_DECLARE(at91rm9200_clk_sys, "atmel,at91rm9200-clk-system",
92062061d35SAlexandre Belloni of_at91rm9200_clk_sys_setup);
92162061d35SAlexandre Belloni
92262061d35SAlexandre Belloni #ifdef CONFIG_HAVE_AT91_USB_CLK
92362061d35SAlexandre Belloni #define USB_SOURCE_MAX 2
92462061d35SAlexandre Belloni
of_at91sam9x5_clk_usb_setup(struct device_node * np)92562061d35SAlexandre Belloni static void __init of_at91sam9x5_clk_usb_setup(struct device_node *np)
92662061d35SAlexandre Belloni {
92762061d35SAlexandre Belloni struct clk_hw *hw;
92862061d35SAlexandre Belloni unsigned int num_parents;
92962061d35SAlexandre Belloni const char *parent_names[USB_SOURCE_MAX];
93062061d35SAlexandre Belloni const char *name = np->name;
93162061d35SAlexandre Belloni struct regmap *regmap;
932b3ff02c5SLiang He struct device_node *parent_np;
93362061d35SAlexandre Belloni
93462061d35SAlexandre Belloni num_parents = of_clk_get_parent_count(np);
93562061d35SAlexandre Belloni if (num_parents == 0 || num_parents > USB_SOURCE_MAX)
93662061d35SAlexandre Belloni return;
93762061d35SAlexandre Belloni
93862061d35SAlexandre Belloni of_clk_parent_fill(np, parent_names, num_parents);
93962061d35SAlexandre Belloni
94062061d35SAlexandre Belloni of_property_read_string(np, "clock-output-names", &name);
94162061d35SAlexandre Belloni
942b3ff02c5SLiang He parent_np = of_get_parent(np);
943b3ff02c5SLiang He regmap = syscon_node_to_regmap(parent_np);
944b3ff02c5SLiang He of_node_put(parent_np);
94562061d35SAlexandre Belloni if (IS_ERR(regmap))
94662061d35SAlexandre Belloni return;
94762061d35SAlexandre Belloni
94862061d35SAlexandre Belloni hw = at91sam9x5_clk_register_usb(regmap, name, parent_names,
94962061d35SAlexandre Belloni num_parents);
95062061d35SAlexandre Belloni if (IS_ERR(hw))
95162061d35SAlexandre Belloni return;
95262061d35SAlexandre Belloni
95362061d35SAlexandre Belloni of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
95462061d35SAlexandre Belloni }
95562061d35SAlexandre Belloni CLK_OF_DECLARE(at91sam9x5_clk_usb, "atmel,at91sam9x5-clk-usb",
95662061d35SAlexandre Belloni of_at91sam9x5_clk_usb_setup);
95762061d35SAlexandre Belloni
of_at91sam9n12_clk_usb_setup(struct device_node * np)95862061d35SAlexandre Belloni static void __init of_at91sam9n12_clk_usb_setup(struct device_node *np)
95962061d35SAlexandre Belloni {
96062061d35SAlexandre Belloni struct clk_hw *hw;
96162061d35SAlexandre Belloni const char *parent_name;
96262061d35SAlexandre Belloni const char *name = np->name;
96362061d35SAlexandre Belloni struct regmap *regmap;
964b3ff02c5SLiang He struct device_node *parent_np;
96562061d35SAlexandre Belloni
96662061d35SAlexandre Belloni parent_name = of_clk_get_parent_name(np, 0);
96762061d35SAlexandre Belloni if (!parent_name)
96862061d35SAlexandre Belloni return;
96962061d35SAlexandre Belloni
97062061d35SAlexandre Belloni of_property_read_string(np, "clock-output-names", &name);
97162061d35SAlexandre Belloni
972b3ff02c5SLiang He parent_np = of_get_parent(np);
973b3ff02c5SLiang He regmap = syscon_node_to_regmap(parent_np);
974b3ff02c5SLiang He of_node_put(parent_np);
97562061d35SAlexandre Belloni if (IS_ERR(regmap))
97662061d35SAlexandre Belloni return;
97762061d35SAlexandre Belloni
97862061d35SAlexandre Belloni hw = at91sam9n12_clk_register_usb(regmap, name, parent_name);
97962061d35SAlexandre Belloni if (IS_ERR(hw))
98062061d35SAlexandre Belloni return;
98162061d35SAlexandre Belloni
98262061d35SAlexandre Belloni of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
98362061d35SAlexandre Belloni }
98462061d35SAlexandre Belloni CLK_OF_DECLARE(at91sam9n12_clk_usb, "atmel,at91sam9n12-clk-usb",
98562061d35SAlexandre Belloni of_at91sam9n12_clk_usb_setup);
98662061d35SAlexandre Belloni
of_at91rm9200_clk_usb_setup(struct device_node * np)98762061d35SAlexandre Belloni static void __init of_at91rm9200_clk_usb_setup(struct device_node *np)
98862061d35SAlexandre Belloni {
98962061d35SAlexandre Belloni struct clk_hw *hw;
99062061d35SAlexandre Belloni const char *parent_name;
99162061d35SAlexandre Belloni const char *name = np->name;
99262061d35SAlexandre Belloni u32 divisors[4] = {0, 0, 0, 0};
99362061d35SAlexandre Belloni struct regmap *regmap;
994b3ff02c5SLiang He struct device_node *parent_np;
99562061d35SAlexandre Belloni
99662061d35SAlexandre Belloni parent_name = of_clk_get_parent_name(np, 0);
99762061d35SAlexandre Belloni if (!parent_name)
99862061d35SAlexandre Belloni return;
99962061d35SAlexandre Belloni
100062061d35SAlexandre Belloni of_property_read_u32_array(np, "atmel,clk-divisors", divisors, 4);
100162061d35SAlexandre Belloni if (!divisors[0])
100262061d35SAlexandre Belloni return;
100362061d35SAlexandre Belloni
100462061d35SAlexandre Belloni of_property_read_string(np, "clock-output-names", &name);
100562061d35SAlexandre Belloni
1006b3ff02c5SLiang He parent_np = of_get_parent(np);
1007b3ff02c5SLiang He regmap = syscon_node_to_regmap(parent_np);
1008b3ff02c5SLiang He of_node_put(parent_np);
100962061d35SAlexandre Belloni if (IS_ERR(regmap))
101062061d35SAlexandre Belloni return;
101162061d35SAlexandre Belloni hw = at91rm9200_clk_register_usb(regmap, name, parent_name, divisors);
101262061d35SAlexandre Belloni if (IS_ERR(hw))
101362061d35SAlexandre Belloni return;
101462061d35SAlexandre Belloni
101562061d35SAlexandre Belloni of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
101662061d35SAlexandre Belloni }
101762061d35SAlexandre Belloni CLK_OF_DECLARE(at91rm9200_clk_usb, "atmel,at91rm9200-clk-usb",
101862061d35SAlexandre Belloni of_at91rm9200_clk_usb_setup);
101962061d35SAlexandre Belloni #endif /* CONFIG_HAVE_AT91_USB_CLK */
102062061d35SAlexandre Belloni
102162061d35SAlexandre Belloni #ifdef CONFIG_HAVE_AT91_UTMI
of_at91sam9x5_clk_utmi_setup(struct device_node * np)102262061d35SAlexandre Belloni static void __init of_at91sam9x5_clk_utmi_setup(struct device_node *np)
102362061d35SAlexandre Belloni {
102462061d35SAlexandre Belloni struct clk_hw *hw;
102562061d35SAlexandre Belloni const char *parent_name;
102662061d35SAlexandre Belloni const char *name = np->name;
102762061d35SAlexandre Belloni struct regmap *regmap_pmc, *regmap_sfr;
1028b3ff02c5SLiang He struct device_node *parent_np;
102962061d35SAlexandre Belloni
103062061d35SAlexandre Belloni parent_name = of_clk_get_parent_name(np, 0);
103162061d35SAlexandre Belloni
103262061d35SAlexandre Belloni of_property_read_string(np, "clock-output-names", &name);
103362061d35SAlexandre Belloni
1034b3ff02c5SLiang He parent_np = of_get_parent(np);
1035b3ff02c5SLiang He regmap_pmc = syscon_node_to_regmap(parent_np);
1036b3ff02c5SLiang He of_node_put(parent_np);
103762061d35SAlexandre Belloni if (IS_ERR(regmap_pmc))
103862061d35SAlexandre Belloni return;
103962061d35SAlexandre Belloni
104062061d35SAlexandre Belloni /*
104162061d35SAlexandre Belloni * If the device supports different mainck rates, this value has to be
104262061d35SAlexandre Belloni * set in the UTMI Clock Trimming register.
104362061d35SAlexandre Belloni * - 9x5: mainck supports several rates but it is indicated that a
104462061d35SAlexandre Belloni * 12 MHz is needed in case of USB.
104562061d35SAlexandre Belloni * - sama5d3 and sama5d2: mainck supports several rates. Configuring
104662061d35SAlexandre Belloni * the FREQ field of the UTMI Clock Trimming register is mandatory.
104762061d35SAlexandre Belloni * - sama5d4: mainck is at 12 MHz.
104862061d35SAlexandre Belloni *
104962061d35SAlexandre Belloni * We only need to retrieve sama5d3 or sama5d2 sfr regmap.
105062061d35SAlexandre Belloni */
105162061d35SAlexandre Belloni regmap_sfr = syscon_regmap_lookup_by_compatible("atmel,sama5d3-sfr");
105262061d35SAlexandre Belloni if (IS_ERR(regmap_sfr)) {
105362061d35SAlexandre Belloni regmap_sfr = syscon_regmap_lookup_by_compatible("atmel,sama5d2-sfr");
105462061d35SAlexandre Belloni if (IS_ERR(regmap_sfr))
105562061d35SAlexandre Belloni regmap_sfr = NULL;
105662061d35SAlexandre Belloni }
105762061d35SAlexandre Belloni
1058*077782e3SClaudiu Beznea hw = at91_clk_register_utmi(regmap_pmc, regmap_sfr, name, parent_name, NULL);
105962061d35SAlexandre Belloni if (IS_ERR(hw))
106062061d35SAlexandre Belloni return;
106162061d35SAlexandre Belloni
106262061d35SAlexandre Belloni of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
106362061d35SAlexandre Belloni }
106462061d35SAlexandre Belloni CLK_OF_DECLARE(at91sam9x5_clk_utmi, "atmel,at91sam9x5-clk-utmi",
106562061d35SAlexandre Belloni of_at91sam9x5_clk_utmi_setup);
106662061d35SAlexandre Belloni #endif /* CONFIG_HAVE_AT91_UTMI */
1067