PERFORCE change 110644 for review
Warner Losh
imp at FreeBSD.org
Tue Nov 28 16:14:00 PST 2006
http://perforce.freebsd.org/chv.cgi?CH=110644
Change 110644 by imp at imp_lighthouse on 2006/11/29 00:13:26
Don't lockup on eeprom lockup.
Affected files ...
.. //depot/projects/arm/src/sys/arm/at91/at91_twi.c#32 edit
.. //depot/projects/arm/src/sys/boot/arm/at91/bootspi/ee.c#6 edit
.. //depot/projects/arm/src/sys/boot/arm/at91/bootspi/ee.h#3 edit
.. //depot/projects/arm/src/sys/boot/arm/at91/libat91/eeprom.c#8 edit
.. //depot/projects/arm/src/sys/boot/arm/at91/libat91/lib.h#21 edit
Differences ...
==== //depot/projects/arm/src/sys/arm/at91/at91_twi.c#32 (text+ko) ====
@@ -224,11 +224,16 @@
{
int err = 0;
int counter = 100000;
+ uint32_t sr;
- while (!(RD4(sc, TWI_SR) & bit) && counter-- > 0)
+ while (!((sr = RD4(sc, TWI_SR)) & bit) && counter-- > 0)
continue;
if (counter <= 0)
err = EBUSY;
+ else if (sr & TWI_SR_NACK)
+ err = EADDRNOTAVAIL;
+ if (sr & ~bit)
+ printf("status is %x\n", sr);
return (err);
}
@@ -241,10 +246,7 @@
sc = device_get_softc(dev);
if (oldaddr)
*oldaddr = sc->twi_addr;
- if (addr != 0)
- sc->twi_addr = 0;
- else
- sc->twi_addr = addr;
+ sc->twi_addr = addr;
/*
* speeds are for 1.5kb/s, 45kb/s and 90kb/s.
@@ -310,7 +312,9 @@
* address feature of twi. A separate i2c message needs to
* be written to use this.
* See http://lists.arm.linux.org.uk/pipermail/linux-arm-kernel/2004-September/024411.html
- * for details.
+ * for details. Upon reflection, we could use this as an
+ * optimization, but it is unclear the code bloat will
+ * result in faster/better operations.
*/
rdwr = (msgs[i].flags & IIC_M_RD) ? TWI_MMR_MREAD : 0;
WR4(sc, TWI_MMR, TWI_MMR_DADR(msgs[i].slave) | rdwr);
@@ -332,14 +336,20 @@
WR4(sc, TWI_THR, *buf++);
if (len == 0)
WR4(sc, TWI_CR, TWI_CR_STOP);
- if ((err = at91_twi_wait(sc, TWI_SR_TXRDY)))
+ if ((err = at91_twi_wait(sc, TWI_SR_TXRDY))) {
+ printf("Len %d\n", len);
goto out;
+ }
}
}
if ((err = at91_twi_wait(sc, TWI_SR_TXCOMP)))
break;
}
out:;
+ if (err) {
+ WR4(sc, TWI_CR, TWI_CR_STOP);
+ printf("Err is %d\n", err);
+ }
AT91_TWI_UNLOCK(sc);
return (err);
}
==== //depot/projects/arm/src/sys/boot/arm/at91/bootspi/ee.c#6 (text+ko) ====
@@ -89,15 +89,15 @@
* This function does not utilize the page read mode to simplify the code.
* .KB_C_FN_DEFINITION_END
*/
-void
+int
EERead(unsigned ee_off, char *data_addr, unsigned size)
{
const AT91PS_TWI twiPtr = AT91C_BASE_TWI;
- unsigned int status;
+ unsigned int status, count;
if ((ee_off & ~0xff) != ((ee_off + size) & ~0xff)) {
printf("Crosses page boundary: 0x%x 0x%x\n", ee_off, size);
- return;
+ return -1;
}
status = twiPtr->TWI_SR;
@@ -107,15 +107,22 @@
twiPtr->TWI_IADR = ee_off & 0xff;
twiPtr->TWI_CR = AT91C_TWI_START;
while (size-- > 1) {
- while (!(twiPtr->TWI_SR & AT91C_TWI_RXRDY))
+ count = 1000000;
+ while (!(twiPtr->TWI_SR & AT91C_TWI_RXRDY) && --count > 0)
continue;
+ if (count <= 0)
+ return -1;
*(data_addr++) = twiPtr->TWI_RHR;
}
twiPtr->TWI_CR = AT91C_TWI_STOP;
status = twiPtr->TWI_SR;
- while (!(twiPtr->TWI_SR & AT91C_TWI_TXCOMP))
+ count = 1000000;
+ while (!(twiPtr->TWI_SR & AT91C_TWI_TXCOMP) && --count > 0)
continue;
*data_addr = twiPtr->TWI_RHR;
+ if (count <= 0)
+ return -1;
+ return 0;
}
==== //depot/projects/arm/src/sys/boot/arm/at91/bootspi/ee.h#3 (text+ko) ====
@@ -1,4 +1,4 @@
void EEInit(void);
-void EERead(unsigned ee_off, char *data_addr, unsigned size);
+int EERead(unsigned ee_off, char *data_addr, unsigned size);
void EEWrite(unsigned ee_off, const char *data_addr, unsigned size);
==== //depot/projects/arm/src/sys/boot/arm/at91/libat91/eeprom.c#8 (text+ko) ====
@@ -82,11 +82,12 @@
* This function does not utilize the page read mode to simplify the code.
* .KB_C_FN_DEFINITION_END
*/
-void
+int
ReadEEPROM(unsigned ee_off, char *data_addr, unsigned size)
{
const AT91PS_TWI twiPtr = AT91C_BASE_TWI;
unsigned int status;
+ unsigned int count;
status = twiPtr->TWI_SR;
status = twiPtr->TWI_RHR;
@@ -104,10 +105,12 @@
status = twiPtr->TWI_SR;
while (size-- > 1){
-
// Wait RHR Holding register is full
- while (!(twiPtr->TWI_SR & AT91C_TWI_RXRDY))
+ count = 1000000;
+ while (!(twiPtr->TWI_SR & AT91C_TWI_RXRDY) && --count > 0)
continue;
+ if (count <= 0)
+ return -1;
// Read byte
*(data_addr++) = twiPtr->TWI_RHR;
@@ -123,6 +126,7 @@
// Read last byte
*data_addr = twiPtr->TWI_RHR;
+ return 0;
}
==== //depot/projects/arm/src/sys/boot/arm/at91/libat91/lib.h#21 (text) ====
@@ -34,7 +34,7 @@
/* The following function write eeprom at ee_addr using data */
/* from data_add for size bytes. */
-void ReadEEPROM(unsigned eeoff, char *data_addr, unsigned size);
+int ReadEEPROM(unsigned eeoff, char *data_addr, unsigned size);
void WriteEEPROM(unsigned eeoff, char *data_addr, unsigned size);
void InitEEPROM(void);
More information about the p4-projects
mailing list