aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi/spi.c
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2012-12-01 22:54:25 -0500
committerGrant Likely <grant.likely@secretlab.ca>2012-12-06 09:03:14 -0500
commitb3a223ee2d1a4635b0643c547bc0096a37334ed1 (patch)
tree0b0e7891825af66e8ecfdc6e3f14bbf2b1941991 /drivers/spi/spi.c
parent266904c77911fdc0a064d97e2f06034b824c23ac (diff)
spi: Remove SPI_BUFSIZ restriction on spi_write_then_read()
In order to avoid constantly allocating and deallocating there is a fixed buffer which spi_write_then_read() uses for transfers, with an early error check to ensure that the transfer fits within the buffer. This limits the size of transfers to this size, currently max(32, SMP_CACHE_BYTES). Since we can dynamically allocate and in fact already have a fallback to do so when there is contention for the fixed buffer remove this restriction and instead dynamically allocate a suitably sized buffer if the transfer won't fit. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Diffstat (limited to 'drivers/spi/spi.c')
-rw-r--r--drivers/spi/spi.c24
1 files changed, 11 insertions, 13 deletions
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index f1217ae59f3d..22c71e238fdf 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -1545,12 +1545,18 @@ int spi_write_then_read(struct spi_device *spi,
1545 struct spi_transfer x[2]; 1545 struct spi_transfer x[2];
1546 u8 *local_buf; 1546 u8 *local_buf;
1547 1547
1548 /* Use preallocated DMA-safe buffer. We can't avoid copying here, 1548 /* Use preallocated DMA-safe buffer if we can. We can't avoid
1549 * (as a pure convenience thing), but we can keep heap costs 1549 * copying here, (as a pure convenience thing), but we can
1550 * out of the hot path ... 1550 * keep heap costs out of the hot path unless someone else is
1551 * using the pre-allocated buffer or the transfer is too large.
1551 */ 1552 */
1552 if ((n_tx + n_rx) > SPI_BUFSIZ) 1553 if ((n_tx + n_rx) > SPI_BUFSIZ || !mutex_trylock(&lock)) {
1553 return -EINVAL; 1554 local_buf = kmalloc(max(SPI_BUFSIZ, n_tx + n_rx), GFP_KERNEL);
1555 if (!local_buf)
1556 return -ENOMEM;
1557 } else {
1558 local_buf = buf;
1559 }
1554 1560
1555 spi_message_init(&message); 1561 spi_message_init(&message);
1556 memset(x, 0, sizeof x); 1562 memset(x, 0, sizeof x);
@@ -1563,14 +1569,6 @@ int spi_write_then_read(struct spi_device *spi,
1563 spi_message_add_tail(&x[1], &message); 1569 spi_message_add_tail(&x[1], &message);
1564 } 1570 }
1565 1571
1566 /* ... unless someone else is using the pre-allocated buffer */
1567 if (!mutex_trylock(&lock)) {
1568 local_buf = kmalloc(SPI_BUFSIZ, GFP_KERNEL);
1569 if (!local_buf)
1570 return -ENOMEM;
1571 } else
1572 local_buf = buf;
1573
1574 memcpy(local_buf, txbuf, n_tx); 1572 memcpy(local_buf, txbuf, n_tx);
1575 x[0].tx_buf = local_buf; 1573 x[0].tx_buf = local_buf;
1576 x[1].rx_buf = local_buf + n_tx; 1574 x[1].rx_buf = local_buf + n_tx;