092-03-spi-Only-idle-the-message-pump-in-the-worker-kthread.patch 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. From: Mark Brown <broonie@kernel.org>
  2. Date: Wed, 10 Dec 2014 13:46:33 +0000
  3. Subject: [PATCH] spi: Only idle the message pump in the worker kthread
  4. In order to avoid the situation where the kthread is waiting for another
  5. context to make the hardware idle let the message pump know if it's being
  6. called from the worker thread context and if it isn't then defer to the
  7. worker thread instead of idling the hardware immediately. This will ensure
  8. that if this situation happens we block rather than busy waiting.
  9. Signed-off-by: Mark Brown <broonie@kernel.org>
  10. ---
  11. --- a/drivers/spi/spi.c
  12. +++ b/drivers/spi/spi.c
  13. @@ -875,8 +875,9 @@ void spi_finalize_current_transfer(struc
  14. EXPORT_SYMBOL_GPL(spi_finalize_current_transfer);
  15. /**
  16. - * spi_pump_messages - kthread work function which processes spi message queue
  17. - * @work: pointer to kthread work struct contained in the master struct
  18. + * __spi_pump_messages - function which processes spi message queue
  19. + * @master: master to process queue for
  20. + * @in_kthread: true if we are in the context of the message pump thread
  21. *
  22. * This function checks if there is any spi message in the queue that
  23. * needs processing and if so call out to the driver to initialize hardware
  24. @@ -886,10 +887,8 @@ EXPORT_SYMBOL_GPL(spi_finalize_current_t
  25. * inside spi_sync(); the queue extraction handling at the top of the
  26. * function should deal with this safely.
  27. */
  28. -static void spi_pump_messages(struct kthread_work *work)
  29. +static void __spi_pump_messages(struct spi_master *master, bool in_kthread)
  30. {
  31. - struct spi_master *master =
  32. - container_of(work, struct spi_master, pump_messages);
  33. unsigned long flags;
  34. bool was_busy = false;
  35. int ret;
  36. @@ -916,6 +915,15 @@ static void spi_pump_messages(struct kth
  37. spin_unlock_irqrestore(&master->queue_lock, flags);
  38. return;
  39. }
  40. +
  41. + /* Only do teardown in the thread */
  42. + if (!in_kthread) {
  43. + queue_kthread_work(&master->kworker,
  44. + &master->pump_messages);
  45. + spin_unlock_irqrestore(&master->queue_lock, flags);
  46. + return;
  47. + }
  48. +
  49. master->busy = false;
  50. master->idling = true;
  51. spin_unlock_irqrestore(&master->queue_lock, flags);
  52. @@ -1004,6 +1012,18 @@ static void spi_pump_messages(struct kth
  53. }
  54. }
  55. +/**
  56. + * spi_pump_messages - kthread work function which processes spi message queue
  57. + * @work: pointer to kthread work struct contained in the master struct
  58. + */
  59. +static void spi_pump_messages(struct kthread_work *work)
  60. +{
  61. + struct spi_master *master =
  62. + container_of(work, struct spi_master, pump_messages);
  63. +
  64. + __spi_pump_messages(master, true);
  65. +}
  66. +
  67. static int spi_init_queue(struct spi_master *master)
  68. {
  69. struct sched_param param = { .sched_priority = MAX_RT_PRIO - 1 };
  70. @@ -2165,7 +2185,7 @@ static int __spi_sync(struct spi_device
  71. * can.
  72. */
  73. if (master->transfer == spi_queued_transfer)
  74. - spi_pump_messages(&master->pump_messages);
  75. + __spi_pump_messages(master, false);
  76. wait_for_completion(&done);
  77. status = message->status;