• Cyrille Pitchen's avatar
    i2c: at91: fix a race condition when using the DMA controller · 93563a6a
    Cyrille Pitchen authored
    For TX transactions, the TXCOMP bit in the Status Register is cleared
    when the first data is written into the Transmit Holding Register.
    
    In the lines from at91_do_twi_transfer():
    at91_twi_write_data_dma(dev);
    at91_twi_write(dev, AT91_TWI_IER, AT91_TWI_TXCOMP);
    
    the TXCOMP interrupt may be enabled before the DMA controller has
    actually started to write into the THR. In such a case, the TXCOMP bit
    is still set into the Status Register so the interrupt is triggered
    immediately. The driver understands that a transaction completion has
    occurred but this transaction hasn't started yet. Hence the TXCOMP
    interrupt is no longer enabled by at91_do_twi_transfer() but instead
    by at91_twi_write_data_dma_callback().
    
    Also, the TXCOMP bit in the Status Register in not a clear on read flag
    but a snapshot of the transmission state at the time the Status
    Register is read.
    When a NACK error is dectected by the I2C controller, the TXCOMP, NACK
    and TXRDY bits are set together to 1 in the SR. If enabled, the TXCOMP
    interrupt is triggered at the same time. Also setting the TXRDY to 1
    triggers the DMA controller to write the next data into the THR. Such
    a write resets the TXCOMP bit to 0 in the SR. So depending on when the
    interrupt handler reads the SR, it may fail to detect the NACK error
    if it relies on the TXCOMP bit. The NACK bit and its interrupt should
    be used instead.
    
    For RX transactions, the TXCOMP bit in the Status Register is cleared
    when the START bit is set into the Control Register. However to unify
    the management of the TXCOMP bit when the DMA controller is used, the
    TXCOMP interrupt is now enabled by the DMA callbacks for both TX and
    RX transfers.
    Signed-off-by: default avatarCyrille Pitchen <cyrille.pitchen@atmel.com>
    Cc: stable@vger.kernel.org #3.10 and later
    Acked-by: default avatarLudovic Desroches <ludovic.desroches@atmel.com>
    Signed-off-by: default avatarWolfram Sang <wsa@the-dreams.de>
    93563a6a
i2c-at91.c 24.7 KB