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

net: dsa: lan9303: MDIO access phy registers directly

Indirect access (PMI) to phy register only work in I2C mode. In
MDIO mode phy registers must be accessed directly. Introduced
struct lan9303_phy_ops to handle the two modes.

Signed-off-by: Egil Hjelmeland <privat@egil-hjelmeland.no>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Reviewed-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Egil Hjelmeland and committed by
David S. Miller
2c340898 9e866e5d

+47 -7
+13 -7
drivers/net/dsa/lan9303-core.c
··· 334 334 return ret; 335 335 } 336 336 337 + const struct lan9303_phy_ops lan9303_indirect_phy_ops = { 338 + .phy_read = lan9303_indirect_phy_read, 339 + .phy_write = lan9303_indirect_phy_write, 340 + }; 341 + EXPORT_SYMBOL_GPL(lan9303_indirect_phy_ops); 342 + 337 343 static int lan9303_switch_wait_for_completion(struct lan9303 *chip) 338 344 { 339 345 int ret, i; ··· 441 435 * 0x0000, which means 'phy_addr_sel_strap' is 1 and the IDs are 1-2-3. 442 436 * 0xffff is returned on MDIO read with no response. 443 437 */ 444 - reg = lan9303_indirect_phy_read(chip, 3, MII_LAN911X_SPECIAL_MODES); 438 + reg = chip->ops->phy_read(chip, 3, MII_LAN911X_SPECIAL_MODES); 445 439 if (reg < 0) { 446 440 dev_err(chip->dev, "Failed to detect phy config: %d\n", reg); 447 441 return reg; ··· 732 726 if (phy > phy_base + 2) 733 727 return -ENODEV; 734 728 735 - return lan9303_indirect_phy_read(chip, phy, regnum); 729 + return chip->ops->phy_read(chip, phy, regnum); 736 730 } 737 731 738 732 static int lan9303_phy_write(struct dsa_switch *ds, int phy, int regnum, ··· 746 740 if (phy > phy_base + 2) 747 741 return -ENODEV; 748 742 749 - return lan9303_indirect_phy_write(chip, phy, regnum, val); 743 + return chip->ops->phy_write(chip, phy, regnum, val); 750 744 } 751 745 752 746 static int lan9303_port_enable(struct dsa_switch *ds, int port, ··· 779 773 switch (port) { 780 774 case 1: 781 775 lan9303_disable_packet_processing(chip, LAN9303_PORT_1_OFFSET); 782 - lan9303_indirect_phy_write(chip, chip->phy_addr_sel_strap + 1, 783 - MII_BMCR, BMCR_PDOWN); 776 + lan9303_phy_write(ds, chip->phy_addr_sel_strap + 1, 777 + MII_BMCR, BMCR_PDOWN); 784 778 break; 785 779 case 2: 786 780 lan9303_disable_packet_processing(chip, LAN9303_PORT_2_OFFSET); 787 - lan9303_indirect_phy_write(chip, chip->phy_addr_sel_strap + 2, 788 - MII_BMCR, BMCR_PDOWN); 781 + lan9303_phy_write(ds, chip->phy_addr_sel_strap + 2, 782 + MII_BMCR, BMCR_PDOWN); 789 783 break; 790 784 default: 791 785 dev_dbg(chip->dev,
+11
drivers/net/dsa/lan9303.h
··· 2 2 #include <linux/device.h> 3 3 #include <net/dsa.h> 4 4 5 + struct lan9303; 6 + 7 + struct lan9303_phy_ops { 8 + /* PHY 1 and 2 access*/ 9 + int (*phy_read)(struct lan9303 *chip, int port, int regnum); 10 + int (*phy_write)(struct lan9303 *chip, int port, 11 + int regnum, u16 val); 12 + }; 13 + 5 14 struct lan9303 { 6 15 struct device *dev; 7 16 struct regmap *regmap; ··· 20 11 bool phy_addr_sel_strap; 21 12 struct dsa_switch *ds; 22 13 struct mutex indirect_mutex; /* protect indexed register access */ 14 + const struct lan9303_phy_ops *ops; 23 15 }; 24 16 25 17 extern const struct regmap_access_table lan9303_register_set; 18 + extern const struct lan9303_phy_ops lan9303_indirect_phy_ops; 26 19 27 20 int lan9303_probe(struct lan9303 *chip, struct device_node *np); 28 21 int lan9303_remove(struct lan9303 *chip);
+2
drivers/net/dsa/lan9303_i2c.c
··· 63 63 i2c_set_clientdata(client, sw_dev); 64 64 sw_dev->chip.dev = &client->dev; 65 65 66 + sw_dev->chip.ops = &lan9303_indirect_phy_ops; 67 + 66 68 ret = lan9303_probe(&sw_dev->chip, client->dev.of_node); 67 69 if (ret != 0) 68 70 return ret;
+21
drivers/net/dsa/lan9303_mdio.c
··· 67 67 return 0; 68 68 } 69 69 70 + int lan9303_mdio_phy_write(struct lan9303 *chip, int phy, int reg, u16 val) 71 + { 72 + struct lan9303_mdio *sw_dev = dev_get_drvdata(chip->dev); 73 + 74 + return mdiobus_write_nested(sw_dev->device->bus, phy, reg, val); 75 + } 76 + 77 + int lan9303_mdio_phy_read(struct lan9303 *chip, int phy, int reg) 78 + { 79 + struct lan9303_mdio *sw_dev = dev_get_drvdata(chip->dev); 80 + 81 + return mdiobus_read_nested(sw_dev->device->bus, phy, reg); 82 + } 83 + 84 + static const struct lan9303_phy_ops lan9303_mdio_phy_ops = { 85 + .phy_read = lan9303_mdio_phy_read, 86 + .phy_write = lan9303_mdio_phy_write, 87 + }; 88 + 70 89 static const struct regmap_config lan9303_mdio_regmap_config = { 71 90 .reg_bits = 8, 72 91 .val_bits = 32, ··· 126 107 sw_dev->device = mdiodev; 127 108 dev_set_drvdata(&mdiodev->dev, sw_dev); 128 109 sw_dev->chip.dev = &mdiodev->dev; 110 + 111 + sw_dev->chip.ops = &lan9303_mdio_phy_ops; 129 112 130 113 ret = lan9303_probe(&sw_dev->chip, mdiodev->dev.of_node); 131 114 if (ret != 0)