spi: Pump transfers inside calling context for spi_sync()
authorMark Brown <broonie@kernel.org>
Tue, 9 Dec 2014 21:38:05 +0000 (21:38 +0000)
committerMark Brown <broonie@kernel.org>
Thu, 11 Dec 2014 12:23:51 +0000 (12:23 +0000)
commit0461a4149836c792d186027c8c859637a4cfb11a
tree38b297f0532201cec0e3562bcd41f48d065c3416
parent983aee5d7090cf12b624f18533777caa09d067b1
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>
drivers/spi/spi.c
include/linux/spi/spi.h