aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMark Brown <broonie@linaro.org>2013-10-05 06:50:40 -0400
committerMark Brown <broonie@linaro.org>2013-10-11 15:09:50 -0400
commitb158935f70b9c156903338053216dd0adf7ce31c (patch)
tree8fc35f89210cf56eb647c64f92a814c2ede84505 /drivers
parent6bb9c0e34185717f5b0df4ad468476f64f0d73fb (diff)
spi: Provide common spi_message processing loop
The loops which SPI controller drivers use to process the list of transfers in a spi_message are typically very similar and have some error prone areas such as the handling of /CS. Help simplify drivers by factoring this code out into the core - if drivers provide a transfer_one() function instead of a transfer_one_message() function the core will handle processing at the message level. /CS can be controlled by either setting cs_gpio or providing a set_cs function. If this is not possible for hardware reasons then both can be omitted and the driver should continue to implement manual /CS handling. This is a first step in refactoring and it is expected that there will be further enhancements, for example factoring out of the mapping of transfers for DMA and the initiation and completion of interrupt driven transfers. Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/spi/spi.c92
1 files changed, 92 insertions, 0 deletions
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 8a30c6b66a64..85c18d8a86b3 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -526,6 +526,95 @@ int spi_register_board_info(struct spi_board_info const *info, unsigned n)
526 526
527/*-------------------------------------------------------------------------*/ 527/*-------------------------------------------------------------------------*/
528 528
529static void spi_set_cs(struct spi_device *spi, bool enable)
530{
531 if (spi->mode & SPI_CS_HIGH)
532 enable = !enable;
533
534 if (spi->cs_gpio >= 0)
535 gpio_set_value(spi->cs_gpio, !enable);
536 else if (spi->master->set_cs)
537 spi->master->set_cs(spi, !enable);
538}
539
540/*
541 * spi_transfer_one_message - Default implementation of transfer_one_message()
542 *
543 * This is a standard implementation of transfer_one_message() for
544 * drivers which impelment a transfer_one() operation. It provides
545 * standard handling of delays and chip select management.
546 */
547static int spi_transfer_one_message(struct spi_master *master,
548 struct spi_message *msg)
549{
550 struct spi_transfer *xfer;
551 bool cur_cs = true;
552 bool keep_cs = false;
553 int ret = 0;
554
555 spi_set_cs(msg->spi, true);
556
557 list_for_each_entry(xfer, &msg->transfers, transfer_list) {
558 trace_spi_transfer_start(msg, xfer);
559
560 INIT_COMPLETION(master->xfer_completion);
561
562 ret = master->transfer_one(master, msg->spi, xfer);
563 if (ret < 0) {
564 dev_err(&msg->spi->dev,
565 "SPI transfer failed: %d\n", ret);
566 goto out;
567 }
568
569 if (ret > 0)
570 wait_for_completion(&master->xfer_completion);
571
572 trace_spi_transfer_stop(msg, xfer);
573
574 if (msg->status != -EINPROGRESS)
575 goto out;
576
577 if (xfer->delay_usecs)
578 udelay(xfer->delay_usecs);
579
580 if (xfer->cs_change) {
581 if (list_is_last(&xfer->transfer_list,
582 &msg->transfers)) {
583 keep_cs = true;
584 } else {
585 cur_cs = !cur_cs;
586 spi_set_cs(msg->spi, cur_cs);
587 }
588 }
589
590 msg->actual_length += xfer->len;
591 }
592
593out:
594 if (ret != 0 || !keep_cs)
595 spi_set_cs(msg->spi, false);
596
597 if (msg->status == -EINPROGRESS)
598 msg->status = ret;
599
600 spi_finalize_current_message(master);
601
602 return ret;
603}
604
605/**
606 * spi_finalize_current_transfer - report completion of a transfer
607 *
608 * Called by SPI drivers using the core transfer_one_message()
609 * implementation to notify it that the current interrupt driven
610 * transfer has finised and the next one may be scheduled.
611 */
612void spi_finalize_current_transfer(struct spi_master *master)
613{
614 complete(&master->xfer_completion);
615}
616EXPORT_SYMBOL_GPL(spi_finalize_current_transfer);
617
529/** 618/**
530 * spi_pump_messages - kthread work function which processes spi message queue 619 * spi_pump_messages - kthread work function which processes spi message queue
531 * @work: pointer to kthread work struct contained in the master struct 620 * @work: pointer to kthread work struct contained in the master struct
@@ -836,6 +925,8 @@ static int spi_master_initialize_queue(struct spi_master *master)
836 925
837 master->queued = true; 926 master->queued = true;
838 master->transfer = spi_queued_transfer; 927 master->transfer = spi_queued_transfer;
928 if (!master->transfer_one_message)
929 master->transfer_one_message = spi_transfer_one_message;
839 930
840 /* Initialize and start queue */ 931 /* Initialize and start queue */
841 ret = spi_init_queue(master); 932 ret = spi_init_queue(master);
@@ -1242,6 +1333,7 @@ int spi_register_master(struct spi_master *master)
1242 spin_lock_init(&master->bus_lock_spinlock); 1333 spin_lock_init(&master->bus_lock_spinlock);
1243 mutex_init(&master->bus_lock_mutex); 1334 mutex_init(&master->bus_lock_mutex);
1244 master->bus_lock_flag = 0; 1335 master->bus_lock_flag = 0;
1336 init_completion(&master->xfer_completion);
1245 1337
1246 /* register the device, then userspace will see it. 1338 /* register the device, then userspace will see it.
1247 * registration fails if the bus ID is in use. 1339 * registration fails if the bus ID is in use.