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

net: dsa: Keep the mii bus and address in the private structure

Rather than looking up the mii bus and address every time, do it once
at probe, and keep it in the private structure. Centralise this probe
code in mv88e6xxx.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Acked-by: Florian Fainelli <f.fainelli@gmail.com>
Tested-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Andrew Lunn and committed by
David S. Miller
a77d43f1 5feebd0a

+89 -83
+26 -18
drivers/net/dsa/mv88e6060.c
··· 19 19 20 20 static int reg_read(struct dsa_switch *ds, int addr, int reg) 21 21 { 22 - struct mii_bus *bus = dsa_host_dev_to_mii_bus(ds->master_dev); 22 + struct mv88e6060_priv *priv = ds_to_priv(ds); 23 23 24 - if (bus == NULL) 25 - return -EINVAL; 26 - 27 - return mdiobus_read_nested(bus, ds->pd->sw_addr + addr, reg); 24 + return mdiobus_read_nested(priv->bus, priv->sw_addr + addr, reg); 28 25 } 29 26 30 27 #define REG_READ(addr, reg) \ ··· 37 40 38 41 static int reg_write(struct dsa_switch *ds, int addr, int reg, u16 val) 39 42 { 40 - struct mii_bus *bus = dsa_host_dev_to_mii_bus(ds->master_dev); 43 + struct mv88e6060_priv *priv = ds_to_priv(ds); 41 44 42 - if (bus == NULL) 43 - return -EINVAL; 44 - 45 - return mdiobus_write_nested(bus, ds->pd->sw_addr + addr, reg, val); 45 + return mdiobus_write_nested(priv->bus, priv->sw_addr + addr, reg, val); 46 46 } 47 47 48 48 #define REG_WRITE(addr, reg, val) \ ··· 51 57 return __ret; \ 52 58 }) 53 59 54 - static char *mv88e6060_probe(struct device *dsa_dev, struct device *host_dev, 55 - int sw_addr, void **priv) 60 + static char *mv88e6060_get_name(struct mii_bus *bus, int sw_addr) 56 61 { 57 - struct mii_bus *bus = dsa_host_dev_to_mii_bus(host_dev); 58 62 int ret; 59 - 60 - *priv = NULL; 61 - if (bus == NULL) 62 - return NULL; 63 63 64 64 ret = mdiobus_read(bus, sw_addr + REG_PORT(0), PORT_SWITCH_ID); 65 65 if (ret >= 0) { ··· 67 79 } 68 80 69 81 return NULL; 82 + } 83 + 84 + static char *mv88e6060_probe(struct device *dsa_dev, struct device *host_dev, 85 + int sw_addr, void **_priv) 86 + { 87 + struct mii_bus *bus = dsa_host_dev_to_mii_bus(host_dev); 88 + struct mv88e6060_priv *priv; 89 + char *name; 90 + 91 + name = mv88e6060_get_name(bus, sw_addr); 92 + if (name) { 93 + priv = devm_kzalloc(dsa_dev, sizeof(*priv), GFP_KERNEL); 94 + if (!priv) 95 + return NULL; 96 + *_priv = priv; 97 + priv->bus = bus; 98 + priv->sw_addr = sw_addr; 99 + } 100 + 101 + return name; 70 102 } 71 103 72 104 static int mv88e6060_switch_reset(struct dsa_switch *ds) ··· 184 176 185 177 static int mv88e6060_setup(struct dsa_switch *ds) 186 178 { 187 - int i; 188 179 int ret; 180 + int i; 189 181 190 182 ret = mv88e6060_switch_reset(ds); 191 183 if (ret < 0)
+11
drivers/net/dsa/mv88e6060.h
··· 108 108 #define GLOBAL_ATU_MAC_23 0x0e 109 109 #define GLOBAL_ATU_MAC_45 0x0f 110 110 111 + struct mv88e6060_priv { 112 + /* MDIO bus and address on bus to use. When in single chip 113 + * mode, address is 0, and the switch uses multiple addresses 114 + * on the bus. When in multi-chip mode, the switch uses a 115 + * single address which contains two registers used for 116 + * indirect access to more registers. 117 + */ 118 + struct mii_bus *bus; 119 + int sw_addr; 120 + }; 121 + 111 122 #endif
+3 -12
drivers/net/dsa/mv88e6123.c
··· 32 32 static char *mv88e6123_probe(struct device *dsa_dev, struct device *host_dev, 33 33 int sw_addr, void **priv) 34 34 { 35 - struct mv88e6xxx_priv_state *ps; 36 - char *name; 37 - 38 - name = mv88e6xxx_lookup_name(host_dev, sw_addr, mv88e6123_table, 39 - ARRAY_SIZE(mv88e6123_table)); 40 - if (name) { 41 - ps = devm_kzalloc(dsa_dev, sizeof(*ps), GFP_KERNEL); 42 - if (!ps) 43 - return NULL; 44 - *priv = ps; 45 - } 46 - return name; 35 + return mv88e6xxx_drv_probe(dsa_dev, host_dev, sw_addr, priv, 36 + mv88e6123_table, 37 + ARRAY_SIZE(mv88e6123_table)); 47 38 } 48 39 49 40 static int mv88e6123_setup_global(struct dsa_switch *ds)
+3 -12
drivers/net/dsa/mv88e6131.c
··· 28 28 static char *mv88e6131_probe(struct device *dsa_dev, struct device *host_dev, 29 29 int sw_addr, void **priv) 30 30 { 31 - struct mv88e6xxx_priv_state *ps; 32 - char *name; 33 - 34 - name = mv88e6xxx_lookup_name(host_dev, sw_addr, mv88e6131_table, 35 - ARRAY_SIZE(mv88e6131_table)); 36 - if (name) { 37 - ps = devm_kzalloc(dsa_dev, sizeof(*ps), GFP_KERNEL); 38 - if (!ps) 39 - return NULL; 40 - *priv = ps; 41 - } 42 - return name; 31 + return mv88e6xxx_drv_probe(dsa_dev, host_dev, sw_addr, priv, 32 + mv88e6131_table, 33 + ARRAY_SIZE(mv88e6131_table)); 43 34 } 44 35 45 36 static int mv88e6131_setup_global(struct dsa_switch *ds)
+3 -12
drivers/net/dsa/mv88e6171.c
··· 27 27 static char *mv88e6171_probe(struct device *dsa_dev, struct device *host_dev, 28 28 int sw_addr, void **priv) 29 29 { 30 - struct mv88e6xxx_priv_state *ps; 31 - char *name; 32 - 33 - name = mv88e6xxx_lookup_name(host_dev, sw_addr, mv88e6171_table, 34 - ARRAY_SIZE(mv88e6171_table)); 35 - if (name) { 36 - ps = devm_kzalloc(dsa_dev, sizeof(*ps), GFP_KERNEL); 37 - if (!ps) 38 - return NULL; 39 - *priv = ps; 40 - } 41 - return name; 30 + return mv88e6xxx_drv_probe(dsa_dev, host_dev, sw_addr, priv, 31 + mv88e6171_table, 32 + ARRAY_SIZE(mv88e6171_table)); 42 33 } 43 34 44 35 static int mv88e6171_setup_global(struct dsa_switch *ds)
+3 -12
drivers/net/dsa/mv88e6352.c
··· 40 40 static char *mv88e6352_probe(struct device *dsa_dev, struct device *host_dev, 41 41 int sw_addr, void **priv) 42 42 { 43 - struct mv88e6xxx_priv_state *ps; 44 - char *name; 45 - 46 - name = mv88e6xxx_lookup_name(host_dev, sw_addr, mv88e6352_table, 47 - ARRAY_SIZE(mv88e6352_table)); 48 - if (name) { 49 - ps = devm_kzalloc(dsa_dev, sizeof(*ps), GFP_KERNEL); 50 - if (!ps) 51 - return NULL; 52 - *priv = ps; 53 - } 54 - return name; 43 + return mv88e6xxx_drv_probe(dsa_dev, host_dev, sw_addr, priv, 44 + mv88e6352_table, 45 + ARRAY_SIZE(mv88e6352_table)); 55 46 } 56 47 57 48 static int mv88e6352_setup_global(struct dsa_switch *ds)
+29 -14
drivers/net/dsa/mv88e6xxx.c
··· 94 94 95 95 static int _mv88e6xxx_reg_read(struct dsa_switch *ds, int addr, int reg) 96 96 { 97 - struct mii_bus *bus = dsa_host_dev_to_mii_bus(ds->master_dev); 97 + struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 98 98 int ret; 99 99 100 100 assert_smi_lock(ds); 101 101 102 - if (bus == NULL) 103 - return -EINVAL; 104 - 105 - ret = __mv88e6xxx_reg_read(bus, ds->pd->sw_addr, addr, reg); 102 + ret = __mv88e6xxx_reg_read(ps->bus, ps->sw_addr, addr, reg); 106 103 if (ret < 0) 107 104 return ret; 108 105 ··· 156 159 static int _mv88e6xxx_reg_write(struct dsa_switch *ds, int addr, int reg, 157 160 u16 val) 158 161 { 159 - struct mii_bus *bus = dsa_host_dev_to_mii_bus(ds->master_dev); 162 + struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 160 163 161 164 assert_smi_lock(ds); 162 - 163 - if (bus == NULL) 164 - return -EINVAL; 165 165 166 166 dev_dbg(ds->master_dev, "-> addr: 0x%.2x reg: 0x%.2x val: 0x%.4x\n", 167 167 addr, reg, val); 168 168 169 - return __mv88e6xxx_reg_write(bus, ds->pd->sw_addr, addr, reg, val); 169 + return __mv88e6xxx_reg_write(ps->bus, ps->sw_addr, addr, reg, val); 170 170 } 171 171 172 172 int mv88e6xxx_reg_write(struct dsa_switch *ds, int addr, int reg, u16 val) ··· 2665 2671 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 2666 2672 2667 2673 ps->ds = ds; 2668 - 2669 2674 mutex_init(&ps->smi_mutex); 2670 2675 2671 2676 ps->id = REG_READ(REG_PORT(0), PORT_SWITCH_ID) & 0xfff0; ··· 3068 3075 } 3069 3076 #endif /* CONFIG_NET_DSA_HWMON */ 3070 3077 3071 - char *mv88e6xxx_lookup_name(struct device *host_dev, int sw_addr, 3072 - const struct mv88e6xxx_switch_id *table, 3073 - unsigned int num) 3078 + static char *mv88e6xxx_lookup_name(struct device *host_dev, int sw_addr, 3079 + const struct mv88e6xxx_switch_id *table, 3080 + unsigned int num) 3074 3081 { 3075 3082 struct mii_bus *bus = dsa_host_dev_to_mii_bus(host_dev); 3076 3083 int i, ret; ··· 3098 3105 } 3099 3106 3100 3107 return NULL; 3108 + } 3109 + 3110 + char *mv88e6xxx_drv_probe(struct device *dsa_dev, struct device *host_dev, 3111 + int sw_addr, void **priv, 3112 + const struct mv88e6xxx_switch_id *table, 3113 + unsigned int num) 3114 + { 3115 + struct mv88e6xxx_priv_state *ps; 3116 + char *name; 3117 + 3118 + name = mv88e6xxx_lookup_name(host_dev, sw_addr, table, num); 3119 + if (name) { 3120 + ps = devm_kzalloc(dsa_dev, sizeof(*ps), GFP_KERNEL); 3121 + if (!ps) 3122 + return NULL; 3123 + *priv = ps; 3124 + ps->bus = dsa_host_dev_to_mii_bus(host_dev); 3125 + if (!ps->bus) 3126 + return NULL; 3127 + ps->sw_addr = sw_addr; 3128 + } 3129 + return name; 3101 3130 } 3102 3131 3103 3132 static int __init mv88e6xxx_init(void)
+11 -3
drivers/net/dsa/mv88e6xxx.h
··· 406 406 */ 407 407 struct mutex smi_mutex; 408 408 409 + /* The MII bus and the address on the bus that is used to 410 + * communication with the switch 411 + */ 412 + struct mii_bus *bus; 413 + int sw_addr; 414 + 409 415 #ifdef CONFIG_NET_DSA_MV88E6XXX_NEED_PPU 410 416 /* Handles automatic disabling and re-enabling of the PHY 411 417 * polling unit. ··· 462 456 }; 463 457 464 458 int mv88e6xxx_switch_reset(struct dsa_switch *ds, bool ppu_active); 465 - char *mv88e6xxx_lookup_name(struct device *host_dev, int sw_addr, 466 - const struct mv88e6xxx_switch_id *table, 467 - unsigned int num); 459 + char *mv88e6xxx_drv_probe(struct device *dsa_dev, struct device *host_dev, 460 + int sw_addr, void **priv, 461 + const struct mv88e6xxx_switch_id *table, 462 + unsigned int num); 463 + 468 464 int mv88e6xxx_setup_ports(struct dsa_switch *ds); 469 465 int mv88e6xxx_setup_common(struct dsa_switch *ds); 470 466 int mv88e6xxx_setup_global(struct dsa_switch *ds);