diff options
author | Russell King <rmk+kernel@armlinux.org.uk> | 2017-05-09 16:43:35 +0100 |
---|---|---|
committer | Russell King <rmk+kernel@armlinux.org.uk> | 2017-05-09 18:08:27 +0100 |
commit | b782030fcf3e0fd790f0972a439d4431a2fa0224 (patch) | |
tree | c2587d0c11fb65726088fc49c7a8fc135d06b806 | |
parent | 2546b8933d66fdec4ece43606d46f395b6e550e3 (diff) |
sfp: hold the rtnetlink lock while calling phylink
Hold the rtnetlink lock while causing phylink to prevent changes to
the networking configuration. This will allow us to eliminate the
configuration locking in phylink, and thus simplify the locking
strategy.
This will also allow phylink to attach the phy directly to the net
device, so allowing a reduction in veneer code.
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
-rw-r--r-- | drivers/net/phy/sfp.c | 9 |
1 files changed, 9 insertions, 0 deletions
diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c index 294f59e140b0..e8ab34879a96 100644 --- a/drivers/net/phy/sfp.c +++ b/drivers/net/phy/sfp.c @@ -10,6 +10,7 @@ #include <linux/of_net.h> #include <linux/phylink.h> #include <linux/platform_device.h> +#include <linux/rtnetlink.h> #include <linux/sfp.h> #include <linux/slab.h> #include <linux/workqueue.h> @@ -1045,7 +1046,9 @@ static void sfp_timeout(struct work_struct *work) { struct sfp *sfp = container_of(work, struct sfp, timeout.work); + rtnl_lock(); sfp_sm_event(sfp, SFP_E_TIMEOUT); + rtnl_unlock(); } static void sfp_check_state(struct sfp *sfp) @@ -1064,6 +1067,7 @@ static void sfp_check_state(struct sfp *sfp) state |= sfp->state & (SFP_F_TX_DISABLE | SFP_F_RATE_SELECT); sfp->state = state; + rtnl_lock(); if (changed & SFP_F_PRESENT) sfp_sm_event(sfp, state & SFP_F_PRESENT ? SFP_E_INSERT : SFP_E_REMOVE); @@ -1075,6 +1079,7 @@ static void sfp_check_state(struct sfp *sfp) if (changed & SFP_F_LOS) sfp_sm_event(sfp, state & SFP_F_LOS ? SFP_E_LOS_HIGH : SFP_E_LOS_LOW); + rtnl_unlock(); } static irqreturn_t sfp_irq(int irq, void *data) @@ -1232,8 +1237,10 @@ static int sfp_probe(struct platform_device *pdev) return -EPROBE_DEFER; } + rtnl_lock(); phylink_disable(sfp->phylink); phylink_register_module(sfp->phylink, sfp, &sfp_module_ops); + rtnl_unlock(); } /* Get the initial state, and always signal TX disable, @@ -1246,8 +1253,10 @@ static int sfp_probe(struct platform_device *pdev) sfp->state |= SFP_F_RATE_SELECT; sfp_set_state(sfp, sfp->state); sfp_module_tx_disable(sfp); + rtnl_lock(); if (sfp->state & SFP_F_PRESENT) sfp_sm_event(sfp, SFP_E_INSERT); + rtnl_unlock(); for (i = 0; i < GPIO_MAX; i++) { if (gpio_flags[i] != GPIOD_IN || !sfp->gpio[i]) |