Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: dsa: microchip: add port_cleanup function

Add port_cleanup function to reset some device variables when the port is
disabled. Add a mutex to make sure changing those variables is
thread-safe.

Signed-off-by: Tristram Ha <Tristram.Ha@microchip.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Tristram Ha and committed by
David S. Miller
7049f9b5 6ca50815

+31
+6
drivers/net/dsa/microchip/ksz9477.c
··· 450 450 break; 451 451 452 452 member = dev->host_mask | p->vid_member; 453 + mutex_lock(&dev->dev_mutex); 453 454 454 455 /* Port is a member of a bridge. */ 455 456 if (dev->br_member & (1 << port)) { 456 457 dev->member |= (1 << port); 457 458 member = dev->member; 458 459 } 460 + mutex_unlock(&dev->dev_mutex); 459 461 break; 460 462 case BR_STATE_BLOCKING: 461 463 data |= PORT_LEARN_DISABLE; ··· 472 470 473 471 ksz_pwrite8(dev, port, P_STP_CTRL, data); 474 472 p->stp_state = state; 473 + mutex_lock(&dev->dev_mutex); 475 474 if (data & PORT_RX_ENABLE) 476 475 dev->rx_ports |= (1 << port); 477 476 else ··· 497 494 */ 498 495 if (forward != dev->member) 499 496 ksz_update_port_member(dev, port); 497 + mutex_unlock(&dev->dev_mutex); 500 498 } 501 499 502 500 static void ksz9477_flush_dyn_mac_table(struct ksz_device *dev, int port) ··· 1084 1080 ksz_pwrite8(dev, port, REG_PORT_XMII_CTRL_1, data8); 1085 1081 p->phydev.duplex = 1; 1086 1082 } 1083 + mutex_lock(&dev->dev_mutex); 1087 1084 if (cpu_port) { 1088 1085 member = dev->port_mask; 1089 1086 dev->on_ports = dev->host_mask; ··· 1097 1092 if (p->phydev.link) 1098 1093 dev->live_ports |= (1 << port); 1099 1094 } 1095 + mutex_unlock(&dev->dev_mutex); 1100 1096 ksz9477_cfg_port_member(dev, port, member); 1101 1097 1102 1098 /* clear pending interrupts */
+22
drivers/net/dsa/microchip/ksz_common.c
··· 20 20 21 21 #include "ksz_priv.h" 22 22 23 + void ksz_port_cleanup(struct ksz_device *dev, int port) 24 + { 25 + /* Common code for port cleanup. */ 26 + mutex_lock(&dev->dev_mutex); 27 + dev->on_ports &= ~(1 << port); 28 + dev->live_ports &= ~(1 << port); 29 + mutex_unlock(&dev->dev_mutex); 30 + } 31 + EXPORT_SYMBOL_GPL(ksz_port_cleanup); 32 + 23 33 void ksz_update_port_member(struct ksz_device *dev, int port) 24 34 { 25 35 struct ksz_port *p; ··· 161 151 p->read = true; 162 152 schedule_work(&dev->mib_read); 163 153 } 154 + mutex_lock(&dev->dev_mutex); 155 + if (!phydev->link) 156 + dev->live_ports &= ~(1 << port); 157 + else 158 + /* Remember which port is connected and active. */ 159 + dev->live_ports |= (1 << port) & dev->on_ports; 160 + mutex_unlock(&dev->dev_mutex); 164 161 } 165 162 EXPORT_SYMBOL_GPL(ksz_adjust_link); 166 163 ··· 205 188 { 206 189 struct ksz_device *dev = ds->priv; 207 190 191 + mutex_lock(&dev->dev_mutex); 208 192 dev->br_member |= (1 << port); 193 + mutex_unlock(&dev->dev_mutex); 209 194 210 195 /* port_stp_state_set() will be called after to put the port in 211 196 * appropriate state so there is no need to do anything. ··· 222 203 { 223 204 struct ksz_device *dev = ds->priv; 224 205 206 + mutex_lock(&dev->dev_mutex); 225 207 dev->br_member &= ~(1 << port); 226 208 dev->member &= ~(1 << port); 209 + mutex_unlock(&dev->dev_mutex); 227 210 228 211 /* port_stp_state_set() will be called after to put the port in 229 212 * forwarding state so there is no need to do anything. ··· 438 417 gpiod_set_value(dev->reset_gpio, 0); 439 418 } 440 419 420 + mutex_init(&dev->dev_mutex); 441 421 mutex_init(&dev->reg_mutex); 442 422 mutex_init(&dev->stats_mutex); 443 423 mutex_init(&dev->alu_mutex);
+1
drivers/net/dsa/microchip/ksz_common.h
··· 7 7 #ifndef __KSZ_COMMON_H 8 8 #define __KSZ_COMMON_H 9 9 10 + void ksz_port_cleanup(struct ksz_device *dev, int port); 10 11 void ksz_update_port_member(struct ksz_device *dev, int port); 11 12 void ksz_init_mib_timer(struct ksz_device *dev); 12 13
+2
drivers/net/dsa/microchip/ksz_priv.h
··· 48 48 struct ksz_platform_data *pdata; 49 49 const char *name; 50 50 51 + struct mutex dev_mutex; /* device access */ 51 52 struct mutex reg_mutex; /* register access */ 52 53 struct mutex stats_mutex; /* status access */ 53 54 struct mutex alu_mutex; /* ALU access */ ··· 138 137 void (*flush_dyn_mac_table)(struct ksz_device *dev, int port); 139 138 void (*phy_setup)(struct ksz_device *dev, int port, 140 139 struct phy_device *phy); 140 + void (*port_cleanup)(struct ksz_device *dev, int port); 141 141 void (*port_setup)(struct ksz_device *dev, int port, bool cpu_port); 142 142 void (*r_phy)(struct ksz_device *dev, u16 phy, u16 reg, u16 *val); 143 143 void (*w_phy)(struct ksz_device *dev, u16 phy, u16 reg, u16 val);