Commit 568d0697f42771425ae9f1e9a3db769fef7e10b6

Authored by David Brownell
Committed by Linus Torvalds
1 parent 7869c0b9ed

spi: handle TX-only/RX-only

Support two new half-duplex SPI implementation restrictions, for links
that talk to TX-only or RX-only devices.  (Existing half-duplex flavors
support both transfer directions, just not at the same time.)

Move spi_async() into the spi.c core, and stop inlining it.  Then make
that function perform error checks and reject messages that demand more
than the underlying controller can support.

Based on a patch from Marek Szyprowski which did this only for the
bitbanged GPIO driver.

Cc: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 2 changed files with 62 additions and 36 deletions Side-by-side Diff

... ... @@ -663,6 +663,65 @@
663 663 }
664 664 EXPORT_SYMBOL_GPL(spi_setup);
665 665  
  666 +/**
  667 + * spi_async - asynchronous SPI transfer
  668 + * @spi: device with which data will be exchanged
  669 + * @message: describes the data transfers, including completion callback
  670 + * Context: any (irqs may be blocked, etc)
  671 + *
  672 + * This call may be used in_irq and other contexts which can't sleep,
  673 + * as well as from task contexts which can sleep.
  674 + *
  675 + * The completion callback is invoked in a context which can't sleep.
  676 + * Before that invocation, the value of message->status is undefined.
  677 + * When the callback is issued, message->status holds either zero (to
  678 + * indicate complete success) or a negative error code. After that
  679 + * callback returns, the driver which issued the transfer request may
  680 + * deallocate the associated memory; it's no longer in use by any SPI
  681 + * core or controller driver code.
  682 + *
  683 + * Note that although all messages to a spi_device are handled in
  684 + * FIFO order, messages may go to different devices in other orders.
  685 + * Some device might be higher priority, or have various "hard" access
  686 + * time requirements, for example.
  687 + *
  688 + * On detection of any fault during the transfer, processing of
  689 + * the entire message is aborted, and the device is deselected.
  690 + * Until returning from the associated message completion callback,
  691 + * no other spi_message queued to that device will be processed.
  692 + * (This rule applies equally to all the synchronous transfer calls,
  693 + * which are wrappers around this core asynchronous primitive.)
  694 + */
  695 +int spi_async(struct spi_device *spi, struct spi_message *message)
  696 +{
  697 + struct spi_master *master = spi->master;
  698 +
  699 + /* Half-duplex links include original MicroWire, and ones with
  700 + * only one data pin like SPI_3WIRE (switches direction) or where
  701 + * either MOSI or MISO is missing. They can also be caused by
  702 + * software limitations.
  703 + */
  704 + if ((master->flags & SPI_MASTER_HALF_DUPLEX)
  705 + || (spi->mode & SPI_3WIRE)) {
  706 + struct spi_transfer *xfer;
  707 + unsigned flags = master->flags;
  708 +
  709 + list_for_each_entry(xfer, &message->transfers, transfer_list) {
  710 + if (xfer->rx_buf && xfer->tx_buf)
  711 + return -EINVAL;
  712 + if ((flags & SPI_MASTER_NO_TX) && xfer->tx_buf)
  713 + return -EINVAL;
  714 + if ((flags & SPI_MASTER_NO_RX) && xfer->rx_buf)
  715 + return -EINVAL;
  716 + }
  717 + }
  718 +
  719 + message->spi = spi;
  720 + message->status = -EINPROGRESS;
  721 + return master->transfer(spi, message);
  722 +}
  723 +EXPORT_SYMBOL_GPL(spi_async);
  724 +
666 725  
667 726 /*-------------------------------------------------------------------------*/
668 727  
include/linux/spi/spi.h
... ... @@ -258,6 +258,8 @@
258 258 /* other constraints relevant to this driver */
259 259 u16 flags;
260 260 #define SPI_MASTER_HALF_DUPLEX BIT(0) /* can't do full duplex */
  261 +#define SPI_MASTER_NO_RX BIT(1) /* can't do buffer read */
  262 +#define SPI_MASTER_NO_TX BIT(2) /* can't do buffer write */
261 263  
262 264 /* Setup mode and clock, etc (spi driver may call many times).
263 265 *
... ... @@ -538,42 +540,7 @@
538 540 }
539 541  
540 542 extern int spi_setup(struct spi_device *spi);
541   -
542   -/**
543   - * spi_async - asynchronous SPI transfer
544   - * @spi: device with which data will be exchanged
545   - * @message: describes the data transfers, including completion callback
546   - * Context: any (irqs may be blocked, etc)
547   - *
548   - * This call may be used in_irq and other contexts which can't sleep,
549   - * as well as from task contexts which can sleep.
550   - *
551   - * The completion callback is invoked in a context which can't sleep.
552   - * Before that invocation, the value of message->status is undefined.
553   - * When the callback is issued, message->status holds either zero (to
554   - * indicate complete success) or a negative error code. After that
555   - * callback returns, the driver which issued the transfer request may
556   - * deallocate the associated memory; it's no longer in use by any SPI
557   - * core or controller driver code.
558   - *
559   - * Note that although all messages to a spi_device are handled in
560   - * FIFO order, messages may go to different devices in other orders.
561   - * Some device might be higher priority, or have various "hard" access
562   - * time requirements, for example.
563   - *
564   - * On detection of any fault during the transfer, processing of
565   - * the entire message is aborted, and the device is deselected.
566   - * Until returning from the associated message completion callback,
567   - * no other spi_message queued to that device will be processed.
568   - * (This rule applies equally to all the synchronous transfer calls,
569   - * which are wrappers around this core asynchronous primitive.)
570   - */
571   -static inline int
572   -spi_async(struct spi_device *spi, struct spi_message *message)
573   -{
574   - message->spi = spi;
575   - return spi->master->transfer(spi, message);
576   -}
  543 +extern int spi_async(struct spi_device *spi, struct spi_message *message);
577 544  
578 545 /*---------------------------------------------------------------------------*/
579 546