* [U-Boot] [PATCH V2] i2c: mxs_i2c: Squash endless loop
@ 2013-11-04 13:29 Marek Vasut
2013-11-13 6:36 ` [U-Boot] [U-Boot,V2] " Heiko Schocher
0 siblings, 1 reply; 2+ messages in thread
From: Marek Vasut @ 2013-11-04 13:29 UTC (permalink / raw)
To: u-boot
The endless waiting for a bit to be set can cause a hang, add a timeout
so we prevent such situation. A testcase for such a hang is below. The
testcase assumes a device to be present at address 0x50 and a device to
NOT be present at address 0x42 . Also note that the "sleep 1" induced
delays are imperative for this bug to manifest .
i2c read 0x42 0x0.2 0x10 0x42000000 ; sleep 1 ; \
i2c read 0x50 0x0.2 0x10 0x42000000 ; sleep 1 ; \
i2c read 0x42 0x0.2 0x10 0x42000000
The expected result of the above command is:
Error reading the chip.
Error reading the chip.
While without this patch, we observe a hang in the last read from 0x42
precisely when waiting for this bit to be set.
Signed-off-by: Marek Vasut <marex@denx.de>
Cc: Fabio Estevam <fabio.estevam@freescale.com>
Cc: Heiko Schocher <hs@denx.de>
Cc: Stefano Babic <sbabic@denx.de>
---
drivers/i2c/mxs_i2c.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
V2: Replace -EINVAL with -ETIMEDOUT
diff --git a/drivers/i2c/mxs_i2c.c b/drivers/i2c/mxs_i2c.c
index 46106b7..a298c95 100644
--- a/drivers/i2c/mxs_i2c.c
+++ b/drivers/i2c/mxs_i2c.c
@@ -150,6 +150,7 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
{
struct mxs_i2c_regs *i2c_regs = (struct mxs_i2c_regs *)MXS_I2C0_BASE;
uint32_t tmp = 0;
+ int timeout = MXS_I2C_MAX_TIMEOUT;
int ret;
int i;
@@ -169,9 +170,17 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
for (i = 0; i < len; i++) {
if (!(i & 3)) {
- while (readl(&i2c_regs->hw_i2c_queuestat) &
- I2C_QUEUESTAT_RD_QUEUE_EMPTY)
- ;
+ while (--timeout) {
+ tmp = readl(&i2c_regs->hw_i2c_queuestat);
+ if (!(tmp & I2C_QUEUESTAT_RD_QUEUE_EMPTY))
+ break;
+ }
+
+ if (!timeout) {
+ debug("MXS I2C: Failed receiving data!\n");
+ return -ETIMEDOUT;
+ }
+
tmp = readl(&i2c_regs->hw_i2c_queuedata);
}
buffer[i] = tmp & 0xff;
--
1.8.4.rc3
^ permalink raw reply related [flat|nested] 2+ messages in thread
* [U-Boot] [U-Boot,V2] i2c: mxs_i2c: Squash endless loop
2013-11-04 13:29 [U-Boot] [PATCH V2] i2c: mxs_i2c: Squash endless loop Marek Vasut
@ 2013-11-13 6:36 ` Heiko Schocher
0 siblings, 0 replies; 2+ messages in thread
From: Heiko Schocher @ 2013-11-13 6:36 UTC (permalink / raw)
To: u-boot
Hello Marek,
Am 04.11.2013 14:29, schrieb Marek Vasut:
> The endless waiting for a bit to be set can cause a hang, add a timeout
> so we prevent such situation. A testcase for such a hang is below. The
> testcase assumes a device to be present at address 0x50 and a device to
> NOT be present at address 0x42 . Also note that the "sleep 1" induced
> delays are imperative for this bug to manifest .
>
> i2c read 0x42 0x0.2 0x10 0x42000000 ; sleep 1 ; \
> i2c read 0x50 0x0.2 0x10 0x42000000 ; sleep 1 ; \
> i2c read 0x42 0x0.2 0x10 0x42000000
>
> The expected result of the above command is:
>
> Error reading the chip.
> Error reading the chip.
>
> While without this patch, we observe a hang in the last read from 0x42
> precisely when waiting for this bit to be set.
>
> Signed-off-by: Marek Vasut<marex@denx.de>
> Cc: Fabio Estevam<fabio.estevam@freescale.com>
> Cc: Heiko Schocher<hs@denx.de>
> Cc: Stefano Babic<sbabic@denx.de>
>
> ---
> drivers/i2c/mxs_i2c.c | 15 ++++++++++++---
> 1 file changed, 12 insertions(+), 3 deletions(-)
Thanks!
Applied to u-boot-i2c.git
bye,
Heiko
--
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2013-11-13 6:36 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-11-04 13:29 [U-Boot] [PATCH V2] i2c: mxs_i2c: Squash endless loop Marek Vasut
2013-11-13 6:36 ` [U-Boot] [U-Boot,V2] " Heiko Schocher
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox