@@ -329,10 +329,19 @@ static void sfp_bus_release(struct kref *kref)
329
329
kfree (bus );
330
330
}
331
331
332
- static void sfp_bus_put (struct sfp_bus * bus )
332
+ /**
333
+ * sfp_bus_put() - put a reference on the &struct sfp_bus
334
+ * bus: the &struct sfp_bus found via sfp_bus_find_fwnode()
335
+ *
336
+ * Put a reference on the &struct sfp_bus and free the underlying structure
337
+ * if this was the last reference.
338
+ */
339
+ void sfp_bus_put (struct sfp_bus * bus )
333
340
{
334
- kref_put_mutex (& bus -> kref , sfp_bus_release , & sfp_mutex );
341
+ if (bus )
342
+ kref_put_mutex (& bus -> kref , sfp_bus_release , & sfp_mutex );
335
343
}
344
+ EXPORT_SYMBOL_GPL (sfp_bus_put );
336
345
337
346
static int sfp_register_bus (struct sfp_bus * bus )
338
347
{
@@ -348,11 +357,11 @@ static int sfp_register_bus(struct sfp_bus *bus)
348
357
return ret ;
349
358
}
350
359
}
360
+ bus -> registered = true;
351
361
bus -> socket_ops -> attach (bus -> sfp );
352
362
if (bus -> started )
353
363
bus -> socket_ops -> start (bus -> sfp );
354
364
bus -> upstream_ops -> attach (bus -> upstream , bus );
355
- bus -> registered = true;
356
365
return 0 ;
357
366
}
358
367
@@ -446,13 +455,12 @@ static void sfp_upstream_clear(struct sfp_bus *bus)
446
455
}
447
456
448
457
/**
449
- * sfp_register_upstream_node () - parse and register the neighbouring device
458
+ * sfp_bus_find_fwnode () - parse and locate the SFP bus from fwnode
450
459
* @fwnode: firmware node for the parent device (MAC or PHY)
451
- * @upstream: the upstream private data
452
- * @ops: the upstream's &struct sfp_upstream_ops
453
460
*
454
- * Parse the parent device's firmware node for a SFP bus, and register the
455
- * SFP bus using sfp_register_upstream().
461
+ * Parse the parent device's firmware node for a SFP bus, and locate
462
+ * the sfp_bus structure, incrementing its reference count. This must
463
+ * be put via sfp_bus_put() when done.
456
464
*
457
465
* Returns: on success, a pointer to the sfp_bus structure,
458
466
* %NULL if no SFP is specified,
@@ -462,9 +470,7 @@ static void sfp_upstream_clear(struct sfp_bus *bus)
462
470
* %-ENOMEM if we failed to allocate the bus.
463
471
* an error from the upstream's connect_phy() method.
464
472
*/
465
- struct sfp_bus * sfp_register_upstream_node (struct fwnode_handle * fwnode ,
466
- void * upstream ,
467
- const struct sfp_upstream_ops * ops )
473
+ struct sfp_bus * sfp_bus_find_fwnode (struct fwnode_handle * fwnode )
468
474
{
469
475
struct fwnode_reference_args ref ;
470
476
struct sfp_bus * bus ;
@@ -482,7 +488,39 @@ struct sfp_bus *sfp_register_upstream_node(struct fwnode_handle *fwnode,
482
488
if (!bus )
483
489
return ERR_PTR (- ENOMEM );
484
490
491
+ return bus ;
492
+ }
493
+ EXPORT_SYMBOL_GPL (sfp_bus_find_fwnode );
494
+
495
+ /**
496
+ * sfp_bus_add_upstream() - parse and register the neighbouring device
497
+ * @bus: the &struct sfp_bus found via sfp_bus_find_fwnode()
498
+ * @upstream: the upstream private data
499
+ * @ops: the upstream's &struct sfp_upstream_ops
500
+ *
501
+ * Add upstream driver for the SFP bus, and if the bus is complete, register
502
+ * the SFP bus using sfp_register_upstream(). This takes a reference on the
503
+ * bus, so it is safe to put the bus after this call.
504
+ *
505
+ * Returns: on success, a pointer to the sfp_bus structure,
506
+ * %NULL if no SFP is specified,
507
+ * on failure, an error pointer value:
508
+ * corresponding to the errors detailed for
509
+ * fwnode_property_get_reference_args().
510
+ * %-ENOMEM if we failed to allocate the bus.
511
+ * an error from the upstream's connect_phy() method.
512
+ */
513
+ int sfp_bus_add_upstream (struct sfp_bus * bus , void * upstream ,
514
+ const struct sfp_upstream_ops * ops )
515
+ {
516
+ int ret ;
517
+
518
+ /* If no bus, return success */
519
+ if (!bus )
520
+ return 0 ;
521
+
485
522
rtnl_lock ();
523
+ kref_get (& bus -> kref );
486
524
bus -> upstream_ops = ops ;
487
525
bus -> upstream = upstream ;
488
526
@@ -495,33 +533,33 @@ struct sfp_bus *sfp_register_upstream_node(struct fwnode_handle *fwnode,
495
533
}
496
534
rtnl_unlock ();
497
535
498
- if (ret ) {
536
+ if (ret )
499
537
sfp_bus_put (bus );
500
- bus = ERR_PTR (ret );
501
- }
502
538
503
- return bus ;
539
+ return ret ;
504
540
}
505
- EXPORT_SYMBOL_GPL (sfp_register_upstream_node );
541
+ EXPORT_SYMBOL_GPL (sfp_bus_add_upstream );
506
542
507
543
/**
508
- * sfp_unregister_upstream () - Unregister sfp bus
544
+ * sfp_bus_del_upstream () - Delete a sfp bus
509
545
* @bus: a pointer to the &struct sfp_bus structure for the sfp module
510
546
*
511
- * Unregister a previously registered upstream connection for the SFP
512
- * module. @bus is returned from sfp_register_upstream ().
547
+ * Delete a previously registered upstream connection for the SFP
548
+ * module. @bus should have been added by sfp_bus_add_upstream ().
513
549
*/
514
- void sfp_unregister_upstream (struct sfp_bus * bus )
550
+ void sfp_bus_del_upstream (struct sfp_bus * bus )
515
551
{
516
- rtnl_lock ();
517
- if (bus -> sfp )
518
- sfp_unregister_bus (bus );
519
- sfp_upstream_clear (bus );
520
- rtnl_unlock ();
552
+ if (bus ) {
553
+ rtnl_lock ();
554
+ if (bus -> sfp )
555
+ sfp_unregister_bus (bus );
556
+ sfp_upstream_clear (bus );
557
+ rtnl_unlock ();
521
558
522
- sfp_bus_put (bus );
559
+ sfp_bus_put (bus );
560
+ }
523
561
}
524
- EXPORT_SYMBOL_GPL (sfp_unregister_upstream );
562
+ EXPORT_SYMBOL_GPL (sfp_bus_del_upstream );
525
563
526
564
/* Socket driver entry points */
527
565
int sfp_add_phy (struct sfp_bus * bus , struct phy_device * phydev )
0 commit comments