Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 65bf2205 authored by Geert Uytterhoeven's avatar Geert Uytterhoeven Committed by Mark Brown
Browse files

spi: rspi: Extract rspi_request_dma_chan()



Setup of the receive and transmit DMA channels is very similar, so let's
consolidate.

Signed-off-by: default avatarGeert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: default avatarMark Brown <broonie@linaro.org>
parent 27e105a6
Loading
Loading
Loading
Loading
+55 −34
Original line number Diff line number Diff line
@@ -942,52 +942,73 @@ static irqreturn_t rspi_irq_tx(int irq, void *_sr)
	return 0;
}

static struct dma_chan *rspi_request_dma_chan(struct device *dev,
					      enum dma_transfer_direction dir,
					      unsigned int id,
					      dma_addr_t port_addr)
{
	dma_cap_mask_t mask;
	struct dma_chan *chan;
	struct dma_slave_config cfg;
	int ret;

	dma_cap_zero(mask);
	dma_cap_set(DMA_SLAVE, mask);

	chan = dma_request_channel(mask, shdma_chan_filter,
				   (void *)(unsigned long)id);
	if (!chan) {
		dev_warn(dev, "dma_request_channel failed\n");
		return NULL;
	}

	memset(&cfg, 0, sizeof(cfg));
	cfg.slave_id = id;
	cfg.direction = dir;
	if (dir == DMA_MEM_TO_DEV)
		cfg.dst_addr = port_addr;
	else
		cfg.src_addr = port_addr;

	ret = dmaengine_slave_config(chan, &cfg);
	if (ret) {
		dev_warn(dev, "dmaengine_slave_config failed %d\n", ret);
		dma_release_channel(chan);
		return NULL;
	}

	return chan;
}

static int rspi_request_dma(struct rspi_data *rspi,
			    struct platform_device *pdev)
{
	const struct rspi_plat_data *rspi_pd = dev_get_platdata(&pdev->dev);
	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	dma_cap_mask_t mask;
	struct dma_slave_config cfg;
	int ret;

	if (!res || !rspi_pd)
		return 0;	/* The driver assumes no error. */

	/* If the module receives data by DMAC, it also needs TX DMAC */
	if (rspi_pd->dma_rx_id && rspi_pd->dma_tx_id) {
		dma_cap_zero(mask);
		dma_cap_set(DMA_SLAVE, mask);
		rspi->chan_rx = dma_request_channel(mask, shdma_chan_filter,
						    (void *)rspi_pd->dma_rx_id);
		if (rspi->chan_rx) {
			cfg.slave_id = rspi_pd->dma_rx_id;
			cfg.direction = DMA_DEV_TO_MEM;
			cfg.dst_addr = 0;
			cfg.src_addr = res->start + RSPI_SPDR;
			ret = dmaengine_slave_config(rspi->chan_rx, &cfg);
			if (!ret)
		rspi->chan_rx = rspi_request_dma_chan(&pdev->dev,
						      DMA_DEV_TO_MEM,
						      rspi_pd->dma_rx_id,
						      res->start + RSPI_SPDR);
		if (!rspi->chan_rx)
			return -ENODEV;

		dev_info(&pdev->dev, "Use DMA when rx.\n");
			else
				return ret;
		}
	}
	if (rspi_pd->dma_tx_id) {
		dma_cap_zero(mask);
		dma_cap_set(DMA_SLAVE, mask);
		rspi->chan_tx = dma_request_channel(mask, shdma_chan_filter,
						    (void *)rspi_pd->dma_tx_id);
		if (rspi->chan_tx) {
			cfg.slave_id = rspi_pd->dma_tx_id;
			cfg.direction = DMA_MEM_TO_DEV;
			cfg.dst_addr = res->start + RSPI_SPDR;
			cfg.src_addr = 0;
			ret = dmaengine_slave_config(rspi->chan_tx, &cfg);
			if (!ret)
		rspi->chan_tx = rspi_request_dma_chan(&pdev->dev,
						      DMA_MEM_TO_DEV,
						      rspi_pd->dma_tx_id,
						      res->start + RSPI_SPDR);
		if (!rspi->chan_tx)
			return -ENODEV;

		dev_info(&pdev->dev, "Use DMA when tx\n");
			else
				return ret;
		}
	}

	return 0;