The patch spi: Allow SPI devices to request the pumping thread be realtime has been applied to the spi tree at https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-5.3 All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted. You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed. If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced. Please add any relevant lists and maintainers to the CCs when replying to this mail. Thanks, Mark >From 924b5867e7bd6a6a98014f0517b747465b108011 Mon Sep 17 00:00:00 2001 From: Douglas Anderson <dianders@xxxxxxxxxxxx> Date: Wed, 15 May 2019 09:48:12 -0700 Subject: [PATCH] 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@xxxxxxxxxxxx> Reviewed-by: Guenter Roeck <groeck@xxxxxxxxxxxx> Tested-by: Enric Balletbo i Serra <enric.balletbo@xxxxxxxxxxxxx> Signed-off-by: Mark Brown <broonie@xxxxxxxxxx> --- drivers/spi/spi.c | 36 ++++++++++++++++++++++++++++++------ include/linux/spi/spi.h | 2 ++ 2 files changed, 32 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, " : "", diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index 053abd22ad31..15505c2485d6 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -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 */ -- 2.20.1