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