123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179 |
- From 4054955f0da08c81d42220cb445820d474f1ac92 Mon Sep 17 00:00:00 2001
- From: Russell King <[email protected]>
- Date: Sat, 14 Sep 2019 14:21:22 +0100
- Subject: [PATCH 614/660] net: sfp: move fwnode parsing into sfp-bus layer
- Rather than parsing the sfp firmware node in phylink, parse it in the
- sfp-bus code, so we can re-use this code for PHYs without having to
- duplicate the parsing.
- Signed-off-by: Russell King <[email protected]>
- ---
- drivers/net/phy/phylink.c | 21 ++++---------
- drivers/net/phy/sfp-bus.c | 65 +++++++++++++++++++++++++--------------
- include/linux/sfp.h | 10 +++---
- 3 files changed, 53 insertions(+), 43 deletions(-)
- --- a/drivers/net/phy/phylink.c
- +++ b/drivers/net/phy/phylink.c
- @@ -538,26 +538,17 @@ static const struct sfp_upstream_ops sfp
- static int phylink_register_sfp(struct phylink *pl,
- struct fwnode_handle *fwnode)
- {
- - struct fwnode_reference_args ref;
- + struct sfp_bus *bus;
- int ret;
-
- - if (!fwnode)
- - return 0;
- -
- - ret = fwnode_property_get_reference_args(fwnode, "sfp", NULL,
- - 0, 0, &ref);
- - if (ret < 0) {
- - if (ret == -ENOENT)
- - return 0;
- -
- - netdev_err(pl->netdev, "unable to parse \"sfp\" node: %d\n",
- - ret);
- + bus = sfp_register_upstream_node(fwnode, pl, &sfp_phylink_ops);
- + if (IS_ERR(bus)) {
- + ret = PTR_ERR(bus);
- + netdev_err(pl->netdev, "unable to attach SFP bus: %d\n", ret);
- return ret;
- }
-
- - pl->sfp_bus = sfp_register_upstream(ref.fwnode, pl, &sfp_phylink_ops);
- - if (!pl->sfp_bus)
- - return -ENOMEM;
- + pl->sfp_bus = bus;
-
- return 0;
- }
- --- a/drivers/net/phy/sfp-bus.c
- +++ b/drivers/net/phy/sfp-bus.c
- @@ -3,6 +3,7 @@
- #include <linux/list.h>
- #include <linux/mutex.h>
- #include <linux/phylink.h>
- +#include <linux/property.h>
- #include <linux/rtnetlink.h>
- #include <linux/slab.h>
-
- @@ -444,45 +445,63 @@ static void sfp_upstream_clear(struct sf
- }
-
- /**
- - * sfp_register_upstream() - Register the neighbouring device
- - * @fwnode: firmware node for the SFP bus
- + * sfp_register_upstream_node() - parse and register the neighbouring device
- + * @fwnode: firmware node for the parent device (MAC or PHY)
- * @upstream: the upstream private data
- * @ops: the upstream's &struct sfp_upstream_ops
- *
- - * Register the upstream device (eg, PHY) with the SFP bus. MAC drivers
- - * should use phylink, which will call this function for them. Returns
- - * a pointer to the allocated &struct sfp_bus.
- + * Parse the parent device's firmware node for a SFP bus, and register the
- + * SFP bus using sfp_register_upstream().
- *
- - * On error, returns %NULL.
- + * Returns: on success, a pointer to the sfp_bus structure,
- + * %NULL if no SFP is specified,
- + * on failure, an error pointer value:
- + * corresponding to the errors detailed for
- + * fwnode_property_get_reference_args().
- + * %-ENOMEM if we failed to allocate the bus.
- + * an error from the upstream's connect_phy() method.
- */
- -struct sfp_bus *sfp_register_upstream(struct fwnode_handle *fwnode,
- - void *upstream,
- - const struct sfp_upstream_ops *ops)
- -{
- - struct sfp_bus *bus = sfp_bus_get(fwnode);
- - int ret = 0;
- -
- - if (bus) {
- - rtnl_lock();
- - bus->upstream_ops = ops;
- - bus->upstream = upstream;
- +struct sfp_bus *sfp_register_upstream_node(struct fwnode_handle *fwnode,
- + void *upstream,
- + const struct sfp_upstream_ops *ops)
- +{
- + struct fwnode_reference_args ref;
- + struct sfp_bus *bus;
- + int ret;
-
- - if (bus->sfp) {
- - ret = sfp_register_bus(bus);
- - if (ret)
- - sfp_upstream_clear(bus);
- - }
- - rtnl_unlock();
- + ret = fwnode_property_get_reference_args(fwnode, "sfp", NULL,
- + 0, 0, &ref);
- + if (ret == -ENOENT)
- + return NULL;
- + else if (ret < 0)
- + return ERR_PTR(ret);
- +
- + bus = sfp_bus_get(ref.fwnode);
- + fwnode_handle_put(ref.fwnode);
- + if (!bus)
- + return ERR_PTR(-ENOMEM);
- +
- + rtnl_lock();
- + bus->upstream_ops = ops;
- + bus->upstream = upstream;
- +
- + if (bus->sfp) {
- + ret = sfp_register_bus(bus);
- + if (ret)
- + sfp_upstream_clear(bus);
- + } else {
- + ret = 0;
- }
- + rtnl_unlock();
-
- if (ret) {
- sfp_bus_put(bus);
- - bus = NULL;
- + bus = ERR_PTR(ret);
- }
-
- return bus;
- }
- -EXPORT_SYMBOL_GPL(sfp_register_upstream);
- +EXPORT_SYMBOL_GPL(sfp_register_upstream_node);
-
- /**
- * sfp_unregister_upstream() - Unregister sfp bus
- --- a/include/linux/sfp.h
- +++ b/include/linux/sfp.h
- @@ -508,9 +508,9 @@ int sfp_get_module_eeprom(struct sfp_bus
- u8 *data);
- void sfp_upstream_start(struct sfp_bus *bus);
- void sfp_upstream_stop(struct sfp_bus *bus);
- -struct sfp_bus *sfp_register_upstream(struct fwnode_handle *fwnode,
- - void *upstream,
- - const struct sfp_upstream_ops *ops);
- +struct sfp_bus *sfp_register_upstream_node(struct fwnode_handle *fwnode,
- + void *upstream,
- + const struct sfp_upstream_ops *ops);
- void sfp_unregister_upstream(struct sfp_bus *bus);
- #else
- static inline int sfp_parse_port(struct sfp_bus *bus,
- @@ -553,11 +553,11 @@ static inline void sfp_upstream_stop(str
- {
- }
-
- -static inline struct sfp_bus *sfp_register_upstream(
- +static inline struct sfp_bus *sfp_register_upstream_node(
- struct fwnode_handle *fwnode, void *upstream,
- const struct sfp_upstream_ops *ops)
- {
- - return (struct sfp_bus *)-1;
- + return NULL;
- }
-
- static inline void sfp_unregister_upstream(struct sfp_bus *bus)
|