3030
3131struct imx8_soc_data {
3232 char * name ;
33- u32 (* soc_revision )(void );
33+ int (* soc_revision )(u32 * socrev , u64 * socuid );
3434};
3535
36- static u64 soc_uid ;
37-
3836#ifdef CONFIG_HAVE_ARM_SMCCC
3937static u32 imx8mq_soc_revision_from_atf (void )
4038{
@@ -51,24 +49,27 @@ static u32 imx8mq_soc_revision_from_atf(void)
5149static inline u32 imx8mq_soc_revision_from_atf (void ) { return 0 ; };
5250#endif
5351
54- static u32 __init imx8mq_soc_revision (void )
52+ static int imx8mq_soc_revision (u32 * socrev , u64 * socuid )
5553{
56- struct device_node * np ;
54+ struct device_node * np __free (device_node ) =
55+ of_find_compatible_node (NULL , NULL , "fsl,imx8mq-ocotp" );
5756 void __iomem * ocotp_base ;
5857 u32 magic ;
5958 u32 rev ;
6059 struct clk * clk ;
60+ int ret ;
6161
62- np = of_find_compatible_node (NULL , NULL , "fsl,imx8mq-ocotp" );
6362 if (!np )
64- return 0 ;
63+ return - EINVAL ;
6564
6665 ocotp_base = of_iomap (np , 0 );
67- WARN_ON (!ocotp_base );
66+ if (!ocotp_base )
67+ return - EINVAL ;
68+
6869 clk = of_clk_get_by_name (np , NULL );
6970 if (IS_ERR (clk )) {
70- WARN_ON ( IS_ERR ( clk ) );
71- return 0 ;
71+ ret = PTR_ERR ( clk );
72+ goto err_clk ;
7273 }
7374
7475 clk_prepare_enable (clk );
@@ -84,71 +85,78 @@ static u32 __init imx8mq_soc_revision(void)
8485 rev = REV_B1 ;
8586 }
8687
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 ;
9093
9194 clk_disable_unprepare (clk );
9295 clk_put (clk );
9396 iounmap (ocotp_base );
94- of_node_put (np );
9597
96- return rev ;
98+ return 0 ;
99+
100+ err_clk :
101+ iounmap (ocotp_base );
102+ return ret ;
97103}
98104
99- static void __init imx8mm_soc_uid (void )
105+ static int imx8mm_soc_uid (u64 * socuid )
100106{
107+ struct device_node * np __free (device_node ) =
108+ of_find_compatible_node (NULL , NULL , "fsl,imx8mm-ocotp" );
101109 void __iomem * ocotp_base ;
102- struct device_node * np ;
103110 struct clk * clk ;
111+ int ret = 0 ;
104112 u32 offset = of_machine_is_compatible ("fsl,imx8mp" ) ?
105113 IMX8MP_OCOTP_UID_OFFSET : 0 ;
106114
107- np = of_find_compatible_node (NULL , NULL , "fsl,imx8mm-ocotp" );
108115 if (!np )
109- return ;
116+ return - EINVAL ;
110117
111118 ocotp_base = of_iomap (np , 0 );
112- WARN_ON (!ocotp_base );
119+ if (!ocotp_base )
120+ return - EINVAL ;
121+
113122 clk = of_clk_get_by_name (np , NULL );
114123 if (IS_ERR (clk )) {
115- WARN_ON ( IS_ERR ( clk ) );
116- return ;
124+ ret = PTR_ERR ( clk );
125+ goto err_clk ;
117126 }
118127
119128 clk_prepare_enable (clk );
120129
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 );
124133
125134 clk_disable_unprepare (clk );
126135 clk_put (clk );
136+
137+ err_clk :
127138 iounmap (ocotp_base );
128- of_node_put ( np ) ;
139+ return ret ;
129140}
130141
131- static u32 __init imx8mm_soc_revision (void )
142+ static int imx8mm_soc_revision (u32 * socrev , u64 * socuid )
132143{
133- struct device_node * np ;
144+ struct device_node * np __free (device_node ) =
145+ of_find_compatible_node (NULL , NULL , "fsl,imx8mm-anatop" );
134146 void __iomem * anatop_base ;
135- u32 rev ;
136147
137- np = of_find_compatible_node (NULL , NULL , "fsl,imx8mm-anatop" );
138148 if (!np )
139- return 0 ;
149+ return - EINVAL ;
140150
141151 anatop_base = of_iomap (np , 0 );
142- WARN_ON (!anatop_base );
152+ if (!anatop_base )
153+ return - EINVAL ;
143154
144- rev = readl_relaxed (anatop_base + ANADIG_DIGPROG_IMX8MM );
155+ * socrev = readl_relaxed (anatop_base + ANADIG_DIGPROG_IMX8MM );
145156
146157 iounmap (anatop_base );
147- of_node_put (np );
148-
149- imx8mm_soc_uid ();
150158
151- return rev ;
159+ return imx8mm_soc_uid ( socuid ) ;
152160}
153161
154162static const struct imx8_soc_data imx8mq_soc_data = {
@@ -179,60 +187,57 @@ static __maybe_unused const struct of_device_id imx8_soc_match[] = {
179187 { }
180188};
181189
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) : \
185193 "unknown"
186194
187- static int __init imx8_soc_init ( void )
195+ static int imx8m_soc_probe ( struct platform_device * pdev )
188196{
189197 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 ;
191200 const struct of_device_id * id ;
201+ struct soc_device * soc_dev ;
192202 u32 soc_rev = 0 ;
193- const struct imx8_soc_data * data ;
203+ u64 soc_uid = 0 ;
194204 int ret ;
195205
196- soc_dev_attr = kzalloc ( sizeof (* soc_dev_attr ), GFP_KERNEL );
206+ soc_dev_attr = devm_kzalloc ( dev , sizeof (* soc_dev_attr ), GFP_KERNEL );
197207 if (!soc_dev_attr )
198208 return - ENOMEM ;
199209
200210 soc_dev_attr -> family = "Freescale i.MX" ;
201211
202212 ret = of_property_read_string (of_root , "model" , & soc_dev_attr -> machine );
203213 if (ret )
204- goto free_soc ;
214+ return ret ;
205215
206216 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 ;
211219
212220 data = id -> data ;
213221 if (data ) {
214222 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+ }
217228 }
218229
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 ;
224233
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 ;
230237
231238 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 );
236241
237242 pr_info ("SoC: %s revision %s\n" , soc_dev_attr -> soc_id ,
238243 soc_dev_attr -> revision );
@@ -241,15 +246,38 @@ static int __init imx8_soc_init(void)
241246 platform_device_register_simple ("imx-cpufreq-dt" , -1 , NULL , 0 );
242247
243248 return 0 ;
249+ }
244250
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 ;
253281}
254282device_initcall (imx8_soc_init );
255283MODULE_DESCRIPTION ("NXP i.MX8M SoC driver" );
0 commit comments