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

net: dsa: lan9303: ensure chip reset and wait for READY status

Accessing device registers seems to be not reliable, the chip
revision is sometimes detected wrongly (0 instead of expected 1).

Ensure that the chip reset is performed via reset GPIO and then
wait for 'Device Ready' status in HW_CFG register before doing
any register initializations.

Cc: stable@vger.kernel.org
Fixes: a1292595e006 ("net: dsa: add new DSA switch driver for the SMSC-LAN9303")
Signed-off-by: Anatolij Gustschin <agust@denx.de>
[alex: reworked using read_poll_timeout()]
Signed-off-by: Alexander Sverdlin <alexander.sverdlin@siemens.com>
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
Link: https://patch.msgid.link/20241004113655.3436296-1-alexander.sverdlin@siemens.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Anatolij Gustschin and committed by
Jakub Kicinski
5c14e51d 63108314

+29
+29
drivers/net/dsa/lan9303-core.c
··· 6 6 #include <linux/module.h> 7 7 #include <linux/gpio/consumer.h> 8 8 #include <linux/regmap.h> 9 + #include <linux/iopoll.h> 9 10 #include <linux/mutex.h> 10 11 #include <linux/mii.h> 11 12 #include <linux/of.h> ··· 840 839 if (!chip->reset_gpio) 841 840 return; 842 841 842 + gpiod_set_value_cansleep(chip->reset_gpio, 1); 843 + 843 844 if (chip->reset_duration != 0) 844 845 msleep(chip->reset_duration); 845 846 ··· 867 864 static int lan9303_check_device(struct lan9303 *chip) 868 865 { 869 866 int ret; 867 + int err; 870 868 u32 reg; 869 + 870 + /* In I2C-managed configurations this polling loop will clash with 871 + * switch's reading of EEPROM right after reset and this behaviour is 872 + * not configurable. While lan9303_read() already has quite long retry 873 + * timeout, seems not all cases are being detected as arbitration error. 874 + * 875 + * According to datasheet, EEPROM loader has 30ms timeout (in case of 876 + * missing EEPROM). 877 + * 878 + * Loading of the largest supported EEPROM is expected to take at least 879 + * 5.9s. 880 + */ 881 + err = read_poll_timeout(lan9303_read, ret, 882 + !ret && reg & LAN9303_HW_CFG_READY, 883 + 20000, 6000000, false, 884 + chip->regmap, LAN9303_HW_CFG, &reg); 885 + if (ret) { 886 + dev_err(chip->dev, "failed to read HW_CFG reg: %pe\n", 887 + ERR_PTR(ret)); 888 + return ret; 889 + } 890 + if (err) { 891 + dev_err(chip->dev, "HW_CFG not ready: 0x%08x\n", reg); 892 + return err; 893 + } 871 894 872 895 ret = lan9303_read(chip->regmap, LAN9303_CHIP_REV, &reg); 873 896 if (ret) {