]> git.proxmox.com Git - mirror_ubuntu-eoan-kernel.git/blame - drivers/clk/st/clkgen-mux.c
treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152
[mirror_ubuntu-eoan-kernel.git] / drivers / clk / st / clkgen-mux.c
CommitLineData
2874c5fd 1// SPDX-License-Identifier: GPL-2.0-or-later
94885faf
GF
2/*
3 * clkgen-mux.c: ST GEN-MUX Clock driver
4 *
5 * Copyright (C) 2014 STMicroelectronics (R&D) Limited
6 *
7 * Authors: Stephen Gallimore <stephen.gallimore@st.com>
8 * Pankaj Dev <pankaj.dev@st.com>
94885faf
GF
9 */
10
11#include <linux/slab.h>
62e59c4e 12#include <linux/io.h>
94885faf 13#include <linux/of_address.h>
d5f728ac 14#include <linux/clk.h>
94885faf 15#include <linux/clk-provider.h>
46a57afd 16#include "clkgen.h"
94885faf 17
94885faf
GF
18static const char ** __init clkgen_mux_get_parents(struct device_node *np,
19 int *num_parents)
20{
21 const char **parents;
caeb057c 22 unsigned int nparents;
94885faf 23
0a65239c 24 nparents = of_clk_get_parent_count(np);
caeb057c 25 if (WARN_ON(!nparents))
94885faf
GF
26 return ERR_PTR(-EINVAL);
27
86665d28 28 parents = kcalloc(nparents, sizeof(const char *), GFP_KERNEL);
94885faf
GF
29 if (!parents)
30 return ERR_PTR(-ENOMEM);
31
0b4e7f08 32 *num_parents = of_clk_parent_fill(np, parents, nparents);
94885faf
GF
33 return parents;
34}
35
44993d38
GF
36struct clkgen_mux_data {
37 u32 offset;
38 u8 shift;
39 u8 width;
40 spinlock_t *lock;
41 unsigned long clk_flags;
42 u8 mux_flags;
43};
44
13e6f2da
GF
45static struct clkgen_mux_data stih407_a9_mux_data = {
46 .offset = 0x1a4,
3be6d8ce 47 .shift = 0,
13e6f2da 48 .width = 2,
46a57afd 49 .lock = &clkgen_a9_lock,
13e6f2da 50};
ab35dc13 51
880d54ff
GF
52static void __init st_of_clkgen_mux_setup(struct device_node *np,
53 struct clkgen_mux_data *data)
44993d38 54{
44993d38
GF
55 struct clk *clk;
56 void __iomem *reg;
57 const char **parents;
7df404c9 58 int num_parents = 0;
44993d38
GF
59
60 reg = of_iomap(np, 0);
61 if (!reg) {
62 pr_err("%s: Failed to get base address\n", __func__);
63 return;
64 }
65
66 parents = clkgen_mux_get_parents(np, &num_parents);
67 if (IS_ERR(parents)) {
68 pr_err("%s: Failed to get parents (%ld)\n",
69 __func__, PTR_ERR(parents));
86665d28 70 goto err_parents;
44993d38
GF
71 }
72
73 clk = clk_register_mux(NULL, np->name, parents, num_parents,
74 data->clk_flags | CLK_SET_RATE_PARENT,
75 reg + data->offset,
76 data->shift, data->width, data->mux_flags,
77 data->lock);
78 if (IS_ERR(clk))
79 goto err;
80
81 pr_debug("%s: parent %s rate %u\n",
82 __clk_get_name(clk),
83 __clk_get_name(clk_get_parent(clk)),
84 (unsigned int)clk_get_rate(clk));
85
86665d28 86 kfree(parents);
44993d38 87 of_clk_add_provider(np, of_clk_src_simple_get, clk);
86665d28 88 return;
44993d38
GF
89
90err:
91 kfree(parents);
86665d28
SB
92err_parents:
93 iounmap(reg);
44993d38 94}
880d54ff
GF
95
96static void __init st_of_clkgen_a9_mux_setup(struct device_node *np)
97{
98 st_of_clkgen_mux_setup(np, &stih407_a9_mux_data);
99}
100CLK_OF_DECLARE(clkgen_a9mux, "st,stih407-clkgen-a9-mux",
101 st_of_clkgen_a9_mux_setup);