brcm2708: switch to linux 4.4 and update patches
[openwrt.git] / target / linux / brcm2708 / patches-4.1 / 0155-spi-bcm2835-fallback-to-interrupt-for-polling-timeou.patch
1 From 4a42130b7fe39652a3ed8ced413a71c7f5d7ce61 Mon Sep 17 00:00:00 2001
2 From: Martin Sperl <kernel@martin.sperl.org>
3 Date: Wed, 22 Apr 2015 07:33:03 +0000
4 Subject: [PATCH 155/222] spi: bcm2835: fallback to interrupt for polling
5  timeouts exceeding 2 jiffies
6
7 The polling mode of the driver is designed for transfers that run
8 less than 30us - it will only execute under those circumstances.
9 So it should run comfortably without getting interrupted by the
10 scheduler.
11
12 But there are situations where the raspberry pi is so overloaded
13 that it can take up to 80 jiffies until the polling thread gets
14 rescheduled - this has been observed especially under heavy
15 IO situations.
16
17 In such a situation we now fall back to the interrupt handler and
18 log the situation at debug level.
19
20 Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
21 Signed-off-by: Mark Brown <broonie@kernel.org>
22 (cherry picked from commit a750b124cfd27bae1a12df22318db5a2083dfb12)
23 ---
24  drivers/spi/spi-bcm2835.c | 87 +++++++++++++++++++++++++++--------------------
25  1 file changed, 50 insertions(+), 37 deletions(-)
26
27 --- a/drivers/spi/spi-bcm2835.c
28 +++ b/drivers/spi/spi-bcm2835.c
29 @@ -69,7 +69,7 @@
30  #define BCM2835_SPI_CS_CS_01           0x00000001
31  
32  #define BCM2835_SPI_POLLING_LIMIT_US   30
33 -#define BCM2835_SPI_TIMEOUT_MS         30000
34 +#define BCM2835_SPI_POLLING_JIFFIES    2
35  #define BCM2835_SPI_MODE_BITS  (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH \
36                                 | SPI_NO_CS | SPI_3WIRE)
37  
38 @@ -157,42 +157,6 @@ static irqreturn_t bcm2835_spi_interrupt
39         return IRQ_HANDLED;
40  }
41  
42 -static int bcm2835_spi_transfer_one_poll(struct spi_master *master,
43 -                                        struct spi_device *spi,
44 -                                        struct spi_transfer *tfr,
45 -                                        u32 cs,
46 -                                        unsigned long xfer_time_us)
47 -{
48 -       struct bcm2835_spi *bs = spi_master_get_devdata(master);
49 -       /* set timeout to 1 second of maximum polling */
50 -       unsigned long timeout = jiffies + HZ;
51 -
52 -       /* enable HW block without interrupts */
53 -       bcm2835_wr(bs, BCM2835_SPI_CS, cs | BCM2835_SPI_CS_TA);
54 -
55 -       /* loop until finished the transfer */
56 -       while (bs->rx_len) {
57 -               /* read from fifo as much as possible */
58 -               bcm2835_rd_fifo(bs);
59 -               /* fill in tx fifo as much as possible */
60 -               bcm2835_wr_fifo(bs);
61 -               /* if we still expect some data after the read,
62 -                * check for a possible timeout
63 -                */
64 -               if (bs->rx_len && time_after(jiffies, timeout)) {
65 -                       /* Transfer complete - reset SPI HW */
66 -                       bcm2835_spi_reset_hw(master);
67 -                       /* and return timeout */
68 -                       return -ETIMEDOUT;
69 -               }
70 -       }
71 -
72 -       /* Transfer complete - reset SPI HW */
73 -       bcm2835_spi_reset_hw(master);
74 -       /* and return without waiting for completion */
75 -       return 0;
76 -}
77 -
78  static int bcm2835_spi_transfer_one_irq(struct spi_master *master,
79                                         struct spi_device *spi,
80                                         struct spi_transfer *tfr,
81 @@ -229,6 +193,55 @@ static int bcm2835_spi_transfer_one_irq(
82         return 1;
83  }
84  
85 +static int bcm2835_spi_transfer_one_poll(struct spi_master *master,
86 +                                        struct spi_device *spi,
87 +                                        struct spi_transfer *tfr,
88 +                                        u32 cs,
89 +                                        unsigned long xfer_time_us)
90 +{
91 +       struct bcm2835_spi *bs = spi_master_get_devdata(master);
92 +       unsigned long timeout;
93 +
94 +       /* enable HW block without interrupts */
95 +       bcm2835_wr(bs, BCM2835_SPI_CS, cs | BCM2835_SPI_CS_TA);
96 +
97 +       /* fill in the fifo before timeout calculations
98 +        * if we are interrupted here, then the data is
99 +        * getting transferred by the HW while we are interrupted
100 +        */
101 +       bcm2835_wr_fifo(bs);
102 +
103 +       /* set the timeout */
104 +       timeout = jiffies + BCM2835_SPI_POLLING_JIFFIES;
105 +
106 +       /* loop until finished the transfer */
107 +       while (bs->rx_len) {
108 +               /* fill in tx fifo with remaining data */
109 +               bcm2835_wr_fifo(bs);
110 +
111 +               /* read from fifo as much as possible */
112 +               bcm2835_rd_fifo(bs);
113 +
114 +               /* if there is still data pending to read
115 +                * then check the timeout
116 +                */
117 +               if (bs->rx_len && time_after(jiffies, timeout)) {
118 +                       dev_dbg_ratelimited(&spi->dev,
119 +                                           "timeout period reached: jiffies: %lu remaining tx/rx: %d/%d - falling back to interrupt mode\n",
120 +                                           jiffies - timeout,
121 +                                           bs->tx_len, bs->rx_len);
122 +                       /* fall back to interrupt mode */
123 +                       return bcm2835_spi_transfer_one_irq(master, spi,
124 +                                                           tfr, cs);
125 +               }
126 +       }
127 +
128 +       /* Transfer complete - reset SPI HW */
129 +       bcm2835_spi_reset_hw(master);
130 +       /* and return without waiting for completion */
131 +       return 0;
132 +}
133 +
134  static int bcm2835_spi_transfer_one(struct spi_master *master,
135                                     struct spi_device *spi,
136                                     struct spi_transfer *tfr)