@@ -197,55 +197,67 @@ static int mac_probe(struct platform_device *_of_dev)
197
197
err = - EINVAL ;
198
198
goto _return_of_node_put ;
199
199
}
200
+ mac_dev -> fman_dev = & of_dev -> dev ;
200
201
201
202
/* Get the FMan cell-index */
202
203
err = of_property_read_u32 (dev_node , "cell-index" , & val );
203
204
if (err ) {
204
205
dev_err (dev , "failed to read cell-index for %pOF\n" , dev_node );
205
206
err = - EINVAL ;
206
- goto _return_of_node_put ;
207
+ goto _return_dev_put ;
207
208
}
208
209
/* cell-index 0 => FMan id 1 */
209
210
fman_id = (u8 )(val + 1 );
210
211
211
- priv -> fman = fman_bind (& of_dev -> dev );
212
+ priv -> fman = fman_bind (mac_dev -> fman_dev );
212
213
if (!priv -> fman ) {
213
214
dev_err (dev , "fman_bind(%pOF) failed\n" , dev_node );
214
215
err = - ENODEV ;
215
- goto _return_of_node_put ;
216
+ goto _return_dev_put ;
216
217
}
217
218
219
+ /* Two references have been taken in of_find_device_by_node()
220
+ * and fman_bind(). Release one of them here. The second one
221
+ * will be released in mac_remove().
222
+ */
223
+ put_device (mac_dev -> fman_dev );
218
224
of_node_put (dev_node );
225
+ dev_node = NULL ;
219
226
220
227
/* Get the address of the memory mapped registers */
221
228
mac_dev -> res = platform_get_mem_or_io (_of_dev , 0 );
222
229
if (!mac_dev -> res ) {
223
230
dev_err (dev , "could not get registers\n" );
224
- return - EINVAL ;
231
+ err = - EINVAL ;
232
+ goto _return_dev_put ;
225
233
}
226
234
227
235
err = devm_request_resource (dev , fman_get_mem_region (priv -> fman ),
228
236
mac_dev -> res );
229
237
if (err ) {
230
238
dev_err_probe (dev , err , "could not request resource\n" );
231
- return err ;
239
+ goto _return_dev_put ;
232
240
}
233
241
234
242
mac_dev -> vaddr = devm_ioremap (dev , mac_dev -> res -> start ,
235
243
resource_size (mac_dev -> res ));
236
244
if (!mac_dev -> vaddr ) {
237
245
dev_err (dev , "devm_ioremap() failed\n" );
238
- return - EIO ;
246
+ err = - EIO ;
247
+ goto _return_dev_put ;
239
248
}
240
249
241
- if (!of_device_is_available (mac_node ))
242
- return - ENODEV ;
250
+ if (!of_device_is_available (mac_node )) {
251
+ err = - ENODEV ;
252
+ goto _return_dev_put ;
253
+ }
243
254
244
255
/* Get the cell-index */
245
256
err = of_property_read_u32 (mac_node , "cell-index" , & val );
246
257
if (err ) {
247
258
dev_err (dev , "failed to read cell-index for %pOF\n" , mac_node );
248
- return - EINVAL ;
259
+ err = - EINVAL ;
260
+ goto _return_dev_put ;
249
261
}
250
262
priv -> cell_index = (u8 )val ;
251
263
@@ -259,40 +271,51 @@ static int mac_probe(struct platform_device *_of_dev)
259
271
if (unlikely (nph < 0 )) {
260
272
dev_err (dev , "of_count_phandle_with_args(%pOF, fsl,fman-ports) failed\n" ,
261
273
mac_node );
262
- return nph ;
274
+ err = nph ;
275
+ goto _return_dev_put ;
263
276
}
264
277
265
278
if (nph != ARRAY_SIZE (mac_dev -> port )) {
266
279
dev_err (dev , "Not supported number of fman-ports handles of mac node %pOF from device tree\n" ,
267
280
mac_node );
268
- return - EINVAL ;
281
+ err = - EINVAL ;
282
+ goto _return_dev_put ;
269
283
}
270
284
271
- for (i = 0 ; i < ARRAY_SIZE (mac_dev -> port ); i ++ ) {
285
+ /* PORT_NUM determines the size of the port array */
286
+ for (i = 0 ; i < PORT_NUM ; i ++ ) {
272
287
/* Find the port node */
273
288
dev_node = of_parse_phandle (mac_node , "fsl,fman-ports" , i );
274
289
if (!dev_node ) {
275
290
dev_err (dev , "of_parse_phandle(%pOF, fsl,fman-ports) failed\n" ,
276
291
mac_node );
277
- return - EINVAL ;
292
+ err = - EINVAL ;
293
+ goto _return_dev_arr_put ;
278
294
}
279
295
280
296
of_dev = of_find_device_by_node (dev_node );
281
297
if (!of_dev ) {
282
298
dev_err (dev , "of_find_device_by_node(%pOF) failed\n" ,
283
299
dev_node );
284
300
err = - EINVAL ;
285
- goto _return_of_node_put ;
301
+ goto _return_dev_arr_put ;
286
302
}
303
+ mac_dev -> fman_port_devs [i ] = & of_dev -> dev ;
287
304
288
- mac_dev -> port [i ] = fman_port_bind (& of_dev -> dev );
305
+ mac_dev -> port [i ] = fman_port_bind (mac_dev -> fman_port_devs [ i ] );
289
306
if (!mac_dev -> port [i ]) {
290
307
dev_err (dev , "dev_get_drvdata(%pOF) failed\n" ,
291
308
dev_node );
292
309
err = - EINVAL ;
293
- goto _return_of_node_put ;
310
+ goto _return_dev_arr_put ;
294
311
}
312
+ /* Two references have been taken in of_find_device_by_node()
313
+ * and fman_port_bind(). Release one of them here. The second
314
+ * one will be released in mac_remove().
315
+ */
316
+ put_device (mac_dev -> fman_port_devs [i ]);
295
317
of_node_put (dev_node );
318
+ dev_node = NULL ;
296
319
}
297
320
298
321
/* Get the PHY connection type */
@@ -312,7 +335,7 @@ static int mac_probe(struct platform_device *_of_dev)
312
335
313
336
err = init (mac_dev , mac_node , & params );
314
337
if (err < 0 )
315
- return err ;
338
+ goto _return_dev_arr_put ;
316
339
317
340
if (!is_zero_ether_addr (mac_dev -> addr ))
318
341
dev_info (dev , "FMan MAC address: %pM\n" , mac_dev -> addr );
@@ -327,6 +350,12 @@ static int mac_probe(struct platform_device *_of_dev)
327
350
328
351
return err ;
329
352
353
+ _return_dev_arr_put :
354
+ /* mac_dev is kzalloc'ed */
355
+ for (i = 0 ; i < PORT_NUM ; i ++ )
356
+ put_device (mac_dev -> fman_port_devs [i ]);
357
+ _return_dev_put :
358
+ put_device (mac_dev -> fman_dev );
330
359
_return_of_node_put :
331
360
of_node_put (dev_node );
332
361
return err ;
@@ -335,6 +364,11 @@ static int mac_probe(struct platform_device *_of_dev)
335
364
static void mac_remove (struct platform_device * pdev )
336
365
{
337
366
struct mac_device * mac_dev = platform_get_drvdata (pdev );
367
+ int i ;
368
+
369
+ for (i = 0 ; i < PORT_NUM ; i ++ )
370
+ put_device (mac_dev -> fman_port_devs [i ]);
371
+ put_device (mac_dev -> fman_dev );
338
372
339
373
platform_device_unregister (mac_dev -> priv -> eth_dev );
340
374
}
0 commit comments