diff options
author | Mark Brown <broonie@linaro.org> | 2014-01-23 13:07:01 +0000 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2014-01-23 13:07:01 +0000 |
commit | 3c1039745ef2925aceed53d38af0cddac8e36f31 (patch) | |
tree | 163fe6bf0ab203d69712936b3bda5d3e98acdeee /drivers/spi/spi.c | |
parent | 7e2c225d585cd6d7481ff4ec446a67334ef11f4d (diff) | |
parent | 1afd9989a6a2561183be82e420d4d2f3889b7ee7 (diff) | |
download | linux-3c1039745ef2925aceed53d38af0cddac8e36f31.tar.bz2 |
Merge remote-tracking branch 'spi/topic/core' into spi-linus
Diffstat (limited to 'drivers/spi/spi.c')
-rw-r--r-- | drivers/spi/spi.c | 46 |
1 files changed, 26 insertions, 20 deletions
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 965dd8ac5939..63613a96233c 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -695,7 +695,7 @@ static void spi_pump_messages(struct kthread_work *work) } /* Extract head of queue */ master->cur_msg = - list_entry(master->queue.next, struct spi_message, queue); + list_first_entry(&master->queue, struct spi_message, queue); list_del_init(&master->cur_msg->queue); if (master->busy) @@ -803,11 +803,8 @@ struct spi_message *spi_get_next_queued_message(struct spi_master *master) /* get a pointer to the next message, if any */ spin_lock_irqsave(&master->queue_lock, flags); - if (list_empty(&master->queue)) - next = NULL; - else - next = list_entry(master->queue.next, - struct spi_message, queue); + next = list_first_entry_or_null(&master->queue, struct spi_message, + queue); spin_unlock_irqrestore(&master->queue_lock, flags); return next; @@ -1608,15 +1605,11 @@ int spi_setup(struct spi_device *spi) } EXPORT_SYMBOL_GPL(spi_setup); -static int __spi_async(struct spi_device *spi, struct spi_message *message) +static int __spi_validate(struct spi_device *spi, struct spi_message *message) { struct spi_master *master = spi->master; struct spi_transfer *xfer; - message->spi = spi; - - trace_spi_message_submit(message); - if (list_empty(&message->transfers)) return -EINVAL; if (!message->complete) @@ -1679,9 +1672,8 @@ static int __spi_async(struct spi_device *spi, struct spi_message *message) if (xfer->rx_buf && !xfer->rx_nbits) xfer->rx_nbits = SPI_NBITS_SINGLE; /* check transfer tx/rx_nbits: - * 1. keep the value is not out of single, dual and quad - * 2. keep tx/rx_nbits is contained by mode in spi_device - * 3. if SPI_3WIRE, tx/rx_nbits should be in single + * 1. check the value matches one of single, dual and quad + * 2. check tx/rx_nbits match the mode in spi_device */ if (xfer->tx_buf) { if (xfer->tx_nbits != SPI_NBITS_SINGLE && @@ -1694,9 +1686,6 @@ static int __spi_async(struct spi_device *spi, struct spi_message *message) if ((xfer->tx_nbits == SPI_NBITS_QUAD) && !(spi->mode & SPI_TX_QUAD)) return -EINVAL; - if ((spi->mode & SPI_3WIRE) && - (xfer->tx_nbits != SPI_NBITS_SINGLE)) - return -EINVAL; } /* check transfer rx_nbits */ if (xfer->rx_buf) { @@ -1710,13 +1699,22 @@ static int __spi_async(struct spi_device *spi, struct spi_message *message) if ((xfer->rx_nbits == SPI_NBITS_QUAD) && !(spi->mode & SPI_RX_QUAD)) return -EINVAL; - if ((spi->mode & SPI_3WIRE) && - (xfer->rx_nbits != SPI_NBITS_SINGLE)) - return -EINVAL; } } message->status = -EINPROGRESS; + + return 0; +} + +static int __spi_async(struct spi_device *spi, struct spi_message *message) +{ + struct spi_master *master = spi->master; + + message->spi = spi; + + trace_spi_message_submit(message); + return master->transfer(spi, message); } @@ -1755,6 +1753,10 @@ int spi_async(struct spi_device *spi, struct spi_message *message) int ret; unsigned long flags; + ret = __spi_validate(spi, message); + if (ret != 0) + return ret; + spin_lock_irqsave(&master->bus_lock_spinlock, flags); if (master->bus_lock_flag) @@ -1803,6 +1805,10 @@ int spi_async_locked(struct spi_device *spi, struct spi_message *message) int ret; unsigned long flags; + ret = __spi_validate(spi, message); + if (ret != 0) + return ret; + spin_lock_irqsave(&master->bus_lock_spinlock, flags); ret = __spi_async(spi, message); |