aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/freescale/fsl_pq_mdio.c29
1 files changed, 19 insertions, 10 deletions
diff --git a/drivers/net/ethernet/freescale/fsl_pq_mdio.c b/drivers/net/ethernet/freescale/fsl_pq_mdio.c
index f7f0bf5d037b..9527b28d70d1 100644
--- a/drivers/net/ethernet/freescale/fsl_pq_mdio.c
+++ b/drivers/net/ethernet/freescale/fsl_pq_mdio.c
@@ -47,6 +47,9 @@
47#include "gianfar.h" 47#include "gianfar.h"
48#include "fsl_pq_mdio.h" 48#include "fsl_pq_mdio.h"
49 49
50/* Number of microseconds to wait for an MII register to respond */
51#define MII_TIMEOUT 1000
52
50struct fsl_pq_mdio_priv { 53struct fsl_pq_mdio_priv {
51 void __iomem *map; 54 void __iomem *map;
52 struct fsl_pq_mdio __iomem *regs; 55 struct fsl_pq_mdio __iomem *regs;
@@ -64,6 +67,8 @@ struct fsl_pq_mdio_priv {
64int fsl_pq_local_mdio_write(struct fsl_pq_mdio __iomem *regs, int mii_id, 67int fsl_pq_local_mdio_write(struct fsl_pq_mdio __iomem *regs, int mii_id,
65 int regnum, u16 value) 68 int regnum, u16 value)
66{ 69{
70 u32 status;
71
67 /* Set the PHY address and the register address we want to write */ 72 /* Set the PHY address and the register address we want to write */
68 out_be32(&regs->miimadd, (mii_id << 8) | regnum); 73 out_be32(&regs->miimadd, (mii_id << 8) | regnum);
69 74
@@ -71,10 +76,10 @@ int fsl_pq_local_mdio_write(struct fsl_pq_mdio __iomem *regs, int mii_id,
71 out_be32(&regs->miimcon, value); 76 out_be32(&regs->miimcon, value);
72 77
73 /* Wait for the transaction to finish */ 78 /* Wait for the transaction to finish */
74 while (in_be32(&regs->miimind) & MIIMIND_BUSY) 79 status = spin_event_timeout(!(in_be32(&regs->miimind) & MIIMIND_BUSY),
75 cpu_relax(); 80 MII_TIMEOUT, 0);
76 81
77 return 0; 82 return status ? 0 : -ETIMEDOUT;
78} 83}
79 84
80/* 85/*
@@ -91,6 +96,7 @@ int fsl_pq_local_mdio_read(struct fsl_pq_mdio __iomem *regs,
91 int mii_id, int regnum) 96 int mii_id, int regnum)
92{ 97{
93 u16 value; 98 u16 value;
99 u32 status;
94 100
95 /* Set the PHY address and the register address we want to read */ 101 /* Set the PHY address and the register address we want to read */
96 out_be32(&regs->miimadd, (mii_id << 8) | regnum); 102 out_be32(&regs->miimadd, (mii_id << 8) | regnum);
@@ -99,9 +105,12 @@ int fsl_pq_local_mdio_read(struct fsl_pq_mdio __iomem *regs,
99 out_be32(&regs->miimcom, 0); 105 out_be32(&regs->miimcom, 0);
100 out_be32(&regs->miimcom, MII_READ_COMMAND); 106 out_be32(&regs->miimcom, MII_READ_COMMAND);
101 107
102 /* Wait for the transaction to finish */ 108 /* Wait for the transaction to finish, normally less than 100us */
103 while (in_be32(&regs->miimind) & (MIIMIND_NOTVALID | MIIMIND_BUSY)) 109 status = spin_event_timeout(!(in_be32(&regs->miimind) &
104 cpu_relax(); 110 (MIIMIND_NOTVALID | MIIMIND_BUSY)),
111 MII_TIMEOUT, 0);
112 if (!status)
113 return -ETIMEDOUT;
105 114
106 /* Grab the value of the register from miimstat */ 115 /* Grab the value of the register from miimstat */
107 value = in_be32(&regs->miimstat); 116 value = in_be32(&regs->miimstat);
@@ -144,7 +153,7 @@ int fsl_pq_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
144static int fsl_pq_mdio_reset(struct mii_bus *bus) 153static int fsl_pq_mdio_reset(struct mii_bus *bus)
145{ 154{
146 struct fsl_pq_mdio __iomem *regs = fsl_pq_mdio_get_regs(bus); 155 struct fsl_pq_mdio __iomem *regs = fsl_pq_mdio_get_regs(bus);
147 int timeout = PHY_INIT_TIMEOUT; 156 u32 status;
148 157
149 mutex_lock(&bus->mdio_lock); 158 mutex_lock(&bus->mdio_lock);
150 159
@@ -155,12 +164,12 @@ static int fsl_pq_mdio_reset(struct mii_bus *bus)
155 out_be32(&regs->miimcfg, MIIMCFG_INIT_VALUE); 164 out_be32(&regs->miimcfg, MIIMCFG_INIT_VALUE);
156 165
157 /* Wait until the bus is free */ 166 /* Wait until the bus is free */
158 while ((in_be32(&regs->miimind) & MIIMIND_BUSY) && timeout--) 167 status = spin_event_timeout(!(in_be32(&regs->miimind) & MIIMIND_BUSY),
159 cpu_relax(); 168 MII_TIMEOUT, 0);
160 169
161 mutex_unlock(&bus->mdio_lock); 170 mutex_unlock(&bus->mdio_lock);
162 171
163 if (timeout < 0) { 172 if (!status) {
164 printk(KERN_ERR "%s: The MII Bus is stuck!\n", 173 printk(KERN_ERR "%s: The MII Bus is stuck!\n",
165 bus->name); 174 bus->name);
166 return -EBUSY; 175 return -EBUSY;