aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2014-12-10 08:46:33 -0500
committerMark Brown <broonie@kernel.org>2014-12-11 07:25:30 -0500
commitfc9e0f71f2d7ea43fa3ba0bea68586d1462cb5a7 (patch)
treef32627b66f9bb1f2330f629526f0d5111360be22
parent0461a4149836c792d186027c8c859637a4cfb11a (diff)
spi: Only idle the message pump in the worker kthread
In order to avoid the situation where the kthread is waiting for another context to make the hardware idle let the message pump know if it's being called from the worker thread context and if it isn't then defer to the worker thread instead of idling the hardware immediately. This will ensure that if this situation happens we block rather than busy waiting. Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--drivers/spi/spi.c32
1 files changed, 26 insertions, 6 deletions
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index e1bf2579b9c0..3ac188fc36f5 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -875,8 +875,9 @@ void spi_finalize_current_transfer(struct spi_master *master)
875EXPORT_SYMBOL_GPL(spi_finalize_current_transfer); 875EXPORT_SYMBOL_GPL(spi_finalize_current_transfer);
876 876
877/** 877/**
878 * spi_pump_messages - kthread work function which processes spi message queue 878 * __spi_pump_messages - function which processes spi message queue
879 * @work: pointer to kthread work struct contained in the master struct 879 * @master: master to process queue for
880 * @in_kthread: true if we are in the context of the message pump thread
880 * 881 *
881 * This function checks if there is any spi message in the queue that 882 * This function checks if there is any spi message in the queue that
882 * needs processing and if so call out to the driver to initialize hardware 883 * needs processing and if so call out to the driver to initialize hardware
@@ -886,10 +887,8 @@ EXPORT_SYMBOL_GPL(spi_finalize_current_transfer);
886 * inside spi_sync(); the queue extraction handling at the top of the 887 * inside spi_sync(); the queue extraction handling at the top of the
887 * function should deal with this safely. 888 * function should deal with this safely.
888 */ 889 */
889static void spi_pump_messages(struct kthread_work *work) 890static void __spi_pump_messages(struct spi_master *master, bool in_kthread)
890{ 891{
891 struct spi_master *master =
892 container_of(work, struct spi_master, pump_messages);
893 unsigned long flags; 892 unsigned long flags;
894 bool was_busy = false; 893 bool was_busy = false;
895 int ret; 894 int ret;
@@ -916,6 +915,15 @@ static void spi_pump_messages(struct kthread_work *work)
916 spin_unlock_irqrestore(&master->queue_lock, flags); 915 spin_unlock_irqrestore(&master->queue_lock, flags);
917 return; 916 return;
918 } 917 }
918
919 /* Only do teardown in the thread */
920 if (!in_kthread) {
921 queue_kthread_work(&master->kworker,
922 &master->pump_messages);
923 spin_unlock_irqrestore(&master->queue_lock, flags);
924 return;
925 }
926
919 master->busy = false; 927 master->busy = false;
920 master->idling = true; 928 master->idling = true;
921 spin_unlock_irqrestore(&master->queue_lock, flags); 929 spin_unlock_irqrestore(&master->queue_lock, flags);
@@ -1004,6 +1012,18 @@ static void spi_pump_messages(struct kthread_work *work)
1004 } 1012 }
1005} 1013}
1006 1014
1015/**
1016 * spi_pump_messages - kthread work function which processes spi message queue
1017 * @work: pointer to kthread work struct contained in the master struct
1018 */
1019static void spi_pump_messages(struct kthread_work *work)
1020{
1021 struct spi_master *master =
1022 container_of(work, struct spi_master, pump_messages);
1023
1024 __spi_pump_messages(master, true);
1025}
1026
1007static int spi_init_queue(struct spi_master *master) 1027static int spi_init_queue(struct spi_master *master)
1008{ 1028{
1009 struct sched_param param = { .sched_priority = MAX_RT_PRIO - 1 }; 1029 struct sched_param param = { .sched_priority = MAX_RT_PRIO - 1 };
@@ -2163,7 +2183,7 @@ static int __spi_sync(struct spi_device *spi, struct spi_message *message,
2163 * can. 2183 * can.
2164 */ 2184 */
2165 if (master->transfer == spi_queued_transfer) 2185 if (master->transfer == spi_queued_transfer)
2166 spi_pump_messages(&master->pump_messages); 2186 __spi_pump_messages(master, false);
2167 2187
2168 wait_for_completion(&done); 2188 wait_for_completion(&done);
2169 status = message->status; 2189 status = message->status;