From b782030fcf3e0fd790f0972a439d4431a2fa0224 Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 9 May 2017 16:43:35 +0100 Subject: 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 --- drivers/net/phy/sfp.c | 9 +++++++++ 1 file changed, 9 insertions(+) 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 #include #include +#include #include #include #include @@ -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]) -- cgit