The current IRQ handler clears all the IRQ status bits when it bails
out. This is dangerous because it might clear away the status bits
that have just been set while processing the current handler. If this
happens, the IRQ event for the latest transfer is lost forever.
The IRQ status bits must be cleared *before* the next transfer is
kicked.
Fixes: 6a62974b66 ("i2c: uniphier_f: add UniPhier FIFO-builtin I2C driver")
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
Currently, a timeout error could happen at a repeated START condition.
For a (non-repeated) START condition, the controller starts sending
data when the UNIPHIER_FI2C_CR_STA bit is set. However, for a repeated
START condition, the hardware starts running when the slave address is
written to the TX FIFO - the write to the UNIPHIER_FI2C_CR register is
actually unneeded.
Because the hardware is already running before the IRQ is enabled for
a repeated START, the driver may miss the IRQ event. In most cases,
this problem does not show up since modern CPUs are much faster than
the I2C transfer. However, it is still possible that a context switch
happens after the controller starts, but before the IRQ register is
set up.
To fix this,
- Do not write UNIPHIER_FI2C_CR for repeated START conditions.
- Enable IRQ *before* writing the slave address to the TX FIFO.
- Disable IRQ for the current CPU while queuing up the TX FIFO;
If the CPU is interrupted by some task, the interrupt handler
might be invoked due to the empty TX FIFO before completing the
setup.
Fixes: 6a62974b66 ("i2c: uniphier_f: add UniPhier FIFO-builtin I2C driver")
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
This is unlikely to happen, but it is possible for a CPU to enter
the interrupt handler just after wait_for_completion_timeout() has
expired. If this happens, the hardware is accessed from multiple
contexts concurrently.
Disable the IRQ after wait_for_completion_timeout(), and do nothing
from the handler when the IRQ is disabled.
Fixes: 6a62974b66 ("i2c: uniphier_f: add UniPhier FIFO-builtin I2C driver")
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
This driver currently emits a STOP if the next message is not
I2C_MD_RD. It should not do it because it disturbs the I2C_RDWR
ioctl, where read/write transactions are combined without STOP
between.
Issue STOP only when the message is the last one _or_ flagged with
I2C_M_STOP.
Fixes: 6a62974b66 ("i2c: uniphier_f: add UniPhier FIFO-builtin I2C driver")
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
When resuming, set up registers that have been lost in the sleep state.
Also, add clock handling in the resume / suspend hooks.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
Documentation/CodingStyle recommends to use label names which say
what the goto does or why the goto exists.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
Currently, the status register FI2C_SR is checked immediately after
a STOP condition is issued in case of the deferred STOP condition.
It takes typically 5-10 usec until the corresponding bits in the
register are set, so the error check for "stop condition was not
completed" is very likely to be false positive.
Add wait code to relax the status register check.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
Currently, the adapter is set to the master mode at the first use.
Since then, it is kept in the slave mode, so unexpected glitch
signals on the I2C lines may cause the adapter into insane state.
Setting it to the master mode along with initialization solves the
problem.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Reported-by: Akio Noda <noda.akio@socionext.com>
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
If clk_prepare_enable() fails, clk_disable_unprepare() is called in
the failure path, where the enable_count is still zero, so it hits
WARN_ON(core->enable_count == 0) in the clk_core_disable().
To fix this, make the clock setting more linear in the probe function
so that it can exploit "goto err" in case of error.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
The core will do this for us now.
Signed-off-by: Wolfram Sang <wsa-dev@sang-engineering.com>
Acked-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
There is code to divide by "bus_speed" some lines below.
To eliminate the possibility of division by zero, bail out if
"clock-frequency" is specified as zero.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
This input clock is used to generate the sampling clock for I2C bus.
If the clock rate is zero, there is something wrong with the clock
driver. Bail out with the appropriate error message in such a case.
It would make it easier to find the root cause of failure.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
Add support for on-chip I2C controller used on newer UniPhier SoCs
such as PH1-Pro4, PH1-Pro5, etc. This adapter is equipped with
8-depth TX/RX FIFOs.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>