Merge remote-tracking branch 'spi/topic/pump-rt' into spi-next
[sfrench/cifs-2.6.git] / drivers / spi / spi.c
index 81e4d9f7c0f49a60a63ec519145c512e0de4fba8..91673351bcf396bc69a8026a5ed6496bd2422d7f 100644 (file)
@@ -1417,10 +1417,32 @@ static void spi_pump_messages(struct kthread_work *work)
        __spi_pump_messages(ctlr, true);
 }
 
-static int spi_init_queue(struct spi_controller *ctlr)
+/**
+ * spi_set_thread_rt - set the controller to pump at realtime priority
+ * @ctlr: controller to boost priority of
+ *
+ * This can be called because the controller requested realtime priority
+ * (by setting the ->rt value before calling spi_register_controller()) or
+ * because a device on the bus said that its transfers needed realtime
+ * priority.
+ *
+ * NOTE: at the moment if any device on a bus says it needs realtime then
+ * the thread will be at realtime priority for all transfers on that
+ * controller.  If this eventually becomes a problem we may see if we can
+ * find a way to boost the priority only temporarily during relevant
+ * transfers.
+ */
+static void spi_set_thread_rt(struct spi_controller *ctlr)
 {
        struct sched_param param = { .sched_priority = MAX_RT_PRIO - 1 };
 
+       dev_info(&ctlr->dev,
+               "will run message pump with realtime priority\n");
+       sched_setscheduler(ctlr->kworker_task, SCHED_FIFO, &param);
+}
+
+static int spi_init_queue(struct spi_controller *ctlr)
+{
        ctlr->running = false;
        ctlr->busy = false;
 
@@ -1440,11 +1462,8 @@ static int spi_init_queue(struct spi_controller *ctlr)
         * request and the scheduling of the message pump thread. Without this
         * setting the message pump thread will remain at default priority.
         */
-       if (ctlr->rt) {
-               dev_info(&ctlr->dev,
-                       "will run message pump with realtime priority\n");
-               sched_setscheduler(ctlr->kworker_task, SCHED_FIFO, &param);
-       }
+       if (ctlr->rt)
+               spi_set_thread_rt(ctlr);
 
        return 0;
 }
@@ -3071,6 +3090,11 @@ int spi_setup(struct spi_device *spi)
 
        spi_set_cs(spi, false);
 
+       if (spi->rt && !spi->controller->rt) {
+               spi->controller->rt = true;
+               spi_set_thread_rt(spi->controller);
+       }
+
        dev_dbg(&spi->dev, "setup mode %d, %s%s%s%s%u bits/w, %u Hz max --> %d\n",
                        (int) (spi->mode & (SPI_CPOL | SPI_CPHA)),
                        (spi->mode & SPI_CS_HIGH) ? "cs_high, " : "",