aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi/spi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/spi/spi.c')
-rw-r--r--drivers/spi/spi.c46
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)
695 } 695 }
696 /* Extract head of queue */ 696 /* Extract head of queue */
697 master->cur_msg = 697 master->cur_msg =
698 list_entry(master->queue.next, struct spi_message, queue); 698 list_first_entry(&master->queue, struct spi_message, queue);
699 699
700 list_del_init(&master->cur_msg->queue); 700 list_del_init(&master->cur_msg->queue);
701 if (master->busy) 701 if (master->busy)
@@ -803,11 +803,8 @@ struct spi_message *spi_get_next_queued_message(struct spi_master *master)
803 803
804 /* get a pointer to the next message, if any */ 804 /* get a pointer to the next message, if any */
805 spin_lock_irqsave(&master->queue_lock, flags); 805 spin_lock_irqsave(&master->queue_lock, flags);
806 if (list_empty(&master->queue)) 806 next = list_first_entry_or_null(&master->queue, struct spi_message,
807 next = NULL; 807 queue);
808 else
809 next = list_entry(master->queue.next,
810 struct spi_message, queue);
811 spin_unlock_irqrestore(&master->queue_lock, flags); 808 spin_unlock_irqrestore(&master->queue_lock, flags);
812 809
813 return next; 810 return next;
@@ -1608,15 +1605,11 @@ int spi_setup(struct spi_device *spi)
1608} 1605}
1609EXPORT_SYMBOL_GPL(spi_setup); 1606EXPORT_SYMBOL_GPL(spi_setup);
1610 1607
1611static int __spi_async(struct spi_device *spi, struct spi_message *message) 1608static int __spi_validate(struct spi_device *spi, struct spi_message *message)
1612{ 1609{
1613 struct spi_master *master = spi->master; 1610 struct spi_master *master = spi->master;
1614 struct spi_transfer *xfer; 1611 struct spi_transfer *xfer;
1615 1612
1616 message->spi = spi;
1617
1618 trace_spi_message_submit(message);
1619
1620 if (list_empty(&message->transfers)) 1613 if (list_empty(&message->transfers))
1621 return -EINVAL; 1614 return -EINVAL;
1622 if (!message->complete) 1615 if (!message->complete)
@@ -1679,9 +1672,8 @@ static int __spi_async(struct spi_device *spi, struct spi_message *message)
1679 if (xfer->rx_buf && !xfer->rx_nbits) 1672 if (xfer->rx_buf && !xfer->rx_nbits)
1680 xfer->rx_nbits = SPI_NBITS_SINGLE; 1673 xfer->rx_nbits = SPI_NBITS_SINGLE;
1681 /* check transfer tx/rx_nbits: 1674 /* check transfer tx/rx_nbits:
1682 * 1. keep the value is not out of single, dual and quad 1675 * 1. check the value matches one of single, dual and quad
1683 * 2. keep tx/rx_nbits is contained by mode in spi_device 1676 * 2. check tx/rx_nbits match the mode in spi_device
1684 * 3. if SPI_3WIRE, tx/rx_nbits should be in single
1685 */ 1677 */
1686 if (xfer->tx_buf) { 1678 if (xfer->tx_buf) {
1687 if (xfer->tx_nbits != SPI_NBITS_SINGLE && 1679 if (xfer->tx_nbits != SPI_NBITS_SINGLE &&
@@ -1694,9 +1686,6 @@ static int __spi_async(struct spi_device *spi, struct spi_message *message)
1694 if ((xfer->tx_nbits == SPI_NBITS_QUAD) && 1686 if ((xfer->tx_nbits == SPI_NBITS_QUAD) &&
1695 !(spi->mode & SPI_TX_QUAD)) 1687 !(spi->mode & SPI_TX_QUAD))
1696 return -EINVAL; 1688 return -EINVAL;
1697 if ((spi->mode & SPI_3WIRE) &&
1698 (xfer->tx_nbits != SPI_NBITS_SINGLE))
1699 return -EINVAL;
1700 } 1689 }
1701 /* check transfer rx_nbits */ 1690 /* check transfer rx_nbits */
1702 if (xfer->rx_buf) { 1691 if (xfer->rx_buf) {
@@ -1710,13 +1699,22 @@ static int __spi_async(struct spi_device *spi, struct spi_message *message)
1710 if ((xfer->rx_nbits == SPI_NBITS_QUAD) && 1699 if ((xfer->rx_nbits == SPI_NBITS_QUAD) &&
1711 !(spi->mode & SPI_RX_QUAD)) 1700 !(spi->mode & SPI_RX_QUAD))
1712 return -EINVAL; 1701 return -EINVAL;
1713 if ((spi->mode & SPI_3WIRE) &&
1714 (xfer->rx_nbits != SPI_NBITS_SINGLE))
1715 return -EINVAL;
1716 } 1702 }
1717 } 1703 }
1718 1704
1719 message->status = -EINPROGRESS; 1705 message->status = -EINPROGRESS;
1706
1707 return 0;
1708}
1709
1710static int __spi_async(struct spi_device *spi, struct spi_message *message)
1711{
1712 struct spi_master *master = spi->master;
1713
1714 message->spi = spi;
1715
1716 trace_spi_message_submit(message);
1717
1720 return master->transfer(spi, message); 1718 return master->transfer(spi, message);
1721} 1719}
1722 1720
@@ -1755,6 +1753,10 @@ int spi_async(struct spi_device *spi, struct spi_message *message)
1755 int ret; 1753 int ret;
1756 unsigned long flags; 1754 unsigned long flags;
1757 1755
1756 ret = __spi_validate(spi, message);
1757 if (ret != 0)
1758 return ret;
1759
1758 spin_lock_irqsave(&master->bus_lock_spinlock, flags); 1760 spin_lock_irqsave(&master->bus_lock_spinlock, flags);
1759 1761
1760 if (master->bus_lock_flag) 1762 if (master->bus_lock_flag)
@@ -1803,6 +1805,10 @@ int spi_async_locked(struct spi_device *spi, struct spi_message *message)
1803 int ret; 1805 int ret;
1804 unsigned long flags; 1806 unsigned long flags;
1805 1807
1808 ret = __spi_validate(spi, message);
1809 if (ret != 0)
1810 return ret;
1811
1806 spin_lock_irqsave(&master->bus_lock_spinlock, flags); 1812 spin_lock_irqsave(&master->bus_lock_spinlock, flags);
1807 1813
1808 ret = __spi_async(spi, message); 1814 ret = __spi_async(spi, message);