diff options
| -rw-r--r-- | drivers/net/ethernet/freescale/fsl_pq_mdio.c | 29 |
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 | |||
| 50 | struct fsl_pq_mdio_priv { | 53 | struct 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 { | |||
| 64 | int fsl_pq_local_mdio_write(struct fsl_pq_mdio __iomem *regs, int mii_id, | 67 | int 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(®s->miimadd, (mii_id << 8) | regnum); | 73 | out_be32(®s->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(®s->miimcon, value); | 76 | out_be32(®s->miimcon, value); |
| 72 | 77 | ||
| 73 | /* Wait for the transaction to finish */ | 78 | /* Wait for the transaction to finish */ |
| 74 | while (in_be32(®s->miimind) & MIIMIND_BUSY) | 79 | status = spin_event_timeout(!(in_be32(®s->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(®s->miimadd, (mii_id << 8) | regnum); | 102 | out_be32(®s->miimadd, (mii_id << 8) | regnum); |
| @@ -99,9 +105,12 @@ int fsl_pq_local_mdio_read(struct fsl_pq_mdio __iomem *regs, | |||
| 99 | out_be32(®s->miimcom, 0); | 105 | out_be32(®s->miimcom, 0); |
| 100 | out_be32(®s->miimcom, MII_READ_COMMAND); | 106 | out_be32(®s->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(®s->miimind) & (MIIMIND_NOTVALID | MIIMIND_BUSY)) | 109 | status = spin_event_timeout(!(in_be32(®s->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(®s->miimstat); | 116 | value = in_be32(®s->miimstat); |
| @@ -144,7 +153,7 @@ int fsl_pq_mdio_read(struct mii_bus *bus, int mii_id, int regnum) | |||
| 144 | static int fsl_pq_mdio_reset(struct mii_bus *bus) | 153 | static 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(®s->miimcfg, MIIMCFG_INIT_VALUE); | 164 | out_be32(®s->miimcfg, MIIMCFG_INIT_VALUE); |
| 156 | 165 | ||
| 157 | /* Wait until the bus is free */ | 166 | /* Wait until the bus is free */ |
| 158 | while ((in_be32(®s->miimind) & MIIMIND_BUSY) && timeout--) | 167 | status = spin_event_timeout(!(in_be32(®s->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; |
