diff options
author | Bin Meng <bmeng.cn@gmail.com> | 2014-12-10 16:35:50 +0800 |
---|---|---|
committer | Simon Glass <sjg@chromium.org> | 2014-12-13 15:08:04 -0700 |
commit | 15c7c6b31ad8742bd6e63be35f82193895ff8bdd (patch) | |
tree | 3efb8cf25046f533e11d31aada8a4e8ac78293e6 | |
parent | a5a58826110eb3da2956c6b3213bd750e166d75c (diff) | |
download | u-boot-imx-15c7c6b31ad8742bd6e63be35f82193895ff8bdd.zip u-boot-imx-15c7c6b31ad8742bd6e63be35f82193895ff8bdd.tar.gz u-boot-imx-15c7c6b31ad8742bd6e63be35f82193895ff8bdd.tar.bz2 |
x86: ich-spi: Fix a bug of reading from a non-64 bytes aligned address
The ich spi controller driver spi_xfer() tries to align reading
address to 64 bytes when doing spi data in, which causes a bug of
either infinite loop or a huge size memcpy().
Actually the ich spi controller does not have such requirement of
64 bytes alignment when reading data from spi slave devices.
Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
Acked-by: Simon Glass <sjg@chromium.org>
Tested-by: Simon Glass <sjg@chromium.org>
-rw-r--r-- | drivers/spi/ich.c | 17 |
1 files changed, 2 insertions, 15 deletions
diff --git a/drivers/spi/ich.c b/drivers/spi/ich.c index f5c6f3e..c4d3a29 100644 --- a/drivers/spi/ich.c +++ b/drivers/spi/ich.c @@ -483,8 +483,6 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, struct spi_trans *trans = &ich->trans; unsigned type = flags & (SPI_XFER_BEGIN | SPI_XFER_END); int using_cmd = 0; - /* Align read transactions to 64-byte boundaries */ - char buff[ctlr.databytes]; /* Ee don't support writing partial bytes. */ if (bitlen % 8) { @@ -632,14 +630,9 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, */ while (trans->bytesout || trans->bytesin) { uint32_t data_length; - uint32_t aligned_offset; - uint32_t diff; - - aligned_offset = trans->offset & ~(ctlr.databytes - 1); - diff = trans->offset - aligned_offset; /* SPI addresses are 24 bit only */ - ich_writel(aligned_offset & 0x00FFFFFF, ctlr.addr); + ich_writel(trans->offset & 0x00FFFFFF, ctlr.addr); if (trans->bytesout) data_length = min(trans->bytesout, ctlr.databytes); @@ -673,13 +666,7 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, } if (trans->bytesin) { - if (diff) { - data_length -= diff; - read_reg(ctlr.data, buff, ctlr.databytes); - memcpy(trans->in, buff + diff, data_length); - } else { - read_reg(ctlr.data, trans->in, data_length); - } + read_reg(ctlr.data, trans->in, data_length); spi_use_in(trans, data_length); if (with_address) trans->offset += data_length; |