]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blame - drivers/clk/mediatek/clk-mux.c
clk: mediatek: mux: Drop unused clock ops
[mirror_ubuntu-jammy-kernel.git] / drivers / clk / mediatek / clk-mux.c
CommitLineData
a3ae5499
OC
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (c) 2018 MediaTek Inc.
4 * Author: Owen Chen <owen.chen@mediatek.com>
5 */
6
7#include <linux/of.h>
8#include <linux/of_address.h>
9#include <linux/slab.h>
10#include <linux/mfd/syscon.h>
11
12#include "clk-mtk.h"
13#include "clk-mux.h"
14
15static inline struct mtk_clk_mux *to_mtk_clk_mux(struct clk_hw *hw)
16{
17 return container_of(hw, struct mtk_clk_mux, hw);
18}
19
a3ae5499
OC
20static int mtk_clk_mux_enable_setclr(struct clk_hw *hw)
21{
22 struct mtk_clk_mux *mux = to_mtk_clk_mux(hw);
23
24 return regmap_write(mux->regmap, mux->data->clr_ofs,
25 BIT(mux->data->gate_shift));
26}
27
28static void mtk_clk_mux_disable_setclr(struct clk_hw *hw)
29{
30 struct mtk_clk_mux *mux = to_mtk_clk_mux(hw);
31
32 regmap_write(mux->regmap, mux->data->set_ofs,
33 BIT(mux->data->gate_shift));
34}
35
36static int mtk_clk_mux_is_enabled(struct clk_hw *hw)
37{
38 struct mtk_clk_mux *mux = to_mtk_clk_mux(hw);
39 u32 val;
40
41 regmap_read(mux->regmap, mux->data->mux_ofs, &val);
42
43 return (val & BIT(mux->data->gate_shift)) == 0;
44}
45
46static u8 mtk_clk_mux_get_parent(struct clk_hw *hw)
47{
48 struct mtk_clk_mux *mux = to_mtk_clk_mux(hw);
49 u32 mask = GENMASK(mux->data->mux_width - 1, 0);
50 u32 val;
51
52 regmap_read(mux->regmap, mux->data->mux_ofs, &val);
53 val = (val >> mux->data->mux_shift) & mask;
54
55 return val;
56}
57
a3ae5499
OC
58static int mtk_clk_mux_set_parent_setclr_lock(struct clk_hw *hw, u8 index)
59{
60 struct mtk_clk_mux *mux = to_mtk_clk_mux(hw);
61 u32 mask = GENMASK(mux->data->mux_width - 1, 0);
62 u32 val, orig;
63 unsigned long flags = 0;
64
65 if (mux->lock)
66 spin_lock_irqsave(mux->lock, flags);
67 else
68 __acquire(mux->lock);
69
70 regmap_read(mux->regmap, mux->data->mux_ofs, &orig);
71 val = (orig & ~(mask << mux->data->mux_shift))
72 | (index << mux->data->mux_shift);
73
74 if (val != orig) {
75 regmap_write(mux->regmap, mux->data->clr_ofs,
76 mask << mux->data->mux_shift);
77 regmap_write(mux->regmap, mux->data->set_ofs,
78 index << mux->data->mux_shift);
79
80 if (mux->data->upd_shift >= 0)
81 regmap_write(mux->regmap, mux->data->upd_ofs,
82 BIT(mux->data->upd_shift));
83 }
84
85 if (mux->lock)
86 spin_unlock_irqrestore(mux->lock, flags);
87 else
88 __release(mux->lock);
89
90 return 0;
91}
92
6df3c6d9 93static const struct clk_ops mtk_mux_ops = {
a3ae5499
OC
94 .enable = mtk_clk_mux_enable_setclr,
95 .disable = mtk_clk_mux_disable_setclr,
96 .is_enabled = mtk_clk_mux_is_enabled,
97 .get_parent = mtk_clk_mux_get_parent,
98 .set_parent = mtk_clk_mux_set_parent_setclr_lock,
99};
100
2aeff9d8 101static struct clk *mtk_clk_register_mux(const struct mtk_mux *mux,
a3ae5499
OC
102 struct regmap *regmap,
103 spinlock_t *lock)
104{
105 struct mtk_clk_mux *clk_mux;
571cfadc 106 struct clk_init_data init = {};
a3ae5499
OC
107 struct clk *clk;
108
109 clk_mux = kzalloc(sizeof(*clk_mux), GFP_KERNEL);
110 if (!clk_mux)
111 return ERR_PTR(-ENOMEM);
112
113 init.name = mux->name;
114 init.flags = mux->flags | CLK_SET_RATE_PARENT;
115 init.parent_names = mux->parent_names;
116 init.num_parents = mux->num_parents;
6df3c6d9 117 init.ops = &mtk_mux_ops;
a3ae5499
OC
118
119 clk_mux->regmap = regmap;
120 clk_mux->data = mux;
121 clk_mux->lock = lock;
122 clk_mux->hw.init = &init;
123
124 clk = clk_register(NULL, &clk_mux->hw);
125 if (IS_ERR(clk)) {
126 kfree(clk_mux);
127 return clk;
128 }
129
130 return clk;
131}
132
133int mtk_clk_register_muxes(const struct mtk_mux *muxes,
134 int num, struct device_node *node,
135 spinlock_t *lock,
136 struct clk_onecell_data *clk_data)
137{
138 struct regmap *regmap;
139 struct clk *clk;
140 int i;
141
142 regmap = syscon_node_to_regmap(node);
143 if (IS_ERR(regmap)) {
144 pr_err("Cannot find regmap for %pOF: %ld\n", node,
145 PTR_ERR(regmap));
146 return PTR_ERR(regmap);
147 }
148
149 for (i = 0; i < num; i++) {
150 const struct mtk_mux *mux = &muxes[i];
151
152 if (IS_ERR_OR_NULL(clk_data->clks[mux->id])) {
153 clk = mtk_clk_register_mux(mux, regmap, lock);
154
155 if (IS_ERR(clk)) {
156 pr_err("Failed to register clk %s: %ld\n",
157 mux->name, PTR_ERR(clk));
158 continue;
159 }
160
161 clk_data->clks[mux->id] = clk;
162 }
163 }
164
165 return 0;
166}