22/*
33 * Amlogic Meson Reset Controller driver
44 *
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>
78 */
9+
810#include <linux/err.h>
9- #include <linux/init.h>
1011#include <linux/io.h>
1112#include <linux/of.h>
1213#include <linux/module.h>
1314#include <linux/platform_device.h>
1415#include <linux/regmap.h>
1516#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 ;
6617
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"
10519
10620static const struct meson_reset_param meson8b_param = {
10721 .reset_num = 256 ,
@@ -151,33 +65,25 @@ static const struct regmap_config regmap_config = {
15165
15266static int meson_reset_probe (struct platform_device * pdev )
15367{
68+ const struct meson_reset_param * param ;
15469 struct device * dev = & pdev -> dev ;
155- struct meson_reset * data ;
70+ struct regmap * map ;
15671 void __iomem * base ;
15772
158- data = devm_kzalloc (dev , sizeof (* data ), GFP_KERNEL );
159- if (!data )
160- return - ENOMEM ;
161-
16273 base = devm_platform_ioremap_resource (pdev , 0 );
16374 if (IS_ERR (base ))
16475 return PTR_ERR (base );
16576
166- data -> param = device_get_match_data (dev );
167- if (!data -> param )
77+ param = device_get_match_data (dev );
78+ if (!param )
16879 return - ENODEV ;
16980
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 ),
17384 "can't init regmap mmio region\n" );
17485
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 );
18187}
18288
18389static struct platform_driver meson_reset_driver = {
@@ -191,4 +97,6 @@ module_platform_driver(meson_reset_driver);
19197
19298MODULE_DESCRIPTION ("Amlogic Meson Reset Controller driver" );
19399MODULE_AUTHOR ("Neil Armstrong <narmstrong@baylibre.com>" );
100+ MODULE_AUTHOR ("Jerome Brunet <jbrunet@baylibre.com>" );
194101MODULE_LICENSE ("Dual BSD/GPL" );
102+ MODULE_IMPORT_NS (MESON_RESET );
0 commit comments