99#include <linux/auxiliary_bus.h>
1010#include <linux/delay.h>
1111#include <linux/io.h>
12+ #include <linux/mfd/syscon.h>
1213#include <linux/module.h>
1314#include <linux/of.h>
1415#include <linux/platform_device.h>
15- #include <linux/slab .h>
16+ #include <linux/regmap .h>
1617#include <linux/reset-controller.h>
18+ #include <linux/slab.h>
1719#include <dt-bindings/clock/microchip,mpfs-clock.h>
1820#include <soc/microchip/mpfs.h>
1921
2729#define MPFS_SLEEP_MIN_US 100
2830#define MPFS_SLEEP_MAX_US 200
2931
30- /* block concurrent access to the soft reset register */
31- static DEFINE_SPINLOCK (mpfs_reset_lock );
32+ #define REG_SUBBLK_RESET_CR 0x88u
3233
3334struct mpfs_reset {
34- void __iomem * base ;
35+ struct regmap * regmap ;
3536 struct reset_controller_dev rcdev ;
3637};
3738
@@ -46,41 +47,25 @@ static inline struct mpfs_reset *to_mpfs_reset(struct reset_controller_dev *rcde
4647static int mpfs_assert (struct reset_controller_dev * rcdev , unsigned long id )
4748{
4849 struct mpfs_reset * rst = to_mpfs_reset (rcdev );
49- unsigned long flags ;
50- u32 reg ;
51-
52- spin_lock_irqsave (& mpfs_reset_lock , flags );
53-
54- reg = readl (rst -> base );
55- reg |= BIT (id );
56- writel (reg , rst -> base );
5750
58- spin_unlock_irqrestore ( & mpfs_reset_lock , flags );
51+ return regmap_set_bits ( rst -> regmap , REG_SUBBLK_RESET_CR , BIT ( id ) );
5952
60- return 0 ;
6153}
6254
6355static int mpfs_deassert (struct reset_controller_dev * rcdev , unsigned long id )
6456{
6557 struct mpfs_reset * rst = to_mpfs_reset (rcdev );
66- unsigned long flags ;
67- u32 reg ;
68-
69- spin_lock_irqsave (& mpfs_reset_lock , flags );
7058
71- reg = readl (rst -> base );
72- reg &= ~BIT (id );
73- writel (reg , rst -> base );
59+ return regmap_clear_bits (rst -> regmap , REG_SUBBLK_RESET_CR , BIT (id ));
7460
75- spin_unlock_irqrestore (& mpfs_reset_lock , flags );
76-
77- return 0 ;
7861}
7962
8063static int mpfs_status (struct reset_controller_dev * rcdev , unsigned long id )
8164{
8265 struct mpfs_reset * rst = to_mpfs_reset (rcdev );
83- u32 reg = readl (rst -> base );
66+ u32 reg ;
67+
68+ regmap_read (rst -> regmap , REG_SUBBLK_RESET_CR , & reg );
8469
8570 /*
8671 * It is safe to return here as MPFS_NUM_RESETS makes sure the sign bit
@@ -130,23 +115,58 @@ static int mpfs_reset_xlate(struct reset_controller_dev *rcdev,
130115 return index - MPFS_PERIPH_OFFSET ;
131116}
132117
133- static int mpfs_reset_probe (struct auxiliary_device * adev ,
134- const struct auxiliary_device_id * id )
118+ static int mpfs_reset_mfd_probe (struct platform_device * pdev )
119+ {
120+ struct reset_controller_dev * rcdev ;
121+ struct device * dev = & pdev -> dev ;
122+ struct mpfs_reset * rst ;
123+
124+ rst = devm_kzalloc (dev , sizeof (* rst ), GFP_KERNEL );
125+ if (!rst )
126+ return - ENOMEM ;
127+
128+ rcdev = & rst -> rcdev ;
129+ rcdev -> dev = dev ;
130+ rcdev -> ops = & mpfs_reset_ops ;
131+
132+ rcdev -> of_node = pdev -> dev .parent -> of_node ;
133+ rcdev -> of_reset_n_cells = 1 ;
134+ rcdev -> of_xlate = mpfs_reset_xlate ;
135+ rcdev -> nr_resets = MPFS_NUM_RESETS ;
136+
137+ rst -> regmap = device_node_to_regmap (pdev -> dev .parent -> of_node );
138+ if (IS_ERR (rst -> regmap ))
139+ return dev_err_probe (dev , PTR_ERR (rst -> regmap ),
140+ "Failed to find syscon regmap\n" );
141+
142+ return devm_reset_controller_register (dev , rcdev );
143+ }
144+
145+ static struct platform_driver mpfs_reset_mfd_driver = {
146+ .probe = mpfs_reset_mfd_probe ,
147+ .driver = {
148+ .name = "mpfs-reset" ,
149+ },
150+ };
151+ module_platform_driver (mpfs_reset_mfd_driver );
152+
153+ static int mpfs_reset_adev_probe (struct auxiliary_device * adev ,
154+ const struct auxiliary_device_id * id )
135155{
136- struct device * dev = & adev -> dev ;
137156 struct reset_controller_dev * rcdev ;
157+ struct device * dev = & adev -> dev ;
138158 struct mpfs_reset * rst ;
139159
140160 rst = devm_kzalloc (dev , sizeof (* rst ), GFP_KERNEL );
141161 if (!rst )
142162 return - ENOMEM ;
143163
144- rst -> base = (void __iomem * )adev -> dev .platform_data ;
164+ rst -> regmap = (struct regmap * )adev -> dev .platform_data ;
145165
146166 rcdev = & rst -> rcdev ;
147167 rcdev -> dev = dev ;
148- rcdev -> dev -> parent = dev -> parent ;
149168 rcdev -> ops = & mpfs_reset_ops ;
169+
150170 rcdev -> of_node = dev -> parent -> of_node ;
151171 rcdev -> of_reset_n_cells = 1 ;
152172 rcdev -> of_xlate = mpfs_reset_xlate ;
@@ -155,12 +175,11 @@ static int mpfs_reset_probe(struct auxiliary_device *adev,
155175 return devm_reset_controller_register (dev , rcdev );
156176}
157177
158- int mpfs_reset_controller_register (struct device * clk_dev , void __iomem * base )
178+ int mpfs_reset_controller_register (struct device * clk_dev , struct regmap * map )
159179{
160180 struct auxiliary_device * adev ;
161181
162- adev = devm_auxiliary_device_create (clk_dev , "reset-mpfs" ,
163- (__force void * )base );
182+ adev = devm_auxiliary_device_create (clk_dev , "reset-mpfs" , (void * )map );
164183 if (!adev )
165184 return - ENODEV ;
166185
@@ -176,12 +195,12 @@ static const struct auxiliary_device_id mpfs_reset_ids[] = {
176195};
177196MODULE_DEVICE_TABLE (auxiliary , mpfs_reset_ids );
178197
179- static struct auxiliary_driver mpfs_reset_driver = {
180- .probe = mpfs_reset_probe ,
198+ static struct auxiliary_driver mpfs_reset_aux_driver = {
199+ .probe = mpfs_reset_adev_probe ,
181200 .id_table = mpfs_reset_ids ,
182201};
183202
184- module_auxiliary_driver (mpfs_reset_driver );
203+ module_auxiliary_driver (mpfs_reset_aux_driver );
185204
186205MODULE_DESCRIPTION ("Microchip PolarFire SoC Reset Driver" );
187206MODULE_AUTHOR ("Conor Dooley <conor.dooley@microchip.com>" );
0 commit comments