30
30
31
31
struct imx8_soc_data {
32
32
char * name ;
33
- u32 (* soc_revision )(void );
33
+ int (* soc_revision )(u32 * socrev );
34
34
};
35
35
36
36
static u64 soc_uid ;
@@ -51,24 +51,29 @@ static u32 imx8mq_soc_revision_from_atf(void)
51
51
static inline u32 imx8mq_soc_revision_from_atf (void ) { return 0 ; };
52
52
#endif
53
53
54
- static u32 __init imx8mq_soc_revision (void )
54
+ static int imx8mq_soc_revision (u32 * socrev )
55
55
{
56
56
struct device_node * np ;
57
57
void __iomem * ocotp_base ;
58
58
u32 magic ;
59
59
u32 rev ;
60
60
struct clk * clk ;
61
+ int ret ;
61
62
62
63
np = of_find_compatible_node (NULL , NULL , "fsl,imx8mq-ocotp" );
63
64
if (!np )
64
- return 0 ;
65
+ return - EINVAL ;
65
66
66
67
ocotp_base = of_iomap (np , 0 );
67
- WARN_ON (!ocotp_base );
68
+ if (!ocotp_base ) {
69
+ ret = - EINVAL ;
70
+ goto err_iomap ;
71
+ }
72
+
68
73
clk = of_clk_get_by_name (np , NULL );
69
74
if (IS_ERR (clk )) {
70
- WARN_ON ( IS_ERR ( clk ) );
71
- return 0 ;
75
+ ret = PTR_ERR ( clk );
76
+ goto err_clk ;
72
77
}
73
78
74
79
clk_prepare_enable (clk );
@@ -88,32 +93,45 @@ static u32 __init imx8mq_soc_revision(void)
88
93
soc_uid <<= 32 ;
89
94
soc_uid |= readl_relaxed (ocotp_base + OCOTP_UID_LOW );
90
95
96
+ * socrev = rev ;
97
+
91
98
clk_disable_unprepare (clk );
92
99
clk_put (clk );
93
100
iounmap (ocotp_base );
94
101
of_node_put (np );
95
102
96
- return rev ;
103
+ return 0 ;
104
+
105
+ err_clk :
106
+ iounmap (ocotp_base );
107
+ err_iomap :
108
+ of_node_put (np );
109
+ return ret ;
97
110
}
98
111
99
- static void __init imx8mm_soc_uid (void )
112
+ static int imx8mm_soc_uid (void )
100
113
{
101
114
void __iomem * ocotp_base ;
102
115
struct device_node * np ;
103
116
struct clk * clk ;
117
+ int ret = 0 ;
104
118
u32 offset = of_machine_is_compatible ("fsl,imx8mp" ) ?
105
119
IMX8MP_OCOTP_UID_OFFSET : 0 ;
106
120
107
121
np = of_find_compatible_node (NULL , NULL , "fsl,imx8mm-ocotp" );
108
122
if (!np )
109
- return ;
123
+ return - EINVAL ;
110
124
111
125
ocotp_base = of_iomap (np , 0 );
112
- WARN_ON (!ocotp_base );
126
+ if (!ocotp_base ) {
127
+ ret = - EINVAL ;
128
+ goto err_iomap ;
129
+ }
130
+
113
131
clk = of_clk_get_by_name (np , NULL );
114
132
if (IS_ERR (clk )) {
115
- WARN_ON ( IS_ERR ( clk ) );
116
- return ;
133
+ ret = PTR_ERR ( clk );
134
+ goto err_clk ;
117
135
}
118
136
119
137
clk_prepare_enable (clk );
@@ -124,31 +142,41 @@ static void __init imx8mm_soc_uid(void)
124
142
125
143
clk_disable_unprepare (clk );
126
144
clk_put (clk );
145
+
146
+ err_clk :
127
147
iounmap (ocotp_base );
148
+ err_iomap :
128
149
of_node_put (np );
150
+
151
+ return ret ;
129
152
}
130
153
131
- static u32 __init imx8mm_soc_revision (void )
154
+ static int imx8mm_soc_revision (u32 * socrev )
132
155
{
133
156
struct device_node * np ;
134
157
void __iomem * anatop_base ;
135
- u32 rev ;
158
+ int ret ;
136
159
137
160
np = of_find_compatible_node (NULL , NULL , "fsl,imx8mm-anatop" );
138
161
if (!np )
139
- return 0 ;
162
+ return - EINVAL ;
140
163
141
164
anatop_base = of_iomap (np , 0 );
142
- WARN_ON (!anatop_base );
165
+ if (!anatop_base ) {
166
+ ret = - EINVAL ;
167
+ goto err_iomap ;
168
+ }
143
169
144
- rev = readl_relaxed (anatop_base + ANADIG_DIGPROG_IMX8MM );
170
+ * socrev = readl_relaxed (anatop_base + ANADIG_DIGPROG_IMX8MM );
145
171
146
172
iounmap (anatop_base );
147
173
of_node_put (np );
148
174
149
- imx8mm_soc_uid ();
175
+ return imx8mm_soc_uid ();
150
176
151
- return rev ;
177
+ err_iomap :
178
+ of_node_put (np );
179
+ return ret ;
152
180
}
153
181
154
182
static const struct imx8_soc_data imx8mq_soc_data = {
@@ -184,7 +212,7 @@ static __maybe_unused const struct of_device_id imx8_soc_match[] = {
184
212
kasprintf(GFP_KERNEL, "%d.%d", (soc_rev >> 4) & 0xf, soc_rev & 0xf) : \
185
213
"unknown"
186
214
187
- static int __init imx8_soc_init ( void )
215
+ static int imx8m_soc_probe ( struct platform_device * pdev )
188
216
{
189
217
struct soc_device_attribute * soc_dev_attr ;
190
218
struct soc_device * soc_dev ;
@@ -212,8 +240,11 @@ static int __init imx8_soc_init(void)
212
240
data = id -> data ;
213
241
if (data ) {
214
242
soc_dev_attr -> soc_id = data -> name ;
215
- if (data -> soc_revision )
216
- soc_rev = data -> soc_revision ();
243
+ if (data -> soc_revision ) {
244
+ ret = data -> soc_revision (& soc_rev );
245
+ if (ret )
246
+ goto free_soc ;
247
+ }
217
248
}
218
249
219
250
soc_dev_attr -> revision = imx8_revision (soc_rev );
@@ -251,5 +282,37 @@ static int __init imx8_soc_init(void)
251
282
kfree (soc_dev_attr );
252
283
return ret ;
253
284
}
285
+
286
+ static struct platform_driver imx8m_soc_driver = {
287
+ .probe = imx8m_soc_probe ,
288
+ .driver = {
289
+ .name = "imx8m-soc" ,
290
+ },
291
+ };
292
+
293
+ static int __init imx8_soc_init (void )
294
+ {
295
+ struct platform_device * pdev ;
296
+ int ret ;
297
+
298
+ /* No match means this is non-i.MX8M hardware, do nothing. */
299
+ if (!of_match_node (imx8_soc_match , of_root ))
300
+ return 0 ;
301
+
302
+ ret = platform_driver_register (& imx8m_soc_driver );
303
+ if (ret ) {
304
+ pr_err ("Failed to register imx8m-soc platform driver: %d\n" , ret );
305
+ return ret ;
306
+ }
307
+
308
+ pdev = platform_device_register_simple ("imx8m-soc" , -1 , NULL , 0 );
309
+ if (IS_ERR (pdev )) {
310
+ pr_err ("Failed to register imx8m-soc platform device: %ld\n" , PTR_ERR (pdev ));
311
+ platform_driver_unregister (& imx8m_soc_driver );
312
+ return PTR_ERR (pdev );
313
+ }
314
+
315
+ return 0 ;
316
+ }
254
317
device_initcall (imx8_soc_init );
255
318
MODULE_LICENSE ("GPL" );
0 commit comments