diff options
| author | Ben Dooks <ben-linux@fluff.org> | 2008-02-04 19:02:17 -0500 |
|---|---|---|
| committer | Jeff Garzik <jeff@garzik.org> | 2008-02-11 11:06:33 -0500 |
| commit | 39c341a8dcf060b246b0beddac90cd7de11d4a20 (patch) | |
| tree | b71d29ba042edcd2dbb19da2f783eff4d27fd3a7 | |
| parent | c991d168cb649d416c5a773a50d0754299f31366 (diff) | |
DM9000: Fix delays used by EEPROM read and write
The code was using a delay of 8ms, when it should have been
using the EEPROM status flag from the device to indicate the
EEPROM transaction had finished.
Signed-off-by: Ben Dooks <ben-linux@fluff.org>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
| -rw-r--r-- | drivers/net/dm9000.c | 54 |
1 files changed, 51 insertions, 3 deletions
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c index 851618338b2e..1d790a8e3a98 100644 --- a/drivers/net/dm9000.c +++ b/drivers/net/dm9000.c | |||
| @@ -1048,6 +1048,50 @@ dm9000_rx(struct net_device *dev) | |||
| 1048 | } while (rxbyte == DM9000_PKT_RDY); | 1048 | } while (rxbyte == DM9000_PKT_RDY); |
| 1049 | } | 1049 | } |
| 1050 | 1050 | ||
| 1051 | static unsigned int | ||
| 1052 | dm9000_read_locked(board_info_t *db, int reg) | ||
| 1053 | { | ||
| 1054 | unsigned long flags; | ||
| 1055 | unsigned int ret; | ||
| 1056 | |||
| 1057 | spin_lock_irqsave(&db->lock, flags); | ||
| 1058 | ret = ior(db, reg); | ||
| 1059 | spin_unlock_irqrestore(&db->lock, flags); | ||
| 1060 | |||
| 1061 | return ret; | ||
| 1062 | } | ||
| 1063 | |||
| 1064 | static int dm9000_wait_eeprom(board_info_t *db) | ||
| 1065 | { | ||
| 1066 | unsigned int status; | ||
| 1067 | int timeout = 8; /* wait max 8msec */ | ||
| 1068 | |||
| 1069 | /* The DM9000 data sheets say we should be able to | ||
| 1070 | * poll the ERRE bit in EPCR to wait for the EEPROM | ||
| 1071 | * operation. From testing several chips, this bit | ||
| 1072 | * does not seem to work. | ||
| 1073 | * | ||
| 1074 | * We attempt to use the bit, but fall back to the | ||
| 1075 | * timeout (which is why we do not return an error | ||
| 1076 | * on expiry) to say that the EEPROM operation has | ||
| 1077 | * completed. | ||
| 1078 | */ | ||
| 1079 | |||
| 1080 | while (1) { | ||
| 1081 | status = dm9000_read_locked(db, DM9000_EPCR); | ||
| 1082 | |||
| 1083 | if ((status & EPCR_ERRE) == 0) | ||
| 1084 | break; | ||
| 1085 | |||
| 1086 | if (timeout-- < 0) { | ||
| 1087 | dev_dbg(db->dev, "timeout waiting EEPROM\n"); | ||
| 1088 | break; | ||
| 1089 | } | ||
| 1090 | } | ||
| 1091 | |||
| 1092 | return 0; | ||
| 1093 | } | ||
| 1094 | |||
| 1051 | /* | 1095 | /* |
| 1052 | * Read a word data from EEPROM | 1096 | * Read a word data from EEPROM |
| 1053 | */ | 1097 | */ |
| @@ -1065,8 +1109,10 @@ dm9000_read_eeprom(board_info_t *db, int offset, u8 *to) | |||
| 1065 | 1109 | ||
| 1066 | spin_unlock_irqrestore(&db->lock, flags); | 1110 | spin_unlock_irqrestore(&db->lock, flags); |
| 1067 | 1111 | ||
| 1068 | mdelay(8); /* according to the datasheet 200us should be enough, | 1112 | dm9000_wait_eeprom(db); |
| 1069 | but it doesn't work */ | 1113 | |
| 1114 | /* delay for at-least 150uS */ | ||
| 1115 | msleep(1); | ||
| 1070 | 1116 | ||
| 1071 | spin_lock_irqsave(&db->lock, flags); | 1117 | spin_lock_irqsave(&db->lock, flags); |
| 1072 | 1118 | ||
| @@ -1097,7 +1143,9 @@ dm9000_write_eeprom(board_info_t *db, int offset, u8 *data) | |||
| 1097 | iow(db, DM9000_EPCR, EPCR_WEP | EPCR_ERPRW); | 1143 | iow(db, DM9000_EPCR, EPCR_WEP | EPCR_ERPRW); |
| 1098 | spin_unlock_irqrestore(&db->lock, flags); | 1144 | spin_unlock_irqrestore(&db->lock, flags); |
| 1099 | 1145 | ||
| 1100 | mdelay(8); /* same shit */ | 1146 | dm9000_wait_eeprom(db); |
| 1147 | |||
| 1148 | mdelay(1); /* wait at least 150uS to clear */ | ||
| 1101 | 1149 | ||
| 1102 | spin_lock_irqsave(&db->lock, flags); | 1150 | spin_lock_irqsave(&db->lock, flags); |
| 1103 | iow(db, DM9000_EPCR, 0); | 1151 | iow(db, DM9000_EPCR, 0); |
