xref: /OK3568_Linux_fs/kernel/drivers/clk/mediatek/reset.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Copyright (c) 2014 MediaTek Inc.
4*4882a593Smuzhiyun  */
5*4882a593Smuzhiyun 
6*4882a593Smuzhiyun #include <linux/mfd/syscon.h>
7*4882a593Smuzhiyun #include <linux/module.h>
8*4882a593Smuzhiyun #include <linux/of.h>
9*4882a593Smuzhiyun #include <linux/platform_device.h>
10*4882a593Smuzhiyun #include <linux/regmap.h>
11*4882a593Smuzhiyun #include <linux/reset-controller.h>
12*4882a593Smuzhiyun #include <linux/slab.h>
13*4882a593Smuzhiyun 
14*4882a593Smuzhiyun #include "clk-mtk.h"
15*4882a593Smuzhiyun 
16*4882a593Smuzhiyun struct mtk_reset {
17*4882a593Smuzhiyun 	struct regmap *regmap;
18*4882a593Smuzhiyun 	int regofs;
19*4882a593Smuzhiyun 	struct reset_controller_dev rcdev;
20*4882a593Smuzhiyun };
21*4882a593Smuzhiyun 
mtk_reset_assert_set_clr(struct reset_controller_dev * rcdev,unsigned long id)22*4882a593Smuzhiyun static int mtk_reset_assert_set_clr(struct reset_controller_dev *rcdev,
23*4882a593Smuzhiyun 	unsigned long id)
24*4882a593Smuzhiyun {
25*4882a593Smuzhiyun 	struct mtk_reset *data = container_of(rcdev, struct mtk_reset, rcdev);
26*4882a593Smuzhiyun 	unsigned int reg = data->regofs + ((id / 32) << 4);
27*4882a593Smuzhiyun 
28*4882a593Smuzhiyun 	return regmap_write(data->regmap, reg, BIT(id % 32));
29*4882a593Smuzhiyun }
30*4882a593Smuzhiyun 
mtk_reset_deassert_set_clr(struct reset_controller_dev * rcdev,unsigned long id)31*4882a593Smuzhiyun static int mtk_reset_deassert_set_clr(struct reset_controller_dev *rcdev,
32*4882a593Smuzhiyun 	unsigned long id)
33*4882a593Smuzhiyun {
34*4882a593Smuzhiyun 	struct mtk_reset *data = container_of(rcdev, struct mtk_reset, rcdev);
35*4882a593Smuzhiyun 	unsigned int reg = data->regofs + ((id / 32) << 4) + 0x4;
36*4882a593Smuzhiyun 
37*4882a593Smuzhiyun 	return regmap_write(data->regmap, reg, BIT(id % 32));
38*4882a593Smuzhiyun }
39*4882a593Smuzhiyun 
mtk_reset_assert(struct reset_controller_dev * rcdev,unsigned long id)40*4882a593Smuzhiyun static int mtk_reset_assert(struct reset_controller_dev *rcdev,
41*4882a593Smuzhiyun 			      unsigned long id)
42*4882a593Smuzhiyun {
43*4882a593Smuzhiyun 	struct mtk_reset *data = container_of(rcdev, struct mtk_reset, rcdev);
44*4882a593Smuzhiyun 
45*4882a593Smuzhiyun 	return regmap_update_bits(data->regmap, data->regofs + ((id / 32) << 2),
46*4882a593Smuzhiyun 			BIT(id % 32), ~0);
47*4882a593Smuzhiyun }
48*4882a593Smuzhiyun 
mtk_reset_deassert(struct reset_controller_dev * rcdev,unsigned long id)49*4882a593Smuzhiyun static int mtk_reset_deassert(struct reset_controller_dev *rcdev,
50*4882a593Smuzhiyun 				unsigned long id)
51*4882a593Smuzhiyun {
52*4882a593Smuzhiyun 	struct mtk_reset *data = container_of(rcdev, struct mtk_reset, rcdev);
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun 	return regmap_update_bits(data->regmap, data->regofs + ((id / 32) << 2),
55*4882a593Smuzhiyun 			BIT(id % 32), 0);
56*4882a593Smuzhiyun }
57*4882a593Smuzhiyun 
mtk_reset(struct reset_controller_dev * rcdev,unsigned long id)58*4882a593Smuzhiyun static int mtk_reset(struct reset_controller_dev *rcdev,
59*4882a593Smuzhiyun 			      unsigned long id)
60*4882a593Smuzhiyun {
61*4882a593Smuzhiyun 	int ret;
62*4882a593Smuzhiyun 
63*4882a593Smuzhiyun 	ret = mtk_reset_assert(rcdev, id);
64*4882a593Smuzhiyun 	if (ret)
65*4882a593Smuzhiyun 		return ret;
66*4882a593Smuzhiyun 
67*4882a593Smuzhiyun 	return mtk_reset_deassert(rcdev, id);
68*4882a593Smuzhiyun }
69*4882a593Smuzhiyun 
mtk_reset_set_clr(struct reset_controller_dev * rcdev,unsigned long id)70*4882a593Smuzhiyun static int mtk_reset_set_clr(struct reset_controller_dev *rcdev,
71*4882a593Smuzhiyun 	unsigned long id)
72*4882a593Smuzhiyun {
73*4882a593Smuzhiyun 	int ret;
74*4882a593Smuzhiyun 
75*4882a593Smuzhiyun 	ret = mtk_reset_assert_set_clr(rcdev, id);
76*4882a593Smuzhiyun 	if (ret)
77*4882a593Smuzhiyun 		return ret;
78*4882a593Smuzhiyun 	return mtk_reset_deassert_set_clr(rcdev, id);
79*4882a593Smuzhiyun }
80*4882a593Smuzhiyun 
81*4882a593Smuzhiyun static const struct reset_control_ops mtk_reset_ops = {
82*4882a593Smuzhiyun 	.assert = mtk_reset_assert,
83*4882a593Smuzhiyun 	.deassert = mtk_reset_deassert,
84*4882a593Smuzhiyun 	.reset = mtk_reset,
85*4882a593Smuzhiyun };
86*4882a593Smuzhiyun 
87*4882a593Smuzhiyun static const struct reset_control_ops mtk_reset_ops_set_clr = {
88*4882a593Smuzhiyun 	.assert = mtk_reset_assert_set_clr,
89*4882a593Smuzhiyun 	.deassert = mtk_reset_deassert_set_clr,
90*4882a593Smuzhiyun 	.reset = mtk_reset_set_clr,
91*4882a593Smuzhiyun };
92*4882a593Smuzhiyun 
mtk_register_reset_controller_common(struct device_node * np,unsigned int num_regs,int regofs,const struct reset_control_ops * reset_ops)93*4882a593Smuzhiyun static void mtk_register_reset_controller_common(struct device_node *np,
94*4882a593Smuzhiyun 			unsigned int num_regs, int regofs,
95*4882a593Smuzhiyun 			const struct reset_control_ops *reset_ops)
96*4882a593Smuzhiyun {
97*4882a593Smuzhiyun 	struct mtk_reset *data;
98*4882a593Smuzhiyun 	int ret;
99*4882a593Smuzhiyun 	struct regmap *regmap;
100*4882a593Smuzhiyun 
101*4882a593Smuzhiyun 	regmap = syscon_node_to_regmap(np);
102*4882a593Smuzhiyun 	if (IS_ERR(regmap)) {
103*4882a593Smuzhiyun 		pr_err("Cannot find regmap for %pOF: %ld\n", np,
104*4882a593Smuzhiyun 				PTR_ERR(regmap));
105*4882a593Smuzhiyun 		return;
106*4882a593Smuzhiyun 	}
107*4882a593Smuzhiyun 
108*4882a593Smuzhiyun 	data = kzalloc(sizeof(*data), GFP_KERNEL);
109*4882a593Smuzhiyun 	if (!data)
110*4882a593Smuzhiyun 		return;
111*4882a593Smuzhiyun 
112*4882a593Smuzhiyun 	data->regmap = regmap;
113*4882a593Smuzhiyun 	data->regofs = regofs;
114*4882a593Smuzhiyun 	data->rcdev.owner = THIS_MODULE;
115*4882a593Smuzhiyun 	data->rcdev.nr_resets = num_regs * 32;
116*4882a593Smuzhiyun 	data->rcdev.ops = reset_ops;
117*4882a593Smuzhiyun 	data->rcdev.of_node = np;
118*4882a593Smuzhiyun 
119*4882a593Smuzhiyun 	ret = reset_controller_register(&data->rcdev);
120*4882a593Smuzhiyun 	if (ret) {
121*4882a593Smuzhiyun 		pr_err("could not register reset controller: %d\n", ret);
122*4882a593Smuzhiyun 		kfree(data);
123*4882a593Smuzhiyun 		return;
124*4882a593Smuzhiyun 	}
125*4882a593Smuzhiyun }
126*4882a593Smuzhiyun 
mtk_register_reset_controller(struct device_node * np,unsigned int num_regs,int regofs)127*4882a593Smuzhiyun void mtk_register_reset_controller(struct device_node *np,
128*4882a593Smuzhiyun 	unsigned int num_regs, int regofs)
129*4882a593Smuzhiyun {
130*4882a593Smuzhiyun 	mtk_register_reset_controller_common(np, num_regs, regofs,
131*4882a593Smuzhiyun 		&mtk_reset_ops);
132*4882a593Smuzhiyun }
133*4882a593Smuzhiyun 
mtk_register_reset_controller_set_clr(struct device_node * np,unsigned int num_regs,int regofs)134*4882a593Smuzhiyun void mtk_register_reset_controller_set_clr(struct device_node *np,
135*4882a593Smuzhiyun 	unsigned int num_regs, int regofs)
136*4882a593Smuzhiyun {
137*4882a593Smuzhiyun 	mtk_register_reset_controller_common(np, num_regs, regofs,
138*4882a593Smuzhiyun 		&mtk_reset_ops_set_clr);
139*4882a593Smuzhiyun }
140