diff options
author | Geert Uytterhoeven <geert@linux-m68k.org> | 2014-05-02 00:29:34 -0400 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2014-05-02 13:08:40 -0400 |
commit | 2de440f59ca9615c92820d165d5e59756e54026b (patch) | |
tree | 6f0129e27bda85886806416b473386584fa87696 | |
parent | 83596fbeb5d28e8cb8878786133945d4dc7c0090 (diff) |
spi: core: Protect DMA code by #ifdef CONFIG_HAS_DMA
If NO_DMA=y:
drivers/built-in.o: In function `spi_map_buf':
spi.c:(.text+0x21bc60): undefined reference to `dma_map_sg'
drivers/built-in.o: In function `spi_unmap_buf.isra.33':
spi.c:(.text+0x21c32e): undefined reference to `dma_unmap_sg'
make[3]: *** [vmlinux] Error 1
Protect the DMA code by #ifdef CONFIG_HAS_DMA to fix this:
- Extract __spi_map_msg() from spi_map_msg(),
- Provide dummy definitions of __spi_map_msg() and spi_unmap_msg() if
!CONFIG_HAS_DMA.
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
Signed-off-by: Mark Brown <broonie@linaro.org>
-rw-r--r-- | drivers/spi/spi.c | 109 |
1 files changed, 65 insertions, 44 deletions
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 1534fa1dac34..6046dcd7487e 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c | |||
@@ -580,6 +580,7 @@ static void spi_set_cs(struct spi_device *spi, bool enable) | |||
580 | spi->master->set_cs(spi, !enable); | 580 | spi->master->set_cs(spi, !enable); |
581 | } | 581 | } |
582 | 582 | ||
583 | #ifdef CONFIG_HAS_DMA | ||
583 | static int spi_map_buf(struct spi_master *master, struct device *dev, | 584 | static int spi_map_buf(struct spi_master *master, struct device *dev, |
584 | struct sg_table *sgt, void *buf, size_t len, | 585 | struct sg_table *sgt, void *buf, size_t len, |
585 | enum dma_data_direction dir) | 586 | enum dma_data_direction dir) |
@@ -637,55 +638,12 @@ static void spi_unmap_buf(struct spi_master *master, struct device *dev, | |||
637 | } | 638 | } |
638 | } | 639 | } |
639 | 640 | ||
640 | static int spi_map_msg(struct spi_master *master, struct spi_message *msg) | 641 | static int __spi_map_msg(struct spi_master *master, struct spi_message *msg) |
641 | { | 642 | { |
642 | struct device *tx_dev, *rx_dev; | 643 | struct device *tx_dev, *rx_dev; |
643 | struct spi_transfer *xfer; | 644 | struct spi_transfer *xfer; |
644 | void *tmp; | ||
645 | unsigned int max_tx, max_rx; | ||
646 | int ret; | 645 | int ret; |
647 | 646 | ||
648 | if (master->flags & (SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX)) { | ||
649 | max_tx = 0; | ||
650 | max_rx = 0; | ||
651 | |||
652 | list_for_each_entry(xfer, &msg->transfers, transfer_list) { | ||
653 | if ((master->flags & SPI_MASTER_MUST_TX) && | ||
654 | !xfer->tx_buf) | ||
655 | max_tx = max(xfer->len, max_tx); | ||
656 | if ((master->flags & SPI_MASTER_MUST_RX) && | ||
657 | !xfer->rx_buf) | ||
658 | max_rx = max(xfer->len, max_rx); | ||
659 | } | ||
660 | |||
661 | if (max_tx) { | ||
662 | tmp = krealloc(master->dummy_tx, max_tx, | ||
663 | GFP_KERNEL | GFP_DMA); | ||
664 | if (!tmp) | ||
665 | return -ENOMEM; | ||
666 | master->dummy_tx = tmp; | ||
667 | memset(tmp, 0, max_tx); | ||
668 | } | ||
669 | |||
670 | if (max_rx) { | ||
671 | tmp = krealloc(master->dummy_rx, max_rx, | ||
672 | GFP_KERNEL | GFP_DMA); | ||
673 | if (!tmp) | ||
674 | return -ENOMEM; | ||
675 | master->dummy_rx = tmp; | ||
676 | } | ||
677 | |||
678 | if (max_tx || max_rx) { | ||
679 | list_for_each_entry(xfer, &msg->transfers, | ||
680 | transfer_list) { | ||
681 | if (!xfer->tx_buf) | ||
682 | xfer->tx_buf = master->dummy_tx; | ||
683 | if (!xfer->rx_buf) | ||
684 | xfer->rx_buf = master->dummy_rx; | ||
685 | } | ||
686 | } | ||
687 | } | ||
688 | |||
689 | if (!master->can_dma) | 647 | if (!master->can_dma) |
690 | return 0; | 648 | return 0; |
691 | 649 | ||
@@ -742,6 +700,69 @@ static int spi_unmap_msg(struct spi_master *master, struct spi_message *msg) | |||
742 | 700 | ||
743 | return 0; | 701 | return 0; |
744 | } | 702 | } |
703 | #else /* !CONFIG_HAS_DMA */ | ||
704 | static inline int __spi_map_msg(struct spi_master *master, | ||
705 | struct spi_message *msg) | ||
706 | { | ||
707 | return 0; | ||
708 | } | ||
709 | |||
710 | static inline int spi_unmap_msg(struct spi_master *master, | ||
711 | struct spi_message *msg) | ||
712 | { | ||
713 | return 0; | ||
714 | } | ||
715 | #endif /* !CONFIG_HAS_DMA */ | ||
716 | |||
717 | static int spi_map_msg(struct spi_master *master, struct spi_message *msg) | ||
718 | { | ||
719 | struct spi_transfer *xfer; | ||
720 | void *tmp; | ||
721 | unsigned int max_tx, max_rx; | ||
722 | |||
723 | if (master->flags & (SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX)) { | ||
724 | max_tx = 0; | ||
725 | max_rx = 0; | ||
726 | |||
727 | list_for_each_entry(xfer, &msg->transfers, transfer_list) { | ||
728 | if ((master->flags & SPI_MASTER_MUST_TX) && | ||
729 | !xfer->tx_buf) | ||
730 | max_tx = max(xfer->len, max_tx); | ||
731 | if ((master->flags & SPI_MASTER_MUST_RX) && | ||
732 | !xfer->rx_buf) | ||
733 | max_rx = max(xfer->len, max_rx); | ||
734 | } | ||
735 | |||
736 | if (max_tx) { | ||
737 | tmp = krealloc(master->dummy_tx, max_tx, | ||
738 | GFP_KERNEL | GFP_DMA); | ||
739 | if (!tmp) | ||
740 | return -ENOMEM; | ||
741 | master->dummy_tx = tmp; | ||
742 | memset(tmp, 0, max_tx); | ||
743 | } | ||
744 | |||
745 | if (max_rx) { | ||
746 | tmp = krealloc(master->dummy_rx, max_rx, | ||
747 | GFP_KERNEL | GFP_DMA); | ||
748 | if (!tmp) | ||
749 | return -ENOMEM; | ||
750 | master->dummy_rx = tmp; | ||
751 | } | ||
752 | |||
753 | if (max_tx || max_rx) { | ||
754 | list_for_each_entry(xfer, &msg->transfers, | ||
755 | transfer_list) { | ||
756 | if (!xfer->tx_buf) | ||
757 | xfer->tx_buf = master->dummy_tx; | ||
758 | if (!xfer->rx_buf) | ||
759 | xfer->rx_buf = master->dummy_rx; | ||
760 | } | ||
761 | } | ||
762 | } | ||
763 | |||
764 | return __spi_map_msg(master, msg); | ||
765 | } | ||
745 | 766 | ||
746 | /* | 767 | /* |
747 | * spi_transfer_one_message - Default implementation of transfer_one_message() | 768 | * spi_transfer_one_message - Default implementation of transfer_one_message() |