2
2
/*
3
3
* Amlogic Meson Reset Controller driver
4
4
*
5
- * Copyright (c) 2016 BayLibre, SAS.
6
- * Author: Neil Armstrong <narmstrong@baylibre.com>
5
+ * Copyright (c) 2016-2024 BayLibre, SAS.
6
+ * Authors: Neil Armstrong <narmstrong@baylibre.com>
7
+ * Jerome Brunet <jbrunet@baylibre.com>
7
8
*/
9
+
8
10
#include <linux/err.h>
9
- #include <linux/init.h>
10
11
#include <linux/io.h>
11
12
#include <linux/of.h>
12
13
#include <linux/module.h>
13
14
#include <linux/platform_device.h>
14
15
#include <linux/regmap.h>
15
16
#include <linux/reset-controller.h>
16
- #include <linux/slab.h>
17
- #include <linux/types.h>
18
-
19
- struct meson_reset_param {
20
- unsigned int reset_num ;
21
- unsigned int reset_offset ;
22
- unsigned int level_offset ;
23
- bool level_low_reset ;
24
- };
25
-
26
- struct meson_reset {
27
- const struct meson_reset_param * param ;
28
- struct reset_controller_dev rcdev ;
29
- struct regmap * map ;
30
- };
31
-
32
- static void meson_reset_offset_and_bit (struct meson_reset * data ,
33
- unsigned long id ,
34
- unsigned int * offset ,
35
- unsigned int * bit )
36
- {
37
- unsigned int stride = regmap_get_reg_stride (data -> map );
38
-
39
- * offset = (id / (stride * BITS_PER_BYTE )) * stride ;
40
- * bit = id % (stride * BITS_PER_BYTE );
41
- }
42
-
43
- static int meson_reset_reset (struct reset_controller_dev * rcdev ,
44
- unsigned long id )
45
- {
46
- struct meson_reset * data =
47
- container_of (rcdev , struct meson_reset , rcdev );
48
- unsigned int offset , bit ;
49
-
50
- meson_reset_offset_and_bit (data , id , & offset , & bit );
51
- offset += data -> param -> reset_offset ;
52
-
53
- return regmap_write (data -> map , offset , BIT (bit ));
54
- }
55
-
56
- static int meson_reset_level (struct reset_controller_dev * rcdev ,
57
- unsigned long id , bool assert )
58
- {
59
- struct meson_reset * data =
60
- container_of (rcdev , struct meson_reset , rcdev );
61
- unsigned int offset , bit ;
62
-
63
- meson_reset_offset_and_bit (data , id , & offset , & bit );
64
- offset += data -> param -> level_offset ;
65
- assert ^= data -> param -> level_low_reset ;
66
17
67
- return regmap_update_bits (data -> map , offset ,
68
- BIT (bit ), assert ? BIT (bit ) : 0 );
69
- }
70
-
71
- static int meson_reset_status (struct reset_controller_dev * rcdev ,
72
- unsigned long id )
73
- {
74
- struct meson_reset * data =
75
- container_of (rcdev , struct meson_reset , rcdev );
76
- unsigned int val , offset , bit ;
77
-
78
- meson_reset_offset_and_bit (data , id , & offset , & bit );
79
- offset += data -> param -> level_offset ;
80
-
81
- regmap_read (data -> map , offset , & val );
82
- val = !!(BIT (bit ) & val );
83
-
84
- return val ^ data -> param -> level_low_reset ;
85
- }
86
-
87
- static int meson_reset_assert (struct reset_controller_dev * rcdev ,
88
- unsigned long id )
89
- {
90
- return meson_reset_level (rcdev , id , true);
91
- }
92
-
93
- static int meson_reset_deassert (struct reset_controller_dev * rcdev ,
94
- unsigned long id )
95
- {
96
- return meson_reset_level (rcdev , id , false);
97
- }
98
-
99
- static const struct reset_control_ops meson_reset_ops = {
100
- .reset = meson_reset_reset ,
101
- .assert = meson_reset_assert ,
102
- .deassert = meson_reset_deassert ,
103
- .status = meson_reset_status ,
104
- };
18
+ #include "reset-meson.h"
105
19
106
20
static const struct meson_reset_param meson8b_param = {
107
21
.reset_num = 256 ,
@@ -151,33 +65,25 @@ static const struct regmap_config regmap_config = {
151
65
152
66
static int meson_reset_probe (struct platform_device * pdev )
153
67
{
68
+ const struct meson_reset_param * param ;
154
69
struct device * dev = & pdev -> dev ;
155
- struct meson_reset * data ;
70
+ struct regmap * map ;
156
71
void __iomem * base ;
157
72
158
- data = devm_kzalloc (dev , sizeof (* data ), GFP_KERNEL );
159
- if (!data )
160
- return - ENOMEM ;
161
-
162
73
base = devm_platform_ioremap_resource (pdev , 0 );
163
74
if (IS_ERR (base ))
164
75
return PTR_ERR (base );
165
76
166
- data -> param = device_get_match_data (dev );
167
- if (!data -> param )
77
+ param = device_get_match_data (dev );
78
+ if (!param )
168
79
return - ENODEV ;
169
80
170
- data -> map = devm_regmap_init_mmio (dev , base , & regmap_config );
171
- if (IS_ERR (data -> map ))
172
- return dev_err_probe (dev , PTR_ERR (data -> map ),
81
+ map = devm_regmap_init_mmio (dev , base , & regmap_config );
82
+ if (IS_ERR (map ))
83
+ return dev_err_probe (dev , PTR_ERR (map ),
173
84
"can't init regmap mmio region\n" );
174
85
175
- data -> rcdev .owner = THIS_MODULE ;
176
- data -> rcdev .nr_resets = data -> param -> reset_num ;
177
- data -> rcdev .ops = & meson_reset_ops ;
178
- data -> rcdev .of_node = dev -> of_node ;
179
-
180
- return devm_reset_controller_register (dev , & data -> rcdev );
86
+ return meson_reset_controller_register (dev , map , param );
181
87
}
182
88
183
89
static struct platform_driver meson_reset_driver = {
@@ -191,4 +97,6 @@ module_platform_driver(meson_reset_driver);
191
97
192
98
MODULE_DESCRIPTION ("Amlogic Meson Reset Controller driver" );
193
99
MODULE_AUTHOR ("Neil Armstrong <narmstrong@baylibre.com>" );
100
+ MODULE_AUTHOR ("Jerome Brunet <jbrunet@baylibre.com>" );
194
101
MODULE_LICENSE ("Dual BSD/GPL" );
102
+ MODULE_IMPORT_NS (MESON_RESET );
0 commit comments