H. Nikolaus Schaller
hns at goldelico.com
Sat Feb 13 15:11:14 CET 2021
I finally found a way how I can inspect what the interrupt handler is really
First change was to get rid of the spinlocks. And replace by mutex. This can
be done because we use a threaded interrupt.
The second trick was to move all disturbing printk outside the interrupt routine.
To achieve this I have added a struct-array to log all important variables in
before and after processing in the interrupt handler. This takes just 1-2us
processor time (I hope). And I can even read out the ICSR to see if an IRQ
is pending or not.
Printout is done in the xfer function after all interrupt operations should
With this I was now able to analyse what is going on. It seems as if sending STA
or STO generates and IRQ. And after STA is sent, there is also an IRQ. So
I send the address byte.
Now, there is a a problem. It appears that the next interrupt occurs before
the data byte has been sent. Well, FIFO behaviour...
This als means that the ACKF is not yet valid. And even worse, my test command
i2cdetect -y 0 0x27 0x29 >/dev/null
sends out data packets with 0 bytes. So it should just send STA + address + ACK + STO.
What I have not found is the IRQ mechanism to reset the IRQ if there is no
more data. The IRQ stays pending and is processed by the kernel right again
and my state engine immediately runs through to the end.
The flow charts in the data sheet unfortunately do not tell in any way how
to stop another IRQ after sending the last byte and how to properly switch
to read mode.
What I know is that sending STO does end this, but that is brute force and
not the general case...
Do you have an idea what condition clears the data IRQ if there is no data
to send? We only can write AC to CR or DRF to SR. Both are 0.
> Am 26.01.2021 um 11:25 schrieb H. Nikolaus Schaller <hns at goldelico.com>:
> Hi Paul,
> I think I may have a hint why "spurious interrupts" are reported by
> in my latest i2c driver.
> If I compare the "1.5.2 Write Operation" and "1.5.3 Read Operation",
> the write operation sets the STO bit and then waits for ACKF/TEND.
> While for read the STO isn't even mentioned!
> And if I think about my state machine, there is no such state
> "Wait for STO sent" after finishing the write. Maybe it suffices
> to add another state after sending the STO which IMHO generates
> another IRQ when done.
> I think I also have to study again how I2C works, especially who
> is sending the STO and how it relates to who generates the ACK.
> What I have also started to try is to blacklist on my test setup
> all i2c clients and the i2s driver through some /etc/modprobe.d/blacklist.conf.
> This makes the device boot fine and gives a nice platform for
> individually loading and testing drivers...
> Well, blacklisting the jz4780_dma driver failed because this
> ends in a deadlock for MMC initialization.
More information about the Letux-kernel