]> git.baikalelectronics.ru Git - kernel.git/commit
i2c: uniphier-f: fix timeout error after reading 8 bytes
authorMasahiro Yamada <yamada.masahiro@socionext.com>
Thu, 6 Dec 2018 03:55:25 +0000 (12:55 +0900)
committerWolfram Sang <wsa@the-dreams.de>
Thu, 6 Dec 2018 22:14:59 +0000 (23:14 +0100)
commit9222c0d3a709e8a36b8952f34232ea02647eacbf
tree0b165ad0826b663ab442747201593332aed0d824
parent93a77117213fa155c1066a19e7bf8586450c1371
i2c: uniphier-f: fix timeout error after reading 8 bytes

I was totally screwed up in commit 49236733d1bf ("i2c: uniphier-f:
fix race condition when IRQ is cleared"). Since that commit, if the
number of read bytes is multiple of the FIFO size (8, 16, 24... bytes),
the STOP condition could be issued twice, depending on the timing.
If this happens, the controller will go wrong, resulting in the timeout
error.

It was more than 3 years ago when I wrote this driver, so my memory
about this hardware was vague. Please let me correct the description
in the commit log of 49236733d1bf.

Clearing the IRQ status on exiting the IRQ handler is absolutely
fine. This controller makes a pause while any IRQ status is asserted.
If the IRQ status is cleared first, the hardware may start the next
transaction before the IRQ handler finishes what it supposed to do.

This partially reverts the bad commit with clear comments so that I
will never repeat this mistake.

I also investigated what is happening at the last moment of the read
mode. The UNIPHIER_FI2C_INT_RF interrupt is asserted a bit earlier
(by half a period of the clock cycle) than UNIPHIER_FI2C_INT_RB.

I consulted a hardware engineer, and I got the following information:

UNIPHIER_FI2C_INT_RF
    asserted at the falling edge of SCL at the 8th bit.

UNIPHIER_FI2C_INT_RB
    asserted at the rising edge of SCL at the 9th (ACK) bit.

In order to avoid calling uniphier_fi2c_stop() twice, check the latter
interrupt. I also commented this because it is obscure hardware internal.

Fixes: 49236733d1bf ("i2c: uniphier-f: fix race condition when IRQ is cleared")
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
drivers/i2c/busses/i2c-uniphier-f.c