diff options
author | Mark Brown <broonie@linaro.org> | 2013-07-05 07:06:44 -0400 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2013-07-15 06:29:53 -0400 |
commit | 91b308586793b48c590c9ac3528bbacb8ef53e15 (patch) | |
tree | e42c0f4510cea05fb7e262fe7d9caaab5811c0ed | |
parent | 874b31585650afa6745de5133849365e7e6af418 (diff) |
spi/bitbang: Factor out message transfer from message pump loop
In order to make it easier to convert to transfer_one_message() lift the
code that does the actual message transfer out of the work function that
implements the message pump. This should have no functional impact, it's
just a simple code motion patch.
Signed-off-by: Mark Brown <broonie@linaro.org>
-rw-r--r-- | drivers/spi/spi-bitbang.c | 199 |
1 files changed, 104 insertions, 95 deletions
diff --git a/drivers/spi/spi-bitbang.c b/drivers/spi/spi-bitbang.c index 495ce0a51d2f..8b8487c9694e 100644 --- a/drivers/spi/spi-bitbang.c +++ b/drivers/spi/spi-bitbang.c | |||
@@ -255,117 +255,126 @@ static int spi_bitbang_bufs(struct spi_device *spi, struct spi_transfer *t) | |||
255 | * Drivers can provide word-at-a-time i/o primitives, or provide | 255 | * Drivers can provide word-at-a-time i/o primitives, or provide |
256 | * transfer-at-a-time ones to leverage dma or fifo hardware. | 256 | * transfer-at-a-time ones to leverage dma or fifo hardware. |
257 | */ | 257 | */ |
258 | static void bitbang_work(struct work_struct *work) | 258 | static int spi_bitbang_transfer_one(struct spi_device *spi, |
259 | struct spi_message *m) | ||
259 | { | 260 | { |
260 | struct spi_bitbang *bitbang = | 261 | struct spi_bitbang *bitbang; |
261 | container_of(work, struct spi_bitbang, work); | 262 | unsigned nsecs; |
262 | unsigned long flags; | 263 | struct spi_transfer *t = NULL; |
263 | struct spi_message *m, *_m; | 264 | unsigned tmp; |
265 | unsigned cs_change; | ||
266 | int status; | ||
267 | int do_setup = -1; | ||
264 | 268 | ||
265 | spin_lock_irqsave(&bitbang->lock, flags); | 269 | bitbang = spi_master_get_devdata(spi->master); |
266 | bitbang->busy = 1; | ||
267 | list_for_each_entry_safe(m, _m, &bitbang->queue, queue) { | ||
268 | struct spi_device *spi; | ||
269 | unsigned nsecs; | ||
270 | struct spi_transfer *t = NULL; | ||
271 | unsigned tmp; | ||
272 | unsigned cs_change; | ||
273 | int status; | ||
274 | int do_setup = -1; | ||
275 | 270 | ||
276 | list_del(&m->queue); | 271 | /* FIXME this is made-up ... the correct value is known to |
277 | spin_unlock_irqrestore(&bitbang->lock, flags); | 272 | * word-at-a-time bitbang code, and presumably chipselect() |
273 | * should enforce these requirements too? | ||
274 | */ | ||
275 | nsecs = 100; | ||
278 | 276 | ||
279 | /* FIXME this is made-up ... the correct value is known to | 277 | tmp = 0; |
280 | * word-at-a-time bitbang code, and presumably chipselect() | 278 | cs_change = 1; |
281 | * should enforce these requirements too? | 279 | status = 0; |
282 | */ | ||
283 | nsecs = 100; | ||
284 | 280 | ||
285 | spi = m->spi; | 281 | list_for_each_entry (t, &m->transfers, transfer_list) { |
286 | tmp = 0; | ||
287 | cs_change = 1; | ||
288 | status = 0; | ||
289 | 282 | ||
290 | list_for_each_entry (t, &m->transfers, transfer_list) { | 283 | /* override speed or wordsize? */ |
291 | 284 | if (t->speed_hz || t->bits_per_word) | |
292 | /* override speed or wordsize? */ | 285 | do_setup = 1; |
293 | if (t->speed_hz || t->bits_per_word) | ||
294 | do_setup = 1; | ||
295 | |||
296 | /* init (-1) or override (1) transfer params */ | ||
297 | if (do_setup != 0) { | ||
298 | status = bitbang->setup_transfer(spi, t); | ||
299 | if (status < 0) | ||
300 | break; | ||
301 | if (do_setup == -1) | ||
302 | do_setup = 0; | ||
303 | } | ||
304 | |||
305 | /* set up default clock polarity, and activate chip; | ||
306 | * this implicitly updates clock and spi modes as | ||
307 | * previously recorded for this device via setup(). | ||
308 | * (and also deselects any other chip that might be | ||
309 | * selected ...) | ||
310 | */ | ||
311 | if (cs_change) { | ||
312 | bitbang->chipselect(spi, BITBANG_CS_ACTIVE); | ||
313 | ndelay(nsecs); | ||
314 | } | ||
315 | cs_change = t->cs_change; | ||
316 | if (!t->tx_buf && !t->rx_buf && t->len) { | ||
317 | status = -EINVAL; | ||
318 | break; | ||
319 | } | ||
320 | 286 | ||
321 | /* transfer data. the lower level code handles any | 287 | /* init (-1) or override (1) transfer params */ |
322 | * new dma mappings it needs. our caller always gave | 288 | if (do_setup != 0) { |
323 | * us dma-safe buffers. | 289 | status = bitbang->setup_transfer(spi, t); |
324 | */ | 290 | if (status < 0) |
325 | if (t->len) { | ||
326 | /* REVISIT dma API still needs a designated | ||
327 | * DMA_ADDR_INVALID; ~0 might be better. | ||
328 | */ | ||
329 | if (!m->is_dma_mapped) | ||
330 | t->rx_dma = t->tx_dma = 0; | ||
331 | status = bitbang->txrx_bufs(spi, t); | ||
332 | } | ||
333 | if (status > 0) | ||
334 | m->actual_length += status; | ||
335 | if (status != t->len) { | ||
336 | /* always report some kind of error */ | ||
337 | if (status >= 0) | ||
338 | status = -EREMOTEIO; | ||
339 | break; | 291 | break; |
340 | } | 292 | if (do_setup == -1) |
341 | status = 0; | 293 | do_setup = 0; |
342 | |||
343 | /* protocol tweaks before next transfer */ | ||
344 | if (t->delay_usecs) | ||
345 | udelay(t->delay_usecs); | ||
346 | |||
347 | if (cs_change && !list_is_last(&t->transfer_list, &m->transfers)) { | ||
348 | /* sometimes a short mid-message deselect of the chip | ||
349 | * may be needed to terminate a mode or command | ||
350 | */ | ||
351 | ndelay(nsecs); | ||
352 | bitbang->chipselect(spi, BITBANG_CS_INACTIVE); | ||
353 | ndelay(nsecs); | ||
354 | } | ||
355 | } | 294 | } |
356 | 295 | ||
357 | m->status = status; | 296 | /* set up default clock polarity, and activate chip; |
358 | m->complete(m->context); | 297 | * this implicitly updates clock and spi modes as |
298 | * previously recorded for this device via setup(). | ||
299 | * (and also deselects any other chip that might be | ||
300 | * selected ...) | ||
301 | */ | ||
302 | if (cs_change) { | ||
303 | bitbang->chipselect(spi, BITBANG_CS_ACTIVE); | ||
304 | ndelay(nsecs); | ||
305 | } | ||
306 | cs_change = t->cs_change; | ||
307 | if (!t->tx_buf && !t->rx_buf && t->len) { | ||
308 | status = -EINVAL; | ||
309 | break; | ||
310 | } | ||
359 | 311 | ||
360 | /* normally deactivate chipselect ... unless no error and | 312 | /* transfer data. the lower level code handles any |
361 | * cs_change has hinted that the next message will probably | 313 | * new dma mappings it needs. our caller always gave |
362 | * be for this chip too. | 314 | * us dma-safe buffers. |
363 | */ | 315 | */ |
364 | if (!(status == 0 && cs_change)) { | 316 | if (t->len) { |
317 | /* REVISIT dma API still needs a designated | ||
318 | * DMA_ADDR_INVALID; ~0 might be better. | ||
319 | */ | ||
320 | if (!m->is_dma_mapped) | ||
321 | t->rx_dma = t->tx_dma = 0; | ||
322 | status = bitbang->txrx_bufs(spi, t); | ||
323 | } | ||
324 | if (status > 0) | ||
325 | m->actual_length += status; | ||
326 | if (status != t->len) { | ||
327 | /* always report some kind of error */ | ||
328 | if (status >= 0) | ||
329 | status = -EREMOTEIO; | ||
330 | break; | ||
331 | } | ||
332 | status = 0; | ||
333 | |||
334 | /* protocol tweaks before next transfer */ | ||
335 | if (t->delay_usecs) | ||
336 | udelay(t->delay_usecs); | ||
337 | |||
338 | if (cs_change && !list_is_last(&t->transfer_list, &m->transfers)) { | ||
339 | /* sometimes a short mid-message deselect of the chip | ||
340 | * may be needed to terminate a mode or command | ||
341 | */ | ||
365 | ndelay(nsecs); | 342 | ndelay(nsecs); |
366 | bitbang->chipselect(spi, BITBANG_CS_INACTIVE); | 343 | bitbang->chipselect(spi, BITBANG_CS_INACTIVE); |
367 | ndelay(nsecs); | 344 | ndelay(nsecs); |
368 | } | 345 | } |
346 | } | ||
347 | |||
348 | m->status = status; | ||
349 | m->complete(m->context); | ||
350 | |||
351 | /* normally deactivate chipselect ... unless no error and | ||
352 | * cs_change has hinted that the next message will probably | ||
353 | * be for this chip too. | ||
354 | */ | ||
355 | if (!(status == 0 && cs_change)) { | ||
356 | ndelay(nsecs); | ||
357 | bitbang->chipselect(spi, BITBANG_CS_INACTIVE); | ||
358 | ndelay(nsecs); | ||
359 | } | ||
360 | |||
361 | return status; | ||
362 | } | ||
363 | |||
364 | static void bitbang_work(struct work_struct *work) | ||
365 | { | ||
366 | struct spi_bitbang *bitbang = | ||
367 | container_of(work, struct spi_bitbang, work); | ||
368 | unsigned long flags; | ||
369 | struct spi_message *m, *_m; | ||
370 | |||
371 | spin_lock_irqsave(&bitbang->lock, flags); | ||
372 | bitbang->busy = 1; | ||
373 | list_for_each_entry_safe(m, _m, &bitbang->queue, queue) { | ||
374 | list_del(&m->queue); | ||
375 | spin_unlock_irqrestore(&bitbang->lock, flags); | ||
376 | |||
377 | spi_bitbang_transfer_one(m->spi, m); | ||
369 | 378 | ||
370 | spin_lock_irqsave(&bitbang->lock, flags); | 379 | spin_lock_irqsave(&bitbang->lock, flags); |
371 | } | 380 | } |