|
@@ -34,6 +34,22 @@
|
|
|
#define MII_BUSY 0x00000001
|
|
|
#define MII_WRITE 0x00000002
|
|
|
|
|
|
+static int stmmac_mdio_busy_wait(void __iomem *ioaddr, unsigned int mii_addr)
|
|
|
+{
|
|
|
+ unsigned long curr;
|
|
|
+ unsigned long finish = jiffies + 3 * HZ;
|
|
|
+
|
|
|
+ do {
|
|
|
+ curr = jiffies;
|
|
|
+ if (readl(ioaddr + mii_addr) & MII_BUSY)
|
|
|
+ cpu_relax();
|
|
|
+ else
|
|
|
+ return 0;
|
|
|
+ } while (!time_after_eq(curr, finish));
|
|
|
+
|
|
|
+ return -EBUSY;
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* stmmac_mdio_read
|
|
|
* @bus: points to the mii_bus structure
|
|
@@ -56,9 +72,13 @@ static int stmmac_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg)
|
|
|
((phyreg << 6) & (0x000007C0)));
|
|
|
regValue |= MII_BUSY | ((priv->plat->clk_csr & 7) << 2);
|
|
|
|
|
|
- do {} while (((readl(priv->ioaddr + mii_address)) & MII_BUSY) == 1);
|
|
|
+ if (stmmac_mdio_busy_wait(priv->ioaddr, mii_address))
|
|
|
+ return -EBUSY;
|
|
|
+
|
|
|
writel(regValue, priv->ioaddr + mii_address);
|
|
|
- do {} while (((readl(priv->ioaddr + mii_address)) & MII_BUSY) == 1);
|
|
|
+
|
|
|
+ if (stmmac_mdio_busy_wait(priv->ioaddr, mii_address))
|
|
|
+ return -EBUSY;
|
|
|
|
|
|
/* Read the data from the MII data register */
|
|
|
data = (int)readl(priv->ioaddr + mii_data);
|
|
@@ -88,18 +108,16 @@ static int stmmac_mdio_write(struct mii_bus *bus, int phyaddr, int phyreg,
|
|
|
|
|
|
value |= MII_BUSY | ((priv->plat->clk_csr & 7) << 2);
|
|
|
|
|
|
-
|
|
|
/* Wait until any existing MII operation is complete */
|
|
|
- do {} while (((readl(priv->ioaddr + mii_address)) & MII_BUSY) == 1);
|
|
|
+ if (stmmac_mdio_busy_wait(priv->ioaddr, mii_address))
|
|
|
+ return -EBUSY;
|
|
|
|
|
|
/* Set the MII address register to write */
|
|
|
writel(phydata, priv->ioaddr + mii_data);
|
|
|
writel(value, priv->ioaddr + mii_address);
|
|
|
|
|
|
/* Wait until any existing MII operation is complete */
|
|
|
- do {} while (((readl(priv->ioaddr + mii_address)) & MII_BUSY) == 1);
|
|
|
-
|
|
|
- return 0;
|
|
|
+ return stmmac_mdio_busy_wait(priv->ioaddr, mii_address);
|
|
|
}
|
|
|
|
|
|
/**
|