aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/spi
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2014-12-09 16:38:05 -0500
committerMark Brown <broonie@kernel.org>2014-12-11 07:23:51 -0500
commit0461a4149836c792d186027c8c859637a4cfb11a (patch)
tree38b297f0532201cec0e3562bcd41f48d065c3416 /include/linux/spi
parent983aee5d7090cf12b624f18533777caa09d067b1 (diff)
spi: Pump transfers inside calling context for spi_sync()
If we are using the standard SPI message pump (which all drivers should be transitioning over to) then special case the message enqueue and instead of starting the worker thread to push messages to the hardware do so in the context of the caller if the controller is idle. This avoids a context switch in the common case where the controller has a single user in a single thread, for short PIO transfers there may be no need to context switch away from the calling context to complete the transfer. The code is a bit more complex than is desirable in part due to the need to handle drivers not using the standard queue and in part due to handling the various combinations of bus locking and asynchronous submission in interrupt context. It is still suboptimal since it will still wake the message pump for each transfer in order to schedule idling of the hardware and if multiple contexts are using the controller simultaneously a caller may end up pumping a message for some random other thread rather than for itself, and if the thread ends up deferring due to another context idling the hardware then it will just busy wait. It can, however, have the benefit of aggregating power up and down of the hardware when a caller performs a series of transfers back to back without any need for the use of spi_async(). Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'include/linux/spi')
-rw-r--r--include/linux/spi/spi.h2
1 files changed, 2 insertions, 0 deletions
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index a6ef2a8e6de4..4e6db75e9469 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -260,6 +260,7 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv)
260 * @pump_messages: work struct for scheduling work to the message pump 260 * @pump_messages: work struct for scheduling work to the message pump
261 * @queue_lock: spinlock to syncronise access to message queue 261 * @queue_lock: spinlock to syncronise access to message queue
262 * @queue: message queue 262 * @queue: message queue
263 * @idling: the device is entering idle state
263 * @cur_msg: the currently in-flight message 264 * @cur_msg: the currently in-flight message
264 * @cur_msg_prepared: spi_prepare_message was called for the currently 265 * @cur_msg_prepared: spi_prepare_message was called for the currently
265 * in-flight message 266 * in-flight message
@@ -425,6 +426,7 @@ struct spi_master {
425 spinlock_t queue_lock; 426 spinlock_t queue_lock;
426 struct list_head queue; 427 struct list_head queue;
427 struct spi_message *cur_msg; 428 struct spi_message *cur_msg;
429 bool idling;
428 bool busy; 430 bool busy;
429 bool running; 431 bool running;
430 bool rt; 432 bool rt;