30
30
31
31
struct imx8_soc_data {
32
32
char * name ;
33
- u32 (* soc_revision )(void );
33
+ int (* soc_revision )(u32 * socrev , u64 * socuid );
34
34
};
35
35
36
- static u64 soc_uid ;
37
-
38
36
#ifdef CONFIG_HAVE_ARM_SMCCC
39
37
static u32 imx8mq_soc_revision_from_atf (void )
40
38
{
@@ -51,24 +49,27 @@ static u32 imx8mq_soc_revision_from_atf(void)
51
49
static inline u32 imx8mq_soc_revision_from_atf (void ) { return 0 ; };
52
50
#endif
53
51
54
- static u32 __init imx8mq_soc_revision (void )
52
+ static int imx8mq_soc_revision (u32 * socrev , u64 * socuid )
55
53
{
56
- struct device_node * np ;
54
+ struct device_node * np __free (device_node ) =
55
+ of_find_compatible_node (NULL , NULL , "fsl,imx8mq-ocotp" );
57
56
void __iomem * ocotp_base ;
58
57
u32 magic ;
59
58
u32 rev ;
60
59
struct clk * clk ;
60
+ int ret ;
61
61
62
- np = of_find_compatible_node (NULL , NULL , "fsl,imx8mq-ocotp" );
63
62
if (!np )
64
- return 0 ;
63
+ return - EINVAL ;
65
64
66
65
ocotp_base = of_iomap (np , 0 );
67
- WARN_ON (!ocotp_base );
66
+ if (!ocotp_base )
67
+ return - EINVAL ;
68
+
68
69
clk = of_clk_get_by_name (np , NULL );
69
70
if (IS_ERR (clk )) {
70
- WARN_ON ( IS_ERR ( clk ) );
71
- return 0 ;
71
+ ret = PTR_ERR ( clk );
72
+ goto err_clk ;
72
73
}
73
74
74
75
clk_prepare_enable (clk );
@@ -84,71 +85,78 @@ static u32 __init imx8mq_soc_revision(void)
84
85
rev = REV_B1 ;
85
86
}
86
87
87
- soc_uid = readl_relaxed (ocotp_base + OCOTP_UID_HIGH );
88
- soc_uid <<= 32 ;
89
- soc_uid |= readl_relaxed (ocotp_base + OCOTP_UID_LOW );
88
+ * socuid = readl_relaxed (ocotp_base + OCOTP_UID_HIGH );
89
+ * socuid <<= 32 ;
90
+ * socuid |= readl_relaxed (ocotp_base + OCOTP_UID_LOW );
91
+
92
+ * socrev = rev ;
90
93
91
94
clk_disable_unprepare (clk );
92
95
clk_put (clk );
93
96
iounmap (ocotp_base );
94
- of_node_put (np );
95
97
96
- return rev ;
98
+ return 0 ;
99
+
100
+ err_clk :
101
+ iounmap (ocotp_base );
102
+ return ret ;
97
103
}
98
104
99
- static void __init imx8mm_soc_uid (void )
105
+ static int imx8mm_soc_uid (u64 * socuid )
100
106
{
107
+ struct device_node * np __free (device_node ) =
108
+ of_find_compatible_node (NULL , NULL , "fsl,imx8mm-ocotp" );
101
109
void __iomem * ocotp_base ;
102
- struct device_node * np ;
103
110
struct clk * clk ;
111
+ int ret = 0 ;
104
112
u32 offset = of_machine_is_compatible ("fsl,imx8mp" ) ?
105
113
IMX8MP_OCOTP_UID_OFFSET : 0 ;
106
114
107
- np = of_find_compatible_node (NULL , NULL , "fsl,imx8mm-ocotp" );
108
115
if (!np )
109
- return ;
116
+ return - EINVAL ;
110
117
111
118
ocotp_base = of_iomap (np , 0 );
112
- WARN_ON (!ocotp_base );
119
+ if (!ocotp_base )
120
+ return - EINVAL ;
121
+
113
122
clk = of_clk_get_by_name (np , NULL );
114
123
if (IS_ERR (clk )) {
115
- WARN_ON ( IS_ERR ( clk ) );
116
- return ;
124
+ ret = PTR_ERR ( clk );
125
+ goto err_clk ;
117
126
}
118
127
119
128
clk_prepare_enable (clk );
120
129
121
- soc_uid = readl_relaxed (ocotp_base + OCOTP_UID_HIGH + offset );
122
- soc_uid <<= 32 ;
123
- soc_uid |= readl_relaxed (ocotp_base + OCOTP_UID_LOW + offset );
130
+ * socuid = readl_relaxed (ocotp_base + OCOTP_UID_HIGH + offset );
131
+ * socuid <<= 32 ;
132
+ * socuid |= readl_relaxed (ocotp_base + OCOTP_UID_LOW + offset );
124
133
125
134
clk_disable_unprepare (clk );
126
135
clk_put (clk );
136
+
137
+ err_clk :
127
138
iounmap (ocotp_base );
128
- of_node_put ( np ) ;
139
+ return ret ;
129
140
}
130
141
131
- static u32 __init imx8mm_soc_revision (void )
142
+ static int imx8mm_soc_revision (u32 * socrev , u64 * socuid )
132
143
{
133
- struct device_node * np ;
144
+ struct device_node * np __free (device_node ) =
145
+ of_find_compatible_node (NULL , NULL , "fsl,imx8mm-anatop" );
134
146
void __iomem * anatop_base ;
135
- u32 rev ;
136
147
137
- np = of_find_compatible_node (NULL , NULL , "fsl,imx8mm-anatop" );
138
148
if (!np )
139
- return 0 ;
149
+ return - EINVAL ;
140
150
141
151
anatop_base = of_iomap (np , 0 );
142
- WARN_ON (!anatop_base );
152
+ if (!anatop_base )
153
+ return - EINVAL ;
143
154
144
- rev = readl_relaxed (anatop_base + ANADIG_DIGPROG_IMX8MM );
155
+ * socrev = readl_relaxed (anatop_base + ANADIG_DIGPROG_IMX8MM );
145
156
146
157
iounmap (anatop_base );
147
- of_node_put (np );
148
-
149
- imx8mm_soc_uid ();
150
158
151
- return rev ;
159
+ return imx8mm_soc_uid ( socuid ) ;
152
160
}
153
161
154
162
static const struct imx8_soc_data imx8mq_soc_data = {
@@ -179,60 +187,57 @@ static __maybe_unused const struct of_device_id imx8_soc_match[] = {
179
187
{ }
180
188
};
181
189
182
- #define imx8_revision (soc_rev ) \
183
- soc_rev ? \
184
- kasprintf( GFP_KERNEL, "%d.%d", (soc_rev >> 4) & 0xf, soc_rev & 0xf) : \
190
+ #define imx8_revision (dev , soc_rev ) \
191
+ ( soc_rev) ? \
192
+ devm_kasprintf((dev), GFP_KERNEL, "%d.%d", (( soc_rev) >> 4) & 0xf, ( soc_rev) & 0xf) : \
185
193
"unknown"
186
194
187
- static int __init imx8_soc_init ( void )
195
+ static int imx8m_soc_probe ( struct platform_device * pdev )
188
196
{
189
197
struct soc_device_attribute * soc_dev_attr ;
190
- struct soc_device * soc_dev ;
198
+ const struct imx8_soc_data * data ;
199
+ struct device * dev = & pdev -> dev ;
191
200
const struct of_device_id * id ;
201
+ struct soc_device * soc_dev ;
192
202
u32 soc_rev = 0 ;
193
- const struct imx8_soc_data * data ;
203
+ u64 soc_uid = 0 ;
194
204
int ret ;
195
205
196
- soc_dev_attr = kzalloc ( sizeof (* soc_dev_attr ), GFP_KERNEL );
206
+ soc_dev_attr = devm_kzalloc ( dev , sizeof (* soc_dev_attr ), GFP_KERNEL );
197
207
if (!soc_dev_attr )
198
208
return - ENOMEM ;
199
209
200
210
soc_dev_attr -> family = "Freescale i.MX" ;
201
211
202
212
ret = of_property_read_string (of_root , "model" , & soc_dev_attr -> machine );
203
213
if (ret )
204
- goto free_soc ;
214
+ return ret ;
205
215
206
216
id = of_match_node (imx8_soc_match , of_root );
207
- if (!id ) {
208
- ret = - ENODEV ;
209
- goto free_soc ;
210
- }
217
+ if (!id )
218
+ return - ENODEV ;
211
219
212
220
data = id -> data ;
213
221
if (data ) {
214
222
soc_dev_attr -> soc_id = data -> name ;
215
- if (data -> soc_revision )
216
- soc_rev = data -> soc_revision ();
223
+ if (data -> soc_revision ) {
224
+ ret = data -> soc_revision (& soc_rev , & soc_uid );
225
+ if (ret )
226
+ return ret ;
227
+ }
217
228
}
218
229
219
- soc_dev_attr -> revision = imx8_revision (soc_rev );
220
- if (!soc_dev_attr -> revision ) {
221
- ret = - ENOMEM ;
222
- goto free_soc ;
223
- }
230
+ soc_dev_attr -> revision = imx8_revision (dev , soc_rev );
231
+ if (!soc_dev_attr -> revision )
232
+ return - ENOMEM ;
224
233
225
- soc_dev_attr -> serial_number = kasprintf (GFP_KERNEL , "%016llX" , soc_uid );
226
- if (!soc_dev_attr -> serial_number ) {
227
- ret = - ENOMEM ;
228
- goto free_rev ;
229
- }
234
+ soc_dev_attr -> serial_number = devm_kasprintf (dev , GFP_KERNEL , "%016llX" , soc_uid );
235
+ if (!soc_dev_attr -> serial_number )
236
+ return - ENOMEM ;
230
237
231
238
soc_dev = soc_device_register (soc_dev_attr );
232
- if (IS_ERR (soc_dev )) {
233
- ret = PTR_ERR (soc_dev );
234
- goto free_serial_number ;
235
- }
239
+ if (IS_ERR (soc_dev ))
240
+ return PTR_ERR (soc_dev );
236
241
237
242
pr_info ("SoC: %s revision %s\n" , soc_dev_attr -> soc_id ,
238
243
soc_dev_attr -> revision );
@@ -241,15 +246,38 @@ static int __init imx8_soc_init(void)
241
246
platform_device_register_simple ("imx-cpufreq-dt" , -1 , NULL , 0 );
242
247
243
248
return 0 ;
249
+ }
244
250
245
- free_serial_number :
246
- kfree (soc_dev_attr -> serial_number );
247
- free_rev :
248
- if (strcmp (soc_dev_attr -> revision , "unknown" ))
249
- kfree (soc_dev_attr -> revision );
250
- free_soc :
251
- kfree (soc_dev_attr );
252
- return ret ;
251
+ static struct platform_driver imx8m_soc_driver = {
252
+ .probe = imx8m_soc_probe ,
253
+ .driver = {
254
+ .name = "imx8m-soc" ,
255
+ },
256
+ };
257
+
258
+ static int __init imx8_soc_init (void )
259
+ {
260
+ struct platform_device * pdev ;
261
+ int ret ;
262
+
263
+ /* No match means this is non-i.MX8M hardware, do nothing. */
264
+ if (!of_match_node (imx8_soc_match , of_root ))
265
+ return 0 ;
266
+
267
+ ret = platform_driver_register (& imx8m_soc_driver );
268
+ if (ret ) {
269
+ pr_err ("Failed to register imx8m-soc platform driver: %d\n" , ret );
270
+ return ret ;
271
+ }
272
+
273
+ pdev = platform_device_register_simple ("imx8m-soc" , -1 , NULL , 0 );
274
+ if (IS_ERR (pdev )) {
275
+ pr_err ("Failed to register imx8m-soc platform device: %ld\n" , PTR_ERR (pdev ));
276
+ platform_driver_unregister (& imx8m_soc_driver );
277
+ return PTR_ERR (pdev );
278
+ }
279
+
280
+ return 0 ;
253
281
}
254
282
device_initcall (imx8_soc_init );
255
283
MODULE_DESCRIPTION ("NXP i.MX8M SoC driver" );
0 commit comments