aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorBen Dooks <ben-linux@fluff.org>2008-02-04 19:02:07 -0500
committerJeff Garzik <jeff@garzik.org>2008-02-11 11:06:26 -0500
commit89c8b0e6cd3859a6445398c5aa94ebd21d0e64ce (patch)
tree5aed488a12bcf2654990d715b9da314e9a8172ce /drivers
parent7da998591798ea52938d8482b52ae3f854f14359 (diff)
DM9000: Do not sleep with spinlock and IRQs held
The phy read and write routines call udelay() with the board lock held, and with the posibility of IRQs being disabled. Since these delays can be up to 500usec, and are only required as we have to save the chip's address register. To improve the behaviour, hold the lock whilst we are writing and then restore the state before the delay and then repeat the process once the delay has happened. Signed-off-by: Ben Dooks <ben-linux@fluff.org> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/dm9000.c17
1 files changed, 16 insertions, 1 deletions
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c
index 709fd674ec38..071aad1af577 100644
--- a/drivers/net/dm9000.c
+++ b/drivers/net/dm9000.c
@@ -1127,7 +1127,15 @@ dm9000_phy_read(struct net_device *dev, int phy_reg_unused, int reg)
1127 iow(db, DM9000_EPAR, DM9000_PHY | reg); 1127 iow(db, DM9000_EPAR, DM9000_PHY | reg);
1128 1128
1129 iow(db, DM9000_EPCR, 0xc); /* Issue phyxcer read command */ 1129 iow(db, DM9000_EPCR, 0xc); /* Issue phyxcer read command */
1130
1131 writeb(reg_save, db->io_addr);
1132 spin_unlock_irqrestore(&db->lock,flags);
1133
1130 udelay(100); /* Wait read complete */ 1134 udelay(100); /* Wait read complete */
1135
1136 spin_lock_irqsave(&db->lock,flags);
1137 reg_save = readb(db->io_addr);
1138
1131 iow(db, DM9000_EPCR, 0x0); /* Clear phyxcer read command */ 1139 iow(db, DM9000_EPCR, 0x0); /* Clear phyxcer read command */
1132 1140
1133 /* The read data keeps on REG_0D & REG_0E */ 1141 /* The read data keeps on REG_0D & REG_0E */
@@ -1135,7 +1143,6 @@ dm9000_phy_read(struct net_device *dev, int phy_reg_unused, int reg)
1135 1143
1136 /* restore the previous address */ 1144 /* restore the previous address */
1137 writeb(reg_save, db->io_addr); 1145 writeb(reg_save, db->io_addr);
1138
1139 spin_unlock_irqrestore(&db->lock,flags); 1146 spin_unlock_irqrestore(&db->lock,flags);
1140 1147
1141 return ret; 1148 return ret;
@@ -1164,7 +1171,15 @@ dm9000_phy_write(struct net_device *dev, int phyaddr_unused, int reg, int value)
1164 iow(db, DM9000_EPDRH, ((value >> 8) & 0xff)); 1171 iow(db, DM9000_EPDRH, ((value >> 8) & 0xff));
1165 1172
1166 iow(db, DM9000_EPCR, 0xa); /* Issue phyxcer write command */ 1173 iow(db, DM9000_EPCR, 0xa); /* Issue phyxcer write command */
1174
1175 writeb(reg_save, db->io_addr);
1176 spin_unlock_irqrestore(&db->lock,flags);
1177
1167 udelay(500); /* Wait write complete */ 1178 udelay(500); /* Wait write complete */
1179
1180 spin_lock_irqsave(&db->lock,flags);
1181 reg_save = readb(db->io_addr);
1182
1168 iow(db, DM9000_EPCR, 0x0); /* Clear phyxcer write command */ 1183 iow(db, DM9000_EPCR, 0x0); /* Clear phyxcer write command */
1169 1184
1170 /* restore the previous address */ 1185 /* restore the previous address */