Merge remote-tracking branch 'spi/topic/pump-rt' into spi-next
authorMark Brown <broonie@kernel.org>
Thu, 4 Jul 2019 16:35:11 +0000 (17:35 +0100)
committerMark Brown <broonie@kernel.org>
Thu, 4 Jul 2019 16:35:11 +0000 (17:35 +0100)
drivers/spi/spi.c
include/linux/spi/spi.h

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, " : "",
index 0ec11f2911af1323ab778aabb19d0311a641a784..af4f265d0f67e021a6b38fde7ed10c609b94c1a7 100644 (file)
@@ -109,6 +109,7 @@ void spi_statistics_add_transfer_stats(struct spi_statistics *stats,
  *     This may be changed by the device's driver, or left at the
  *     default (0) indicating protocol words are eight bit bytes.
  *     The spi_transfer.bits_per_word can override this for each transfer.
+ * @rt: Make the pump thread real time priority.
  * @irq: Negative, or the number passed to request_irq() to receive
  *     interrupts from this device.
  * @controller_state: Controller's runtime state
@@ -143,6 +144,7 @@ struct spi_device {
        u32                     max_speed_hz;
        u8                      chip_select;
        u8                      bits_per_word;
+       bool                    rt;
        u32                     mode;
 #define        SPI_CPHA        0x01                    /* clock phase */
 #define        SPI_CPOL        0x02                    /* clock polarity */