]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
net: dsa: vsc73xx: use read_poll_timeout instead delay loop
authorPawel Dembicki <paweldembicki@gmail.com>
Wed, 17 Apr 2024 20:50:44 +0000 (22:50 +0200)
committerJakub Kicinski <kuba@kernel.org>
Mon, 22 Apr 2024 21:20:13 +0000 (14:20 -0700)
Switch the delay loop during the Arbiter empty check from
vsc73xx_adjust_link() to use read_poll_timeout(). Functionally,
one msleep() call is eliminated at the end of the loop in the timeout
case.

As Russell King suggested:

"This [change] avoids the issue that on the last iteration, the code reads
the register, tests it, finds the condition that's being waiting for is
false, _then_ waits and end up printing the error message - that last
wait is rather useless, and as the arbiter state isn't checked after
waiting, it could be that we had success during the last wait."

Suggested-by: Russell King <linux@armlinux.org.uk>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
Signed-off-by: Pawel Dembicki <paweldembicki@gmail.com>
Link: https://lore.kernel.org/r/20240417205048.3542839-2-paweldembicki@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/dsa/vitesse-vsc73xx-core.c

index ae70eac3be28f84ec3ad00910faf3b4dcbe6bddc..ab5771d4d82872b27151c179b0dd66fbb3b70431 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/device.h>
+#include <linux/iopoll.h>
 #include <linux/of.h>
 #include <linux/of_mdio.h>
 #include <linux/bitops.h>
 #define IS_7398(a) ((a)->chipid == VSC73XX_CHIPID_ID_7398)
 #define IS_739X(a) (IS_7395(a) || IS_7398(a))
 
+#define VSC73XX_POLL_SLEEP_US          1000
+#define VSC73XX_POLL_TIMEOUT_US                10000
+
 struct vsc73xx_counter {
        u8 counter;
        const char *name;
@@ -779,7 +783,7 @@ static void vsc73xx_adjust_link(struct dsa_switch *ds, int port,
         * after a PHY or the CPU port comes up or down.
         */
        if (!phydev->link) {
-               int maxloop = 10;
+               int ret, err;
 
                dev_dbg(vsc->dev, "port %d: went down\n",
                        port);
@@ -794,19 +798,17 @@ static void vsc73xx_adjust_link(struct dsa_switch *ds, int port,
                                    VSC73XX_ARBDISC, BIT(port), BIT(port));
 
                /* Wait until queue is empty */
-               vsc73xx_read(vsc, VSC73XX_BLOCK_ARBITER, 0,
-                            VSC73XX_ARBEMPTY, &val);
-               while (!(val & BIT(port))) {
-                       msleep(1);
-                       vsc73xx_read(vsc, VSC73XX_BLOCK_ARBITER, 0,
-                                    VSC73XX_ARBEMPTY, &val);
-                       if (--maxloop == 0) {
-                               dev_err(vsc->dev,
-                                       "timeout waiting for block arbiter\n");
-                               /* Continue anyway */
-                               break;
-                       }
-               }
+               ret = read_poll_timeout(vsc73xx_read, err,
+                                       err < 0 || (val & BIT(port)),
+                                       VSC73XX_POLL_SLEEP_US,
+                                       VSC73XX_POLL_TIMEOUT_US, false,
+                                       vsc, VSC73XX_BLOCK_ARBITER, 0,
+                                       VSC73XX_ARBEMPTY, &val);
+               if (ret)
+                       dev_err(vsc->dev,
+                               "timeout waiting for block arbiter\n");
+               else if (err < 0)
+                       dev_err(vsc->dev, "error reading arbiter\n");
 
                /* Put this port into reset */
                vsc73xx_write(vsc, VSC73XX_BLOCK_MAC, port, VSC73XX_MAC_CFG,