From f66e71554bc72014d6e8e1fd90468d852a838cbc Mon Sep 17 00:00:00 2001 From: David Brownell Date: Tue, 22 Sep 2009 16:46:18 -0700 Subject: [PATCH] --- yaml --- r: 164799 b: refs/heads/master c: 568d0697f42771425ae9f1e9a3db769fef7e10b6 h: refs/heads/master i: 164797: a3b6b857a89a13f03282a77493c7c5856b46231e 164795: 64808ed00f4a96d091b165909be23ece2cffa351 164791: 12012c6775b1e26b43c3169343d6f82f218f36db 164783: acea9515e25ae1ed7848b96a92d05f26f9fbfb4d 164767: ba74105bd720c4bf3ca5b7d9d649d27c293f550f 164735: 2dac260dc36fc979390dfec515a2151247f8f410 v: v3 --- [refs] | 2 +- trunk/drivers/spi/spi.c | 59 +++++++++++++++++++++++++++++++++++ trunk/include/linux/spi/spi.h | 39 ++--------------------- 3 files changed, 63 insertions(+), 37 deletions(-) diff --git a/[refs] b/[refs] index 9114514963c4..19a8605e56b3 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 7869c0b9ed44404bbc675ef76f8ccb3be5496f39 +refs/heads/master: 568d0697f42771425ae9f1e9a3db769fef7e10b6 diff --git a/trunk/drivers/spi/spi.c b/trunk/drivers/spi/spi.c index 49e84860c8da..b76f2468a84a 100644 --- a/trunk/drivers/spi/spi.c +++ b/trunk/drivers/spi/spi.c @@ -663,6 +663,65 @@ int spi_setup(struct spi_device *spi) } EXPORT_SYMBOL_GPL(spi_setup); +/** + * spi_async - asynchronous SPI transfer + * @spi: device with which data will be exchanged + * @message: describes the data transfers, including completion callback + * Context: any (irqs may be blocked, etc) + * + * This call may be used in_irq and other contexts which can't sleep, + * as well as from task contexts which can sleep. + * + * The completion callback is invoked in a context which can't sleep. + * Before that invocation, the value of message->status is undefined. + * When the callback is issued, message->status holds either zero (to + * indicate complete success) or a negative error code. After that + * callback returns, the driver which issued the transfer request may + * deallocate the associated memory; it's no longer in use by any SPI + * core or controller driver code. + * + * Note that although all messages to a spi_device are handled in + * FIFO order, messages may go to different devices in other orders. + * Some device might be higher priority, or have various "hard" access + * time requirements, for example. + * + * On detection of any fault during the transfer, processing of + * the entire message is aborted, and the device is deselected. + * Until returning from the associated message completion callback, + * no other spi_message queued to that device will be processed. + * (This rule applies equally to all the synchronous transfer calls, + * which are wrappers around this core asynchronous primitive.) + */ +int spi_async(struct spi_device *spi, struct spi_message *message) +{ + struct spi_master *master = spi->master; + + /* Half-duplex links include original MicroWire, and ones with + * only one data pin like SPI_3WIRE (switches direction) or where + * either MOSI or MISO is missing. They can also be caused by + * software limitations. + */ + if ((master->flags & SPI_MASTER_HALF_DUPLEX) + || (spi->mode & SPI_3WIRE)) { + struct spi_transfer *xfer; + unsigned flags = master->flags; + + list_for_each_entry(xfer, &message->transfers, transfer_list) { + if (xfer->rx_buf && xfer->tx_buf) + return -EINVAL; + if ((flags & SPI_MASTER_NO_TX) && xfer->tx_buf) + return -EINVAL; + if ((flags & SPI_MASTER_NO_RX) && xfer->rx_buf) + return -EINVAL; + } + } + + message->spi = spi; + message->status = -EINPROGRESS; + return master->transfer(spi, message); +} +EXPORT_SYMBOL_GPL(spi_async); + /*-------------------------------------------------------------------------*/ diff --git a/trunk/include/linux/spi/spi.h b/trunk/include/linux/spi/spi.h index e2051f39f6a8..97b60b37f445 100644 --- a/trunk/include/linux/spi/spi.h +++ b/trunk/include/linux/spi/spi.h @@ -258,6 +258,8 @@ struct spi_master { /* other constraints relevant to this driver */ u16 flags; #define SPI_MASTER_HALF_DUPLEX BIT(0) /* can't do full duplex */ +#define SPI_MASTER_NO_RX BIT(1) /* can't do buffer read */ +#define SPI_MASTER_NO_TX BIT(2) /* can't do buffer write */ /* Setup mode and clock, etc (spi driver may call many times). * @@ -538,42 +540,7 @@ static inline void spi_message_free(struct spi_message *m) } extern int spi_setup(struct spi_device *spi); - -/** - * spi_async - asynchronous SPI transfer - * @spi: device with which data will be exchanged - * @message: describes the data transfers, including completion callback - * Context: any (irqs may be blocked, etc) - * - * This call may be used in_irq and other contexts which can't sleep, - * as well as from task contexts which can sleep. - * - * The completion callback is invoked in a context which can't sleep. - * Before that invocation, the value of message->status is undefined. - * When the callback is issued, message->status holds either zero (to - * indicate complete success) or a negative error code. After that - * callback returns, the driver which issued the transfer request may - * deallocate the associated memory; it's no longer in use by any SPI - * core or controller driver code. - * - * Note that although all messages to a spi_device are handled in - * FIFO order, messages may go to different devices in other orders. - * Some device might be higher priority, or have various "hard" access - * time requirements, for example. - * - * On detection of any fault during the transfer, processing of - * the entire message is aborted, and the device is deselected. - * Until returning from the associated message completion callback, - * no other spi_message queued to that device will be processed. - * (This rule applies equally to all the synchronous transfer calls, - * which are wrappers around this core asynchronous primitive.) - */ -static inline int -spi_async(struct spi_device *spi, struct spi_message *message) -{ - message->spi = spi; - return spi->master->transfer(spi, message); -} +extern int spi_async(struct spi_device *spi, struct spi_message *message); /*---------------------------------------------------------------------------*/