Commit 2de440f5 authored by Geert Uytterhoeven's avatar Geert Uytterhoeven Committed by Mark Brown
Browse files

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: default avatarGeert Uytterhoeven <geert@linux-m68k.org>
Signed-off-by: default avatarMark Brown <broonie@linaro.org>
parent 83596fbe
Loading
Loading
Loading
Loading
+65 −44
Original line number Diff line number Diff line
@@ -580,6 +580,7 @@ static void spi_set_cs(struct spi_device *spi, bool enable)
		spi->master->set_cs(spi, !enable);
}

#ifdef CONFIG_HAS_DMA
static int spi_map_buf(struct spi_master *master, struct device *dev,
		       struct sg_table *sgt, void *buf, size_t len,
		       enum dma_data_direction dir)
@@ -637,55 +638,12 @@ static void spi_unmap_buf(struct spi_master *master, struct device *dev,
	}
}

static int spi_map_msg(struct spi_master *master, struct spi_message *msg)
static int __spi_map_msg(struct spi_master *master, struct spi_message *msg)
{
	struct device *tx_dev, *rx_dev;
	struct spi_transfer *xfer;
	void *tmp;
	unsigned int max_tx, max_rx;
	int ret;

	if (master->flags & (SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX)) {
		max_tx = 0;
		max_rx = 0;

		list_for_each_entry(xfer, &msg->transfers, transfer_list) {
			if ((master->flags & SPI_MASTER_MUST_TX) &&
			    !xfer->tx_buf)
				max_tx = max(xfer->len, max_tx);
			if ((master->flags & SPI_MASTER_MUST_RX) &&
			    !xfer->rx_buf)
				max_rx = max(xfer->len, max_rx);
		}

		if (max_tx) {
			tmp = krealloc(master->dummy_tx, max_tx,
				       GFP_KERNEL | GFP_DMA);
			if (!tmp)
				return -ENOMEM;
			master->dummy_tx = tmp;
			memset(tmp, 0, max_tx);
		}

		if (max_rx) {
			tmp = krealloc(master->dummy_rx, max_rx,
				       GFP_KERNEL | GFP_DMA);
			if (!tmp)
				return -ENOMEM;
			master->dummy_rx = tmp;
		}

		if (max_tx || max_rx) {
			list_for_each_entry(xfer, &msg->transfers,
					    transfer_list) {
				if (!xfer->tx_buf)
					xfer->tx_buf = master->dummy_tx;
				if (!xfer->rx_buf)
					xfer->rx_buf = master->dummy_rx;
			}
		}
	}

	if (!master->can_dma)
		return 0;

@@ -742,6 +700,69 @@ static int spi_unmap_msg(struct spi_master *master, struct spi_message *msg)

	return 0;
}
#else /* !CONFIG_HAS_DMA */
static inline int __spi_map_msg(struct spi_master *master,
				struct spi_message *msg)
{
	return 0;
}

static inline int spi_unmap_msg(struct spi_master *master,
				struct spi_message *msg)
{
	return 0;
}
#endif /* !CONFIG_HAS_DMA */

static int spi_map_msg(struct spi_master *master, struct spi_message *msg)
{
	struct spi_transfer *xfer;
	void *tmp;
	unsigned int max_tx, max_rx;

	if (master->flags & (SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX)) {
		max_tx = 0;
		max_rx = 0;

		list_for_each_entry(xfer, &msg->transfers, transfer_list) {
			if ((master->flags & SPI_MASTER_MUST_TX) &&
			    !xfer->tx_buf)
				max_tx = max(xfer->len, max_tx);
			if ((master->flags & SPI_MASTER_MUST_RX) &&
			    !xfer->rx_buf)
				max_rx = max(xfer->len, max_rx);
		}

		if (max_tx) {
			tmp = krealloc(master->dummy_tx, max_tx,
				       GFP_KERNEL | GFP_DMA);
			if (!tmp)
				return -ENOMEM;
			master->dummy_tx = tmp;
			memset(tmp, 0, max_tx);
		}

		if (max_rx) {
			tmp = krealloc(master->dummy_rx, max_rx,
				       GFP_KERNEL | GFP_DMA);
			if (!tmp)
				return -ENOMEM;
			master->dummy_rx = tmp;
		}

		if (max_tx || max_rx) {
			list_for_each_entry(xfer, &msg->transfers,
					    transfer_list) {
				if (!xfer->tx_buf)
					xfer->tx_buf = master->dummy_tx;
				if (!xfer->rx_buf)
					xfer->rx_buf = master->dummy_rx;
			}
		}
	}

	return __spi_map_msg(master, msg);
}

/*
 * spi_transfer_one_message - Default implementation of transfer_one_message()