Commit 13af14d0 authored by David S. Miller's avatar David S. Miller

Merge branch 'net-readx_poll_timeout'

Benedikt Spranger says:

====================
Convert mdio wait function to use readx_poll_timeout()

On loaded systems with a preemptible kernel both functions
axienet_mdio_wait_until_ready() and xemaclite_mdio_wait() may report a
false positive error return.
Convert both functions to use readx_poll_timeout() to handle the
situation in a safe manner.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents fa2c52be 563ecb8a
...@@ -484,6 +484,11 @@ static inline u32 axienet_ior(struct axienet_local *lp, off_t offset) ...@@ -484,6 +484,11 @@ static inline u32 axienet_ior(struct axienet_local *lp, off_t offset)
return in_be32(lp->regs + offset); return in_be32(lp->regs + offset);
} }
static inline u32 axinet_ior_read_mcr(struct axienet_local *lp)
{
return axienet_ior(lp, XAE_MDIO_MCR_OFFSET);
}
/** /**
* axienet_iow - Memory mapped Axi Ethernet register write * axienet_iow - Memory mapped Axi Ethernet register write
* @lp: Pointer to axienet local structure * @lp: Pointer to axienet local structure
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include <linux/of_address.h> #include <linux/of_address.h>
#include <linux/of_mdio.h> #include <linux/of_mdio.h>
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <linux/iopoll.h>
#include "xilinx_axienet.h" #include "xilinx_axienet.h"
...@@ -20,16 +21,11 @@ ...@@ -20,16 +21,11 @@
/* Wait till MDIO interface is ready to accept a new transaction.*/ /* Wait till MDIO interface is ready to accept a new transaction.*/
int axienet_mdio_wait_until_ready(struct axienet_local *lp) int axienet_mdio_wait_until_ready(struct axienet_local *lp)
{ {
unsigned long end = jiffies + 2; u32 val;
while (!(axienet_ior(lp, XAE_MDIO_MCR_OFFSET) &
XAE_MDIO_MCR_READY_MASK)) { return readx_poll_timeout(axinet_ior_read_mcr, lp,
if (time_before_eq(end, jiffies)) { val, val & XAE_MDIO_MCR_READY_MASK,
WARN_ON(1); 1, 20000);
return -ETIMEDOUT;
}
udelay(1);
}
return 0;
} }
/** /**
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <linux/of_net.h> #include <linux/of_net.h>
#include <linux/phy.h> #include <linux/phy.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/iopoll.h>
#define DRIVER_NAME "xilinx_emaclite" #define DRIVER_NAME "xilinx_emaclite"
...@@ -714,20 +715,15 @@ static irqreturn_t xemaclite_interrupt(int irq, void *dev_id) ...@@ -714,20 +715,15 @@ static irqreturn_t xemaclite_interrupt(int irq, void *dev_id)
static int xemaclite_mdio_wait(struct net_local *lp) 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 /* wait for the MDIO interface to not be busy or timeout
* after some time. * after some time.
*/ */
while (xemaclite_readl(lp->base_addr + XEL_MDIOCTRL_OFFSET) & return readx_poll_timeout(xemaclite_readl,
XEL_MDIOCTRL_MDIOSTS_MASK) { lp->base_addr + XEL_MDIOCTRL_OFFSET,
if (time_before_eq(end, jiffies)) { val, !(val & XEL_MDIOCTRL_MDIOSTS_MASK),
WARN_ON(1); 1000, 20000);
return -ETIMEDOUT;
}
msleep(1);
}
return 0;
} }
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment