1212#include <linux/module.h>
1313#include <linux/of.h>
1414#include <linux/of_address.h>
15+ #include <linux/regmap.h>
1516#include <linux/reset-controller.h>
1617
1718#define IMX8MP_AUDIOMIX_EARC_RESET_OFFSET 0x200
@@ -43,8 +44,7 @@ static const struct imx8mp_reset_map reset_map[] = {
4344
4445struct imx8mp_audiomix_reset {
4546 struct reset_controller_dev rcdev ;
46- spinlock_t lock ; /* protect register read-modify-write cycle */
47- void __iomem * base ;
47+ struct regmap * regmap ;
4848};
4949
5050static struct imx8mp_audiomix_reset * to_imx8mp_audiomix_reset (struct reset_controller_dev * rcdev )
@@ -56,26 +56,14 @@ static int imx8mp_audiomix_update(struct reset_controller_dev *rcdev,
5656 unsigned long id , bool assert )
5757{
5858 struct imx8mp_audiomix_reset * priv = to_imx8mp_audiomix_reset (rcdev );
59- void __iomem * reg_addr = priv -> base ;
60- unsigned int mask , offset , active_low ;
61- unsigned long reg , flags ;
59+ unsigned int mask , offset , active_low , val ;
6260
6361 mask = reset_map [id ].mask ;
6462 offset = reset_map [id ].offset ;
6563 active_low = reset_map [id ].active_low ;
64+ val = (active_low ^ assert ) ? mask : ~mask ;
6665
67- spin_lock_irqsave (& priv -> lock , flags );
68-
69- reg = readl (reg_addr + offset );
70- if (active_low ^ assert )
71- reg |= mask ;
72- else
73- reg &= ~mask ;
74- writel (reg , reg_addr + offset );
75-
76- spin_unlock_irqrestore (& priv -> lock , flags );
77-
78- return 0 ;
66+ return regmap_update_bits (priv -> regmap , offset , mask , val );
7967}
8068
8169static int imx8mp_audiomix_reset_assert (struct reset_controller_dev * rcdev ,
@@ -95,6 +83,52 @@ static const struct reset_control_ops imx8mp_audiomix_reset_ops = {
9583 .deassert = imx8mp_audiomix_reset_deassert ,
9684};
9785
86+ static const struct regmap_config regmap_config = {
87+ .reg_bits = 32 ,
88+ .val_bits = 32 ,
89+ .reg_stride = 4 ,
90+ };
91+
92+ /* assumption: registered only if not using parent regmap */
93+ static void imx8mp_audiomix_reset_iounmap (void * data )
94+ {
95+ void __iomem * base = (void __iomem * )data ;
96+
97+ iounmap (base );
98+ }
99+
100+ static int imx8mp_audiomix_reset_get_regmap (struct imx8mp_audiomix_reset * priv )
101+ {
102+ void __iomem * base ;
103+ struct device * dev ;
104+ int ret ;
105+
106+ dev = priv -> rcdev .dev ;
107+
108+ /* try to use the parent's regmap */
109+ priv -> regmap = dev_get_regmap (dev -> parent , NULL );
110+ if (priv -> regmap )
111+ return 0 ;
112+
113+ /* ... if that's not possible then initialize the regmap right now */
114+ base = of_iomap (dev -> parent -> of_node , 0 );
115+ if (!base )
116+ return dev_err_probe (dev , - ENOMEM , "failed to iomap address space\n" );
117+
118+ ret = devm_add_action_or_reset (dev ,
119+ imx8mp_audiomix_reset_iounmap ,
120+ (void __force * )base );
121+ if (ret )
122+ return dev_err_probe (dev , ret , "failed to register action\n" );
123+
124+ priv -> regmap = devm_regmap_init_mmio (dev , base , & regmap_config );
125+ if (IS_ERR (priv -> regmap ))
126+ return dev_err_probe (dev , PTR_ERR (priv -> regmap ),
127+ "failed to initialize regmap\n" );
128+
129+ return 0 ;
130+ }
131+
98132static int imx8mp_audiomix_reset_probe (struct auxiliary_device * adev ,
99133 const struct auxiliary_device_id * id )
100134{
@@ -106,36 +140,25 @@ static int imx8mp_audiomix_reset_probe(struct auxiliary_device *adev,
106140 if (!priv )
107141 return - ENOMEM ;
108142
109- spin_lock_init (& priv -> lock );
110-
111143 priv -> rcdev .owner = THIS_MODULE ;
112144 priv -> rcdev .nr_resets = ARRAY_SIZE (reset_map );
113145 priv -> rcdev .ops = & imx8mp_audiomix_reset_ops ;
114146 priv -> rcdev .of_node = dev -> parent -> of_node ;
115147 priv -> rcdev .dev = dev ;
116148 priv -> rcdev .of_reset_n_cells = 1 ;
117- priv -> base = of_iomap (dev -> parent -> of_node , 0 );
118- if (!priv -> base )
119- return - ENOMEM ;
120149
121150 dev_set_drvdata (dev , priv );
122151
152+ ret = imx8mp_audiomix_reset_get_regmap (priv );
153+ if (ret )
154+ return dev_err_probe (dev , ret , "failed to get regmap\n" );
155+
123156 ret = devm_reset_controller_register (dev , & priv -> rcdev );
124157 if (ret )
125- goto out_unmap ;
158+ return dev_err_probe (dev , ret ,
159+ "failed to register reset controller\n" );
126160
127161 return 0 ;
128-
129- out_unmap :
130- iounmap (priv -> base );
131- return ret ;
132- }
133-
134- static void imx8mp_audiomix_reset_remove (struct auxiliary_device * adev )
135- {
136- struct imx8mp_audiomix_reset * priv = dev_get_drvdata (& adev -> dev );
137-
138- iounmap (priv -> base );
139162}
140163
141164static const struct auxiliary_device_id imx8mp_audiomix_reset_ids [] = {
@@ -148,7 +171,6 @@ MODULE_DEVICE_TABLE(auxiliary, imx8mp_audiomix_reset_ids);
148171
149172static struct auxiliary_driver imx8mp_audiomix_reset_driver = {
150173 .probe = imx8mp_audiomix_reset_probe ,
151- .remove = imx8mp_audiomix_reset_remove ,
152174 .id_table = imx8mp_audiomix_reset_ids ,
153175};
154176
0 commit comments