aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/spi
diff options
context:
space:
mode:
authorDavid Jander <david@protonic.nl>2022-06-21 08:12:25 +0200
committerMark Brown <broonie@kernel.org>2022-06-27 13:27:17 +0100
commitae7d2346dc89ae89a6e0aabe6037591a11e593c0 (patch)
tree23155ebdfdee2cf38b3ed9bd918e323c1fcc5ca8 /include/linux/spi
parentspi: Move ctlr->cur_msg_prepared to struct spi_message (diff)
downloadlinux-dev-ae7d2346dc89ae89a6e0aabe6037591a11e593c0.tar.xz
linux-dev-ae7d2346dc89ae89a6e0aabe6037591a11e593c0.zip
spi: Don't use the message queue if possible in spi_sync
The interaction with the controller message queue and its corresponding auxiliary flags and variables requires the use of the queue_lock which is costly. Since spi_sync will transfer the complete message anyway, and not return until it is finished, there is no need to put the message into the queue if the queue is empty. This can save a lot of overhead. As an example of how significant this is, when using the MCP2518FD SPI CAN controller on a i.MX8MM SoC, the time during which the interrupt line stays active (during 3 relatively short spi_sync messages), is reduced from 98us to 72us by this patch. Signed-off-by: David Jander <david@protonic.nl> Link: https://lore.kernel.org/r/20220621061234.3626638-3-david@protonic.nl Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'include/linux/spi')
-rw-r--r--include/linux/spi/spi.h11
1 files changed, 10 insertions, 1 deletions
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index 1a75c26742f2..74261a83b5fa 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -461,6 +461,8 @@ extern struct spi_device *spi_new_ancillary_device(struct spi_device *spi, u8 ch
* @irq_flags: Interrupt enable state during PTP system timestamping
* @fallback: fallback to pio if dma transfer return failure with
* SPI_TRANS_FAIL_NO_START.
+ * @queue_empty: signal green light for opportunistically skipping the queue
+ * for spi_sync transfers.
*
* Each SPI controller can communicate with one or more @spi_device
* children. These make a small bus, sharing MOSI, MISO and SCK signals
@@ -677,6 +679,9 @@ struct spi_controller {
/* Interrupt enable state during PTP system timestamping */
unsigned long irq_flags;
+
+ /* Flag for enabling opportunistic skipping of the queue in spi_sync */
+ bool queue_empty;
};
static inline void *spi_controller_get_devdata(struct spi_controller *ctlr)
@@ -986,6 +991,7 @@ struct spi_transfer {
* @state: for use by whichever driver currently owns the message
* @resources: for resource management when the spi message is processed
* @prepared: spi_prepare_message was called for the this message
+ * @sync: this message took the direct sync path skipping the async queue
*
* A @spi_message is used to execute an atomic sequence of data transfers,
* each represented by a struct spi_transfer. The sequence is "atomic"
@@ -1037,7 +1043,10 @@ struct spi_message {
struct list_head resources;
/* spi_prepare_message was called for this message */
- bool prepared;
+ bool prepared;
+
+ /* this message is skipping the async queue */
+ bool sync;
};
static inline void spi_message_init_no_memset(struct spi_message *m)