|
69 | 69 | #define BCM2835_SPI_CS_CS_01 0x00000001
|
70 | 70 |
|
71 | 71 | #define BCM2835_SPI_POLLING_LIMIT_US 30
|
72 |
| -#define BCM2835_SPI_TIMEOUT_MS 30000 |
| 72 | +#define BCM2835_SPI_POLLING_JIFFIES 2 |
73 | 73 | #define BCM2835_SPI_MODE_BITS (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH \
|
74 | 74 | | SPI_NO_CS | SPI_3WIRE)
|
75 | 75 |
|
@@ -157,42 +157,6 @@ static irqreturn_t bcm2835_spi_interrupt(int irq, void *dev_id)
|
157 | 157 | return IRQ_HANDLED;
|
158 | 158 | }
|
159 | 159 |
|
160 |
| -static int bcm2835_spi_transfer_one_poll(struct spi_master *master, |
161 |
| - struct spi_device *spi, |
162 |
| - struct spi_transfer *tfr, |
163 |
| - u32 cs, |
164 |
| - unsigned long xfer_time_us) |
165 |
| -{ |
166 |
| - struct bcm2835_spi *bs = spi_master_get_devdata(master); |
167 |
| - /* set timeout to 1 second of maximum polling */ |
168 |
| - unsigned long timeout = jiffies + HZ; |
169 |
| - |
170 |
| - /* enable HW block without interrupts */ |
171 |
| - bcm2835_wr(bs, BCM2835_SPI_CS, cs | BCM2835_SPI_CS_TA); |
172 |
| - |
173 |
| - /* loop until finished the transfer */ |
174 |
| - while (bs->rx_len) { |
175 |
| - /* read from fifo as much as possible */ |
176 |
| - bcm2835_rd_fifo(bs); |
177 |
| - /* fill in tx fifo as much as possible */ |
178 |
| - bcm2835_wr_fifo(bs); |
179 |
| - /* if we still expect some data after the read, |
180 |
| - * check for a possible timeout |
181 |
| - */ |
182 |
| - if (bs->rx_len && time_after(jiffies, timeout)) { |
183 |
| - /* Transfer complete - reset SPI HW */ |
184 |
| - bcm2835_spi_reset_hw(master); |
185 |
| - /* and return timeout */ |
186 |
| - return -ETIMEDOUT; |
187 |
| - } |
188 |
| - } |
189 |
| - |
190 |
| - /* Transfer complete - reset SPI HW */ |
191 |
| - bcm2835_spi_reset_hw(master); |
192 |
| - /* and return without waiting for completion */ |
193 |
| - return 0; |
194 |
| -} |
195 |
| - |
196 | 160 | static int bcm2835_spi_transfer_one_irq(struct spi_master *master,
|
197 | 161 | struct spi_device *spi,
|
198 | 162 | struct spi_transfer *tfr,
|
@@ -229,6 +193,55 @@ static int bcm2835_spi_transfer_one_irq(struct spi_master *master,
|
229 | 193 | return 1;
|
230 | 194 | }
|
231 | 195 |
|
| 196 | +static int bcm2835_spi_transfer_one_poll(struct spi_master *master, |
| 197 | + struct spi_device *spi, |
| 198 | + struct spi_transfer *tfr, |
| 199 | + u32 cs, |
| 200 | + unsigned long xfer_time_us) |
| 201 | +{ |
| 202 | + struct bcm2835_spi *bs = spi_master_get_devdata(master); |
| 203 | + unsigned long timeout; |
| 204 | + |
| 205 | + /* enable HW block without interrupts */ |
| 206 | + bcm2835_wr(bs, BCM2835_SPI_CS, cs | BCM2835_SPI_CS_TA); |
| 207 | + |
| 208 | + /* fill in the fifo before timeout calculations |
| 209 | + * if we are interrupted here, then the data is |
| 210 | + * getting transferred by the HW while we are interrupted |
| 211 | + */ |
| 212 | + bcm2835_wr_fifo(bs); |
| 213 | + |
| 214 | + /* set the timeout */ |
| 215 | + timeout = jiffies + BCM2835_SPI_POLLING_JIFFIES; |
| 216 | + |
| 217 | + /* loop until finished the transfer */ |
| 218 | + while (bs->rx_len) { |
| 219 | + /* fill in tx fifo with remaining data */ |
| 220 | + bcm2835_wr_fifo(bs); |
| 221 | + |
| 222 | + /* read from fifo as much as possible */ |
| 223 | + bcm2835_rd_fifo(bs); |
| 224 | + |
| 225 | + /* if there is still data pending to read |
| 226 | + * then check the timeout |
| 227 | + */ |
| 228 | + if (bs->rx_len && time_after(jiffies, timeout)) { |
| 229 | + dev_dbg_ratelimited(&spi->dev, |
| 230 | + "timeout period reached: jiffies: %lu remaining tx/rx: %d/%d - falling back to interrupt mode\n", |
| 231 | + jiffies - timeout, |
| 232 | + bs->tx_len, bs->rx_len); |
| 233 | + /* fall back to interrupt mode */ |
| 234 | + return bcm2835_spi_transfer_one_irq(master, spi, |
| 235 | + tfr, cs); |
| 236 | + } |
| 237 | + } |
| 238 | + |
| 239 | + /* Transfer complete - reset SPI HW */ |
| 240 | + bcm2835_spi_reset_hw(master); |
| 241 | + /* and return without waiting for completion */ |
| 242 | + return 0; |
| 243 | +} |
| 244 | + |
232 | 245 | static int bcm2835_spi_transfer_one(struct spi_master *master,
|
233 | 246 | struct spi_device *spi,
|
234 | 247 | struct spi_transfer *tfr)
|
|
0 commit comments