diff options
author | Douglas Anderson <dianders@chromium.org> | 2019-05-15 09:48:12 -0700 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2019-05-23 14:44:02 +0100 |
commit | 924b5867e7bd6a6a98014f0517b747465b108011 (patch) | |
tree | 5c66c777dc99113fc4340627ae897a855b5961fc /drivers/spi | |
parent | a188339ca5a396acc588e5851ed7e19f66b0ebd9 (diff) | |
download | linux-924b5867e7bd6a6a98014f0517b747465b108011.tar.gz linux-924b5867e7bd6a6a98014f0517b747465b108011.tar.bz2 linux-924b5867e7bd6a6a98014f0517b747465b108011.zip |
spi: Allow SPI devices to request the pumping thread be realtime
Right now the only way to get the SPI pumping thread bumped up to
realtime priority is for the controller to request it. However it may
be that the controller works fine with the normal priority but
communication to a particular SPI device on the bus needs realtime
priority.
Let's add a way for devices to request realtime priority when they set
themselves up.
NOTE: this will just affect the priority of transfers that end up on
the SPI core's pumping thread. In many cases transfers happen in the
context of the caller so if you need realtime priority for all
transfers you should ensure the calling context is also realtime
priority.
Signed-off-by: Douglas Anderson <dianders@chromium.org>
Reviewed-by: Guenter Roeck <groeck@chromium.org>
Tested-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'drivers/spi')
-rw-r--r-- | drivers/spi/spi.c | 36 |
1 files changed, 30 insertions, 6 deletions
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 5e75944ad5d1..18f70e4bbb31 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -1364,10 +1364,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, ¶m); +} + +static int spi_init_queue(struct spi_controller *ctlr) +{ ctlr->running = false; ctlr->busy = false; @@ -1387,11 +1409,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, ¶m); - } + if (ctlr->rt) + spi_set_thread_rt(ctlr); return 0; } @@ -2982,6 +3001,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, " : "", |