aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi/spi.c
diff options
context:
space:
mode:
authorMark Brown <broonie@linaro.org>2013-11-13 18:44:15 -0500
committerMark Brown <broonie@linaro.org>2013-11-24 09:04:17 -0500
commit90808738fd242ef2533e86f2f481bebe8a7aa11b (patch)
tree9a5debdf86da3fe08616f56c3c1246fe95f6f7d1 /drivers/spi/spi.c
parent6ce4eac1f600b34f2f7f58f9cd8f0503d79e42ae (diff)
spi: Factor validation and initialisation of messages outside lock
Currently we do a bunch of per-message validation and initialisation in __spi_async() which is called with the bus lock held. Since none of this validation depends on the current bus status there's no need to hold the lock to do it so split it out into a separate __spi_validate() function which is called prior to taking the bus lock. This could be slightly neater but keep things simple for now to show the code motion clearly. Based on observations from Martin Sperl. Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'drivers/spi/spi.c')
-rw-r--r--drivers/spi/spi.c26
1 files changed, 21 insertions, 5 deletions
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 18cc625d887f..857ee8c407b1 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -1596,15 +1596,11 @@ int spi_setup(struct spi_device *spi)
1596} 1596}
1597EXPORT_SYMBOL_GPL(spi_setup); 1597EXPORT_SYMBOL_GPL(spi_setup);
1598 1598
1599static int __spi_async(struct spi_device *spi, struct spi_message *message) 1599static int __spi_validate(struct spi_device *spi, struct spi_message *message)
1600{ 1600{
1601 struct spi_master *master = spi->master; 1601 struct spi_master *master = spi->master;
1602 struct spi_transfer *xfer; 1602 struct spi_transfer *xfer;
1603 1603
1604 message->spi = spi;
1605
1606 trace_spi_message_submit(message);
1607
1608 if (list_empty(&message->transfers)) 1604 if (list_empty(&message->transfers))
1609 return -EINVAL; 1605 return -EINVAL;
1610 if (!message->complete) 1606 if (!message->complete)
@@ -1705,6 +1701,18 @@ static int __spi_async(struct spi_device *spi, struct spi_message *message)
1705 } 1701 }
1706 1702
1707 message->status = -EINPROGRESS; 1703 message->status = -EINPROGRESS;
1704
1705 return 0;
1706}
1707
1708static int __spi_async(struct spi_device *spi, struct spi_message *message)
1709{
1710 struct spi_master *master = spi->master;
1711
1712 message->spi = spi;
1713
1714 trace_spi_message_submit(message);
1715
1708 return master->transfer(spi, message); 1716 return master->transfer(spi, message);
1709} 1717}
1710 1718
@@ -1743,6 +1751,10 @@ int spi_async(struct spi_device *spi, struct spi_message *message)
1743 int ret; 1751 int ret;
1744 unsigned long flags; 1752 unsigned long flags;
1745 1753
1754 ret = __spi_validate(spi, message);
1755 if (ret != 0)
1756 return ret;
1757
1746 spin_lock_irqsave(&master->bus_lock_spinlock, flags); 1758 spin_lock_irqsave(&master->bus_lock_spinlock, flags);
1747 1759
1748 if (master->bus_lock_flag) 1760 if (master->bus_lock_flag)
@@ -1791,6 +1803,10 @@ int spi_async_locked(struct spi_device *spi, struct spi_message *message)
1791 int ret; 1803 int ret;
1792 unsigned long flags; 1804 unsigned long flags;
1793 1805
1806 ret = __spi_validate(spi, message);
1807 if (ret != 0)
1808 return ret;
1809
1794 spin_lock_irqsave(&master->bus_lock_spinlock, flags); 1810 spin_lock_irqsave(&master->bus_lock_spinlock, flags);
1795 1811
1796 ret = __spi_async(spi, message); 1812 ret = __spi_async(spi, message);