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: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
13af14d06a
|
@ -484,6 +484,11 @@ static inline u32 axienet_ior(struct axienet_local *lp, off_t 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
|
||||
* @lp: Pointer to axienet local structure
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <linux/of_address.h>
|
||||
#include <linux/of_mdio.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/iopoll.h>
|
||||
|
||||
#include "xilinx_axienet.h"
|
||||
|
||||
|
@ -20,16 +21,11 @@
|
|||
/* Wait till MDIO interface is ready to accept a new transaction.*/
|
||||
int axienet_mdio_wait_until_ready(struct axienet_local *lp)
|
||||
{
|
||||
unsigned long end = jiffies + 2;
|
||||
while (!(axienet_ior(lp, XAE_MDIO_MCR_OFFSET) &
|
||||
XAE_MDIO_MCR_READY_MASK)) {
|
||||
if (time_before_eq(end, jiffies)) {
|
||||
WARN_ON(1);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
udelay(1);
|
||||
}
|
||||
return 0;
|
||||
u32 val;
|
||||
|
||||
return readx_poll_timeout(axinet_ior_read_mcr, lp,
|
||||
val, val & XAE_MDIO_MCR_READY_MASK,
|
||||
1, 20000);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue