3030
3131struct imx8_soc_data {
3232 char * name ;
33- u32 (* soc_revision )(void );
33+ int (* soc_revision )(u32 * socrev );
3434};
3535
3636static u64 soc_uid ;
@@ -51,24 +51,29 @@ static u32 imx8mq_soc_revision_from_atf(void)
5151static inline u32 imx8mq_soc_revision_from_atf (void ) { return 0 ; };
5252#endif
5353
54- static u32 __init imx8mq_soc_revision (void )
54+ static int imx8mq_soc_revision (u32 * socrev )
5555{
5656 struct device_node * np ;
5757 void __iomem * ocotp_base ;
5858 u32 magic ;
5959 u32 rev ;
6060 struct clk * clk ;
61+ int ret ;
6162
6263 np = of_find_compatible_node (NULL , NULL , "fsl,imx8mq-ocotp" );
6364 if (!np )
64- return 0 ;
65+ return - EINVAL ;
6566
6667 ocotp_base = of_iomap (np , 0 );
67- WARN_ON (!ocotp_base );
68+ if (!ocotp_base ) {
69+ ret = - EINVAL ;
70+ goto err_iomap ;
71+ }
72+
6873 clk = of_clk_get_by_name (np , NULL );
6974 if (IS_ERR (clk )) {
70- WARN_ON ( IS_ERR ( clk ) );
71- return 0 ;
75+ ret = PTR_ERR ( clk );
76+ goto err_clk ;
7277 }
7378
7479 clk_prepare_enable (clk );
@@ -88,32 +93,45 @@ static u32 __init imx8mq_soc_revision(void)
8893 soc_uid <<= 32 ;
8994 soc_uid |= readl_relaxed (ocotp_base + OCOTP_UID_LOW );
9095
96+ * socrev = rev ;
97+
9198 clk_disable_unprepare (clk );
9299 clk_put (clk );
93100 iounmap (ocotp_base );
94101 of_node_put (np );
95102
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 ;
97110}
98111
99- static void __init imx8mm_soc_uid (void )
112+ static int imx8mm_soc_uid (void )
100113{
101114 void __iomem * ocotp_base ;
102115 struct device_node * np ;
103116 struct clk * clk ;
117+ int ret = 0 ;
104118 u32 offset = of_machine_is_compatible ("fsl,imx8mp" ) ?
105119 IMX8MP_OCOTP_UID_OFFSET : 0 ;
106120
107121 np = of_find_compatible_node (NULL , NULL , "fsl,imx8mm-ocotp" );
108122 if (!np )
109- return ;
123+ return - EINVAL ;
110124
111125 ocotp_base = of_iomap (np , 0 );
112- WARN_ON (!ocotp_base );
126+ if (!ocotp_base ) {
127+ ret = - EINVAL ;
128+ goto err_iomap ;
129+ }
130+
113131 clk = of_clk_get_by_name (np , NULL );
114132 if (IS_ERR (clk )) {
115- WARN_ON ( IS_ERR ( clk ) );
116- return ;
133+ ret = PTR_ERR ( clk );
134+ goto err_clk ;
117135 }
118136
119137 clk_prepare_enable (clk );
@@ -124,31 +142,41 @@ static void __init imx8mm_soc_uid(void)
124142
125143 clk_disable_unprepare (clk );
126144 clk_put (clk );
145+
146+ err_clk :
127147 iounmap (ocotp_base );
148+ err_iomap :
128149 of_node_put (np );
150+
151+ return ret ;
129152}
130153
131- static u32 __init imx8mm_soc_revision (void )
154+ static int imx8mm_soc_revision (u32 * socrev )
132155{
133156 struct device_node * np ;
134157 void __iomem * anatop_base ;
135- u32 rev ;
158+ int ret ;
136159
137160 np = of_find_compatible_node (NULL , NULL , "fsl,imx8mm-anatop" );
138161 if (!np )
139- return 0 ;
162+ return - EINVAL ;
140163
141164 anatop_base = of_iomap (np , 0 );
142- WARN_ON (!anatop_base );
165+ if (!anatop_base ) {
166+ ret = - EINVAL ;
167+ goto err_iomap ;
168+ }
143169
144- rev = readl_relaxed (anatop_base + ANADIG_DIGPROG_IMX8MM );
170+ * socrev = readl_relaxed (anatop_base + ANADIG_DIGPROG_IMX8MM );
145171
146172 iounmap (anatop_base );
147173 of_node_put (np );
148174
149- imx8mm_soc_uid ();
175+ return imx8mm_soc_uid ();
150176
151- return rev ;
177+ err_iomap :
178+ of_node_put (np );
179+ return ret ;
152180}
153181
154182static const struct imx8_soc_data imx8mq_soc_data = {
@@ -184,7 +212,7 @@ static __maybe_unused const struct of_device_id imx8_soc_match[] = {
184212 kasprintf(GFP_KERNEL, "%d.%d", (soc_rev >> 4) & 0xf, soc_rev & 0xf) : \
185213 "unknown"
186214
187- static int __init imx8_soc_init ( void )
215+ static int imx8m_soc_probe ( struct platform_device * pdev )
188216{
189217 struct soc_device_attribute * soc_dev_attr ;
190218 struct soc_device * soc_dev ;
@@ -212,8 +240,11 @@ static int __init imx8_soc_init(void)
212240 data = id -> data ;
213241 if (data ) {
214242 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+ }
217248 }
218249
219250 soc_dev_attr -> revision = imx8_revision (soc_rev );
@@ -251,4 +282,36 @@ static int __init imx8_soc_init(void)
251282 kfree (soc_dev_attr );
252283 return ret ;
253284}
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+ }
254317device_initcall (imx8_soc_init );
0 commit comments