mirror of
https://github.com/hardkernel/linux.git
synced 2026-03-25 20:10:23 +09:00
net: stmmac:fix system hang when setting up tag_8021q VLAN for DSA ports
[ Upstream commit35226750f7] The system hang because of dsa_tag_8021q_port_setup()-> stmmac_vlan_rx_add_vid(). I found in stmmac_drv_probe() that cailing pm_runtime_put() disabled the clock. First, when the kernel is compiled with CONFIG_PM=y,The stmmac's resume/suspend is active. Secondly,stmmac as DSA master,the dsa_tag_8021q_port_setup() function will callback stmmac_vlan_rx_add_vid when DSA dirver starts. However, The system is hanged for the stmmac_vlan_rx_add_vid() accesses its registers after stmmac's clock is closed. I would suggest adding the pm_runtime_resume_and_get() to the stmmac_vlan_rx_add_vid().This guarantees that resuming clock output while in use. Fixes:b3dcb31277("net: stmmac: correct clocks enabled in stmmac_vlan_rx_kill_vid()") Reviewed-by: Jacob Keller <jacob.e.keller@intel.com> Signed-off-by: Yan Wang <rk.code@outlook.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
a9e96eef82
commit
77f245ce05
@@ -6283,6 +6283,10 @@ static int stmmac_vlan_rx_add_vid(struct net_device *ndev, __be16 proto, u16 vid
|
||||
bool is_double = false;
|
||||
int ret;
|
||||
|
||||
ret = pm_runtime_resume_and_get(priv->device);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (be16_to_cpu(proto) == ETH_P_8021AD)
|
||||
is_double = true;
|
||||
|
||||
@@ -6290,16 +6294,18 @@ static int stmmac_vlan_rx_add_vid(struct net_device *ndev, __be16 proto, u16 vid
|
||||
ret = stmmac_vlan_update(priv, is_double);
|
||||
if (ret) {
|
||||
clear_bit(vid, priv->active_vlans);
|
||||
return ret;
|
||||
goto err_pm_put;
|
||||
}
|
||||
|
||||
if (priv->hw->num_vlan) {
|
||||
ret = stmmac_add_hw_vlan_rx_fltr(priv, ndev, priv->hw, proto, vid);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto err_pm_put;
|
||||
}
|
||||
err_pm_put:
|
||||
pm_runtime_put(priv->device);
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int stmmac_vlan_rx_kill_vid(struct net_device *ndev, __be16 proto, u16 vid)
|
||||
|
||||
Reference in New Issue
Block a user