When the OMAP I2C controller is operated in master mode, setting the STP bit in the CON register instructs the controller to generate an I2C stop condition only after the programmed number of bytes has been sent on the I2C bus. The current code in QEMU ends the I2C transfer without first sending the pending data instead. Fix the above issue, and let the I2C transfer be ended in omap_i2c_fifo_run(), after the count of bytes to send has reached zero.
Signed-off-by: Francesco Lavra francescolavra.fl@gmail.com
--- Without this patch, the controller driver in Linux is unable to send data on the I2C bus, and when the controller triggers an IRQ after having started an I2C transfer, the XRDY flag in the STAT register remains always asserted, leading to an endless loop which eventually results in a kernel oops.
hw/i2c/omap_i2c.c | 4 ---- 1 files changed, 0 insertions(+), 4 deletions(-)
diff --git a/hw/i2c/omap_i2c.c b/hw/i2c/omap_i2c.c index cfaac07..17d4037 100644 --- a/hw/i2c/omap_i2c.c +++ b/hw/i2c/omap_i2c.c @@ -521,10 +521,6 @@ static void omap_i2c_write(void *opaque, hwaddr addr, omap_i2c_fifo_run(s); } omap_i2c_interrupts_update(s); - } else if (value & 2) { /* STP, but not STT */ - i2c_end_transfer(s->bus); - s->control &= ~0x0602; /* MST | TRX | STP */ - s->count_cur = s->count; } } break;
On 24 June 2013 19:21, Francesco Lavra francescolavra.fl@gmail.com wrote:
When the OMAP I2C controller is operated in master mode, setting the STP bit in the CON register instructs the controller to generate an I2C stop condition only after the programmed number of bytes has been sent on the I2C bus. The current code in QEMU ends the I2C transfer without first sending the pending data instead. Fix the above issue, and let the I2C transfer be ended in omap_i2c_fifo_run(), after the count of bytes to send has reached zero.
Signed-off-by: Francesco Lavra francescolavra.fl@gmail.com
Without this patch, the controller driver in Linux is unable to send data on the I2C bus, and when the controller triggers an IRQ after having started an I2C transfer, the XRDY flag in the STAT register remains always asserted, leading to an endless loop which eventually results in a kernel oops.
Thanks for this patch, and my apologies for not getting back to you sooner (unfortunately qemu-linaro and the OMAP3 code are currently quite low down my todo list). This looks like the right behaviour from the OMAP3 data sheet, so I've applied it to qemu-devel. (The Linux kernels I use as my test case still worked OK without this patch, but they don't really do I2C I think.)
thanks -- PMM
linaro-toolchain@lists.linaro.org