Skip to content

Commit

Permalink
spi/fsl-espi: avoid infinite loops on fsl_espi_cpu_irq()
Browse files Browse the repository at this point in the history
It brought nearly infinite loops, and was possible to be
occurred only if the SPI transaction total size are not
alighed with 4. Loops are here at while (tmp--),
tmp is unsigned, and set it with minus value.

The loops are executed as a result of unexpected RX interrupt
occurrence after that. This interrupt may be hardware eratta
and is not fixed.

Fix mspi->len from minus value to 0 and print warning message.

Signed-off-by: Nobuteru Hayashi <hayashi.nbb@ncos.nec.co.jp>
Signed-off-by: Mark Brown <broonie@kernel.org>
  • Loading branch information
Nobuteru Hayashi authored and Mark Brown committed Mar 28, 2016
1 parent aa70e56 commit 6319a68
Showing 1 changed file with 9 additions and 1 deletion.
10 changes: 9 additions & 1 deletion drivers/spi/spi-fsl-espi.c
Original file line number Diff line number Diff line change
Expand Up @@ -544,6 +544,7 @@ void fsl_espi_cpu_irq(struct mpc8xxx_spi *mspi, u32 events)
if (events & SPIE_NE) {
u32 rx_data, tmp;
u8 rx_data_8;
int rx_nr_bytes = 4;
int ret;

/* Spin until RX is done */
Expand All @@ -560,7 +561,14 @@ void fsl_espi_cpu_irq(struct mpc8xxx_spi *mspi, u32 events)

if (mspi->len >= 4) {
rx_data = mpc8xxx_spi_read_reg(&reg_base->receive);
} else if (mspi->len <= 0) {
dev_err(mspi->dev,
"unexpected RX(SPIE_NE) interrupt occurred,\n"
"(local rxlen %d bytes, reg rxlen %d bytes)\n",
min(4, mspi->len), SPIE_RXCNT(events));
rx_nr_bytes = 0;
} else {
rx_nr_bytes = mspi->len;
tmp = mspi->len;
rx_data = 0;
while (tmp--) {
Expand All @@ -571,7 +579,7 @@ void fsl_espi_cpu_irq(struct mpc8xxx_spi *mspi, u32 events)
rx_data <<= (4 - mspi->len) * 8;
}

mspi->len -= 4;
mspi->len -= rx_nr_bytes;

if (mspi->rx)
mspi->get_rx(rx_data, mspi);
Expand Down

0 comments on commit 6319a68

Please sign in to comment.