xref: /OK3568_Linux_fs/kernel/drivers/clk/rockchip/regmap/clk-regmap-gate.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  * Copyright (c) 2017 Rockchip Electronics Co. Ltd.
3  *
4  * Base on code in drivers/clk/clk-gate.c.
5  * See clk-gate.c for further copyright information.
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  */
17 
18 #include "clk-regmap.h"
19 
20 #define to_clk_regmap_gate(_hw)	container_of(_hw, struct clk_regmap_gate, hw)
21 
clk_regmap_gate_prepare(struct clk_hw * hw)22 static int clk_regmap_gate_prepare(struct clk_hw *hw)
23 {
24 	struct clk_regmap_gate *gate = to_clk_regmap_gate(hw);
25 
26 	return regmap_write(gate->regmap, gate->reg,
27 			    0 | BIT(gate->shift + 16));
28 }
29 
clk_regmap_gate_unprepare(struct clk_hw * hw)30 static void clk_regmap_gate_unprepare(struct clk_hw *hw)
31 {
32 	struct clk_regmap_gate *gate = to_clk_regmap_gate(hw);
33 
34 	regmap_write(gate->regmap, gate->reg,
35 		     BIT(gate->shift) | BIT(gate->shift + 16));
36 }
37 
clk_regmap_gate_is_prepared(struct clk_hw * hw)38 static int clk_regmap_gate_is_prepared(struct clk_hw *hw)
39 {
40 	struct clk_regmap_gate *gate = to_clk_regmap_gate(hw);
41 	u32 val;
42 
43 	regmap_read(gate->regmap, gate->reg, &val);
44 
45 	return !(val & BIT(gate->shift));
46 }
47 
48 const struct clk_ops clk_regmap_gate_ops = {
49 	.prepare = clk_regmap_gate_prepare,
50 	.unprepare = clk_regmap_gate_unprepare,
51 	.is_prepared = clk_regmap_gate_is_prepared,
52 };
53 EXPORT_SYMBOL_GPL(clk_regmap_gate_ops);
54 
55 struct clk *
devm_clk_regmap_register_gate(struct device * dev,const char * name,const char * parent_name,struct regmap * regmap,u32 reg,u8 shift,unsigned long flags)56 devm_clk_regmap_register_gate(struct device *dev, const char *name,
57 			      const char *parent_name,
58 			      struct regmap *regmap, u32 reg, u8 shift,
59 			      unsigned long flags)
60 {
61 	struct clk_regmap_gate *gate;
62 	struct clk_init_data init = {};
63 
64 	gate = devm_kzalloc(dev, sizeof(*gate), GFP_KERNEL);
65 	if (!gate)
66 		return ERR_PTR(-ENOMEM);
67 
68 	init.name = name;
69 	init.ops = &clk_regmap_gate_ops;
70 	init.flags = flags;
71 	init.parent_names = (parent_name ? &parent_name : NULL);
72 	init.num_parents = (parent_name ? 1 : 0);
73 
74 	gate->dev = dev;
75 	gate->regmap = regmap;
76 	gate->reg = reg;
77 	gate->shift = shift;
78 	gate->hw.init = &init;
79 
80 	return devm_clk_register(dev, &gate->hw);
81 }
82 EXPORT_SYMBOL_GPL(devm_clk_regmap_register_gate);
83