提交 bbe48ecc 编写于 作者: J Jan Nikitenko 提交者: Linus Torvalds

spi: au1550_spi: improve pio transfer mode

Improve PIO transfer mode of au1550 spi controller by continuing of spi
transfer, instead of aborting transfer when transmit underflow interrupt
occurrs.

Verified by oscilloscope that the spi clock pauses on trasmit underflow,
so transfer continuation is perfectly valid even though au1550 datasheet
says that on tx underflow zeroes will be transfered.

Also make some error messages more specific.

[akpm@linux-foundation.org: coding-style fixes]
Signed-off-by: NJan Nikitenko <jan.nikitenko@gmail.com>
Signed-off-by: NDavid Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
上级 3a93a159
......@@ -484,9 +484,13 @@ static irqreturn_t au1550_spi_dma_irq_callback(struct au1550_spi *hw)
au1xxx_dbdma_reset(hw->dma_tx_ch);
au1550_spi_reset_fifos(hw);
dev_err(hw->dev,
"Unexpected SPI error: event=0x%x stat=0x%x!\n",
evnt, stat);
if (evnt == PSC_SPIEVNT_RO)
dev_err(hw->dev,
"dma transfer: receive FIFO overflow!\n");
else
dev_err(hw->dev,
"dma transfer: unexpected SPI error "
"(event=0x%x stat=0x%x)!\n", evnt, stat);
complete(&hw->master_done);
return IRQ_HANDLED;
......@@ -596,17 +600,17 @@ static irqreturn_t au1550_spi_pio_irq_callback(struct au1550_spi *hw)
if ((evnt & (PSC_SPIEVNT_MM | PSC_SPIEVNT_RO
| PSC_SPIEVNT_RU | PSC_SPIEVNT_TO
| PSC_SPIEVNT_TU | PSC_SPIEVNT_SD))
| PSC_SPIEVNT_SD))
!= 0) {
dev_err(hw->dev,
"Unexpected SPI error: event=0x%x stat=0x%x!\n",
evnt, stat);
/*
* due to an error we consider transfer as done,
* so mask all events until before next transfer start
*/
au1550_spi_mask_ack_all(hw);
au1550_spi_reset_fifos(hw);
dev_err(hw->dev,
"pio transfer: unexpected SPI error "
"(event=0x%x stat=0x%x)!\n", evnt, stat);
complete(&hw->master_done);
return IRQ_HANDLED;
}
......@@ -620,27 +624,50 @@ static irqreturn_t au1550_spi_pio_irq_callback(struct au1550_spi *hw)
stat = hw->regs->psc_spistat;
au_sync();
if ((stat & PSC_SPISTAT_RE) == 0 && hw->rx_count < hw->len) {
/*
* Take care to not let the Rx FIFO overflow.
*
* We only write a byte if we have read one at least. Initially,
* the write fifo is full, so we should read from the read fifo
* first.
* In case we miss a word from the read fifo, we should get a
* RO event and should back out.
*/
if (!(stat & PSC_SPISTAT_RE) && hw->rx_count < hw->len) {
hw->rx_word(hw);
/* ack the receive request event */
hw->regs->psc_spievent = PSC_SPIEVNT_RR;
au_sync();
busy = 1;
}
if ((stat & PSC_SPISTAT_TF) == 0 && hw->tx_count < hw->len) {
hw->tx_word(hw);
/* ack the transmit request event */
hw->regs->psc_spievent = PSC_SPIEVNT_TR;
au_sync();
busy = 1;
if (!(stat & PSC_SPISTAT_TF) && hw->tx_count < hw->len)
hw->tx_word(hw);
}
} while (busy);
evnt = hw->regs->psc_spievent;
hw->regs->psc_spievent = PSC_SPIEVNT_RR | PSC_SPIEVNT_TR;
au_sync();
if (hw->rx_count >= hw->len || (evnt & PSC_SPIEVNT_MD) != 0) {
/*
* Restart the SPI transmission in case of a transmit underflow.
* This seems to work despite the notes in the Au1550 data book
* of Figure 8-4 with flowchart for SPI master operation:
*
* """Note 1: An XFR Error Interrupt occurs, unless masked,
* for any of the following events: Tx FIFO Underflow,
* Rx FIFO Overflow, or Multiple-master Error
* Note 2: In case of a Tx Underflow Error, all zeroes are
* transmitted."""
*
* By simply restarting the spi transfer on Tx Underflow Error,
* we assume that spi transfer was paused instead of zeroes
* transmittion mentioned in the Note 2 of Au1550 data book.
*/
if (evnt & PSC_SPIEVNT_TU) {
hw->regs->psc_spievent = PSC_SPIEVNT_TU | PSC_SPIEVNT_MD;
au_sync();
hw->regs->psc_spipcr = PSC_SPIPCR_MS;
au_sync();
}
if (hw->rx_count >= hw->len) {
/* transfer completed successfully */
au1550_spi_mask_ack_all(hw);
complete(&hw->master_done);
......@@ -729,6 +756,8 @@ static void __init au1550_spi_setup_psc_as_spi(struct au1550_spi *hw)
stat = hw->regs->psc_spistat;
au_sync();
} while ((stat & PSC_SPISTAT_DR) == 0);
au1550_spi_reset_fifos(hw);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册