diff options
author | Mark Brown <broonie@linaro.org> | 2013-07-10 10:40:19 -0400 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2013-07-15 06:39:30 -0400 |
commit | e8153ab3d7ab33aad872fd36f91a22a1071ceabf (patch) | |
tree | 9ba05f05d2917487067647ce3c77bf08ccb34ea3 /drivers/spi/spi-omap-100k.c | |
parent | 69ea672a13a9b702ea3dc84de0cd9e1f4a088217 (diff) |
spi/omap-100k: Factor message transfer function out of work queue
In preparation for removing the custom workqueue.
Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'drivers/spi/spi-omap-100k.c')
-rw-r--r-- | drivers/spi/spi-omap-100k.c | 133 |
1 files changed, 68 insertions, 65 deletions
diff --git a/drivers/spi/spi-omap-100k.c b/drivers/spi/spi-omap-100k.c index 3b42a4ba8fa2..5999285f4cbd 100644 --- a/drivers/spi/spi-omap-100k.c +++ b/drivers/spi/spi-omap-100k.c | |||
@@ -321,10 +321,76 @@ static int omap1_spi100k_setup(struct spi_device *spi) | |||
321 | return ret; | 321 | return ret; |
322 | } | 322 | } |
323 | 323 | ||
324 | static int omap1_spi100k_transfer_one_message(struct spi_master *master, | ||
325 | struct spi_message *m) | ||
326 | { | ||
327 | struct omap1_spi100k *spi100k = spi_master_get_devdata(master); | ||
328 | struct spi_device *spi = m->spi; | ||
329 | struct spi_transfer *t = NULL; | ||
330 | int cs_active = 0; | ||
331 | int par_override = 0; | ||
332 | int status = 0; | ||
333 | |||
334 | list_for_each_entry(t, &m->transfers, transfer_list) { | ||
335 | if (t->tx_buf == NULL && t->rx_buf == NULL && t->len) { | ||
336 | status = -EINVAL; | ||
337 | break; | ||
338 | } | ||
339 | if (par_override || t->speed_hz || t->bits_per_word) { | ||
340 | par_override = 1; | ||
341 | status = omap1_spi100k_setup_transfer(spi, t); | ||
342 | if (status < 0) | ||
343 | break; | ||
344 | if (!t->speed_hz && !t->bits_per_word) | ||
345 | par_override = 0; | ||
346 | } | ||
347 | |||
348 | if (!cs_active) { | ||
349 | omap1_spi100k_force_cs(spi100k, 1); | ||
350 | cs_active = 1; | ||
351 | } | ||
352 | |||
353 | if (t->len) { | ||
354 | unsigned count; | ||
355 | |||
356 | count = omap1_spi100k_txrx_pio(spi, t); | ||
357 | m->actual_length += count; | ||
358 | |||
359 | if (count != t->len) { | ||
360 | status = -EIO; | ||
361 | break; | ||
362 | } | ||
363 | } | ||
364 | |||
365 | if (t->delay_usecs) | ||
366 | udelay(t->delay_usecs); | ||
367 | |||
368 | /* ignore the "leave it on after last xfer" hint */ | ||
369 | |||
370 | if (t->cs_change) { | ||
371 | omap1_spi100k_force_cs(spi100k, 0); | ||
372 | cs_active = 0; | ||
373 | } | ||
374 | } | ||
375 | |||
376 | /* Restore defaults if they were overriden */ | ||
377 | if (par_override) { | ||
378 | par_override = 0; | ||
379 | status = omap1_spi100k_setup_transfer(spi, NULL); | ||
380 | } | ||
381 | |||
382 | if (cs_active) | ||
383 | omap1_spi100k_force_cs(spi100k, 0); | ||
384 | |||
385 | m->status = status; | ||
386 | m->complete(m->context); | ||
387 | |||
388 | return status; | ||
389 | } | ||
390 | |||
324 | static void omap1_spi100k_work(struct work_struct *work) | 391 | static void omap1_spi100k_work(struct work_struct *work) |
325 | { | 392 | { |
326 | struct omap1_spi100k *spi100k; | 393 | struct omap1_spi100k *spi100k; |
327 | int status = 0; | ||
328 | 394 | ||
329 | spi100k = container_of(work, struct omap1_spi100k, work); | 395 | spi100k = container_of(work, struct omap1_spi100k, work); |
330 | spin_lock_irq(&spi100k->lock); | 396 | spin_lock_irq(&spi100k->lock); |
@@ -340,11 +406,6 @@ static void omap1_spi100k_work(struct work_struct *work) | |||
340 | */ | 406 | */ |
341 | while (!list_empty(&spi100k->msg_queue)) { | 407 | while (!list_empty(&spi100k->msg_queue)) { |
342 | struct spi_message *m; | 408 | struct spi_message *m; |
343 | struct spi_device *spi; | ||
344 | struct spi_transfer *t = NULL; | ||
345 | int cs_active = 0; | ||
346 | struct omap1_spi100k_cs *cs; | ||
347 | int par_override = 0; | ||
348 | 409 | ||
349 | m = container_of(spi100k->msg_queue.next, struct spi_message, | 410 | m = container_of(spi100k->msg_queue.next, struct spi_message, |
350 | queue); | 411 | queue); |
@@ -352,62 +413,7 @@ static void omap1_spi100k_work(struct work_struct *work) | |||
352 | list_del_init(&m->queue); | 413 | list_del_init(&m->queue); |
353 | spin_unlock_irq(&spi100k->lock); | 414 | spin_unlock_irq(&spi100k->lock); |
354 | 415 | ||
355 | spi = m->spi; | 416 | omap1_spi100k_transfer_one_message(m->spi->master, m); |
356 | cs = spi->controller_state; | ||
357 | |||
358 | list_for_each_entry(t, &m->transfers, transfer_list) { | ||
359 | if (t->tx_buf == NULL && t->rx_buf == NULL && t->len) { | ||
360 | status = -EINVAL; | ||
361 | break; | ||
362 | } | ||
363 | if (par_override || t->speed_hz || t->bits_per_word) { | ||
364 | par_override = 1; | ||
365 | status = omap1_spi100k_setup_transfer(spi, t); | ||
366 | if (status < 0) | ||
367 | break; | ||
368 | if (!t->speed_hz && !t->bits_per_word) | ||
369 | par_override = 0; | ||
370 | } | ||
371 | |||
372 | if (!cs_active) { | ||
373 | omap1_spi100k_force_cs(spi100k, 1); | ||
374 | cs_active = 1; | ||
375 | } | ||
376 | |||
377 | if (t->len) { | ||
378 | unsigned count; | ||
379 | |||
380 | count = omap1_spi100k_txrx_pio(spi, t); | ||
381 | m->actual_length += count; | ||
382 | |||
383 | if (count != t->len) { | ||
384 | status = -EIO; | ||
385 | break; | ||
386 | } | ||
387 | } | ||
388 | |||
389 | if (t->delay_usecs) | ||
390 | udelay(t->delay_usecs); | ||
391 | |||
392 | /* ignore the "leave it on after last xfer" hint */ | ||
393 | |||
394 | if (t->cs_change) { | ||
395 | omap1_spi100k_force_cs(spi100k, 0); | ||
396 | cs_active = 0; | ||
397 | } | ||
398 | } | ||
399 | |||
400 | /* Restore defaults if they were overriden */ | ||
401 | if (par_override) { | ||
402 | par_override = 0; | ||
403 | status = omap1_spi100k_setup_transfer(spi, NULL); | ||
404 | } | ||
405 | |||
406 | if (cs_active) | ||
407 | omap1_spi100k_force_cs(spi100k, 0); | ||
408 | |||
409 | m->status = status; | ||
410 | m->complete(m->context); | ||
411 | 417 | ||
412 | spin_lock_irq(&spi100k->lock); | 418 | spin_lock_irq(&spi100k->lock); |
413 | } | 419 | } |
@@ -415,9 +421,6 @@ static void omap1_spi100k_work(struct work_struct *work) | |||
415 | clk_disable(spi100k->ick); | 421 | clk_disable(spi100k->ick); |
416 | clk_disable(spi100k->fck); | 422 | clk_disable(spi100k->fck); |
417 | spin_unlock_irq(&spi100k->lock); | 423 | spin_unlock_irq(&spi100k->lock); |
418 | |||
419 | if (status < 0) | ||
420 | printk(KERN_WARNING "spi transfer failed with %d\n", status); | ||
421 | } | 424 | } |
422 | 425 | ||
423 | static int omap1_spi100k_transfer(struct spi_device *spi, struct spi_message *m) | 426 | static int omap1_spi100k_transfer(struct spi_device *spi, struct spi_message *m) |