2/2] net: xilinx_emaclite: use readx_poll_timeout() in mdio wait function
authorKurt Kanzenbach <kurt@linutronix.de>
Sun, 19 May 2019 17:59:37 +0000 (19:59 +0200)
committerDavid S. Miller <davem@davemloft.net>
Tue, 21 May 2019 00:00:46 +0000 (20:00 -0400)
On loaded systems with a preemptible kernel the mdio_wait() function may
report an error while everything is working fine:

xemaclite_mdio_wait():
  xemaclite_readl() -> chip not ready
  --> interrupt here (other work for some time / chip become ready)
  if (time_before_eq(end, jiffies))
    --> false positive error report

Replace the current code with readx_poll_timeout() which takes care
of the situation.

Signed-off-by: Kurt Kanzenbach <kurt@linutronix.de>
Signed-off-by: Benedikt Spranger <b.spranger@linutronix.de>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/xilinx/xilinx_emaclite.c

index 6886270da695925b0c5155ef8bdd66221d927e7f..c409bab63bd3efce33378bfb5420f05defc02eb8 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/of_net.h>
 #include <linux/phy.h>
 #include <linux/interrupt.h>
+#include <linux/iopoll.h>
 
 #define DRIVER_NAME "xilinx_emaclite"
 
@@ -714,20 +715,15 @@ static irqreturn_t xemaclite_interrupt(int irq, void *dev_id)
 
 static int xemaclite_mdio_wait(struct net_local *lp)
 {
-       unsigned long end = jiffies + 2;
+       u32 val;
 
        /* wait for the MDIO interface to not be busy or timeout
         * after some time.
         */
-       while (xemaclite_readl(lp->base_addr + XEL_MDIOCTRL_OFFSET) &
-                       XEL_MDIOCTRL_MDIOSTS_MASK) {
-               if (time_before_eq(end, jiffies)) {
-                       WARN_ON(1);
-                       return -ETIMEDOUT;
-               }
-               msleep(1);
-       }
-       return 0;
+       return readx_poll_timeout(xemaclite_readl,
+                                 lp->base_addr + XEL_MDIOCTRL_OFFSET,
+                                 val, !(val & XEL_MDIOCTRL_MDIOSTS_MASK),
+                                 1000, 20000);
 }
 
 /**