From patchwork Mon Feb 6 14:57:07 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fabien Parent X-Patchwork-Id: 9558165 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 6F317602B1 for ; Mon, 6 Feb 2017 14:57:15 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5E51327F9A for ; Mon, 6 Feb 2017 14:57:15 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 51A3E27F9F; Mon, 6 Feb 2017 14:57:15 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7A9B327F93 for ; Mon, 6 Feb 2017 14:57:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752001AbdBFO5O (ORCPT ); Mon, 6 Feb 2017 09:57:14 -0500 Received: from mail-wj0-f182.google.com ([209.85.210.182]:33864 "EHLO mail-wj0-f182.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751977AbdBFO5N (ORCPT ); Mon, 6 Feb 2017 09:57:13 -0500 Received: by mail-wj0-f182.google.com with SMTP id uo9so3443495wjc.1 for ; Mon, 06 Feb 2017 06:57:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id; bh=CTFsOj/lmWBcLNVUVNdy7rnj3t1Z0fGy9+JTs1NGs5M=; b=U0CHo95ZGq/vjx5qRoXizeEnwgrqdZfdqCsLCC0S39Wu+sipF0D2/OHm6vkWI7Halq vVGsG9mnZ+IcxTS/s5NWj2lrXXJUiGZSJP/KRyXiUwd146Nc4k6XSL/cYt+F/l0QST73 +RzhnhvA8xuLWhXbC8vtbSS+cWEbtaTPpM8Xy3qu/ZHUEt0TrR3IKlwaX6xf+Kd4qvwy Ot4ioOc1j22hxhRki7ADNi5SoBBXAK92+FFRNoT0JB/VDjugIQ8uJd/xR1TiA1gpnIjH Jf0ZwJjeVm5+MFVKdnF4O+pv1WYyqLDSzWjJbCY8XrA28pGIi1s6WVXG3Llc0KFP6jvb gqYw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=CTFsOj/lmWBcLNVUVNdy7rnj3t1Z0fGy9+JTs1NGs5M=; b=oS3Vw7CLP4Mri568Xi8Ttntyz31/jWGo2mILrTWYZtNNYX3YLKf0ZOBkFxPVnrANwW ZmwWY+cYHnaqbMLQ2ax9WBAPQ1c1nxoOBM17RAeWPRbCfsxi8RRsytvePXT46OKVpqGZ z8UdEjPnkQpRLgGjn6g+BCAstbFDZfPSr2IzmYvON3d1Qp8bv/UBUj/MJoEWTqXf4Pmy EEMg9obkWoQTt4Ac1iOg5Elk9QGIuhbS70ceeXHQII7uYNjLBjrGL12LC405uJdCu6oS HT+Do/oLAUpq0FvgJ3lN+RAerKs2qNZtRczj1rq6JWQDLPvClyqe+JHOWt9GBd3hCMgh KI3A== X-Gm-Message-State: AIkVDXLkFFtK8B5btv7k6zw74rdUELfmpkZ6NEu0JlB9lwIQX0BmDIFgEwkS8MAlEUpPHTzS X-Received: by 10.223.135.163 with SMTP id b32mr9713106wrb.184.1486393031582; Mon, 06 Feb 2017 06:57:11 -0800 (PST) Received: from localhost.localdomain ([90.63.244.31]) by smtp.gmail.com with ESMTPSA id w204sm13300059wmd.17.2017.02.06.06.57.10 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 06 Feb 2017 06:57:11 -0800 (PST) From: Fabien Parent To: broonie@kernel.org Cc: linux-spi@vger.kernel.org, linux-kernel@vger.kernel.org, nsekhar@ti.com, ptitiano@baylibre.com, khilman@baylibre.com, Fabien Parent Subject: [PATCH 1/2] spi: davinci: Use SPI framework to handle DMA mapping Date: Mon, 6 Feb 2017 15:57:07 +0100 Message-Id: <20170206145708.24356-1-fparent@baylibre.com> X-Mailer: git-send-email 2.11.0 Sender: linux-spi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Uppers layers like MTD can pass vmalloc'd buffers to the SPI driver, and the current implementation will fail to map these kind of buffers. The SPI framework is able to detect the best way to handle and map buffers. This commit updates the davinci SPI driver in order to use the SPI framework to handle the DMA mapping of buffers coming from an upper layer. Signed-off-by: Fabien Parent --- drivers/spi/spi-davinci.c | 78 ++++++++++++++++++++++++++++------------------- 1 file changed, 46 insertions(+), 32 deletions(-) diff --git a/drivers/spi/spi-davinci.c b/drivers/spi/spi-davinci.c index 02fb96797ac8..cb80c1d3f86a 100644 --- a/drivers/spi/spi-davinci.c +++ b/drivers/spi/spi-davinci.c @@ -630,7 +630,6 @@ static int davinci_spi_bufs(struct spi_device *spi, struct spi_transfer *t) }; struct dma_async_tx_descriptor *rxdesc; struct dma_async_tx_descriptor *txdesc; - void *buf; dummy_buf = kzalloc(t->len, GFP_KERNEL); if (!dummy_buf) @@ -639,42 +638,40 @@ static int davinci_spi_bufs(struct spi_device *spi, struct spi_transfer *t) dmaengine_slave_config(dspi->dma_rx, &dma_rx_conf); dmaengine_slave_config(dspi->dma_tx, &dma_tx_conf); - sg_init_table(&sg_rx, 1); - if (!t->rx_buf) - buf = dummy_buf; - else - buf = t->rx_buf; - t->rx_dma = dma_map_single(&spi->dev, buf, - t->len, DMA_FROM_DEVICE); - if (dma_mapping_error(&spi->dev, !t->rx_dma)) { - ret = -EFAULT; - goto err_rx_map; + if (!t->rx_buf) { + sg_init_table(&sg_rx, 1); + t->rx_dma = dma_map_single(&spi->dev, dummy_buf, + t->len, DMA_FROM_DEVICE); + if (dma_mapping_error(&spi->dev, !t->rx_dma)) { + ret = -EFAULT; + goto err_rx_map; + } + sg_dma_address(&sg_rx) = t->rx_dma; + sg_dma_len(&sg_rx) = t->len; } - sg_dma_address(&sg_rx) = t->rx_dma; - sg_dma_len(&sg_rx) = t->len; sg_init_table(&sg_tx, 1); - if (!t->tx_buf) - buf = dummy_buf; - else - buf = (void *)t->tx_buf; - t->tx_dma = dma_map_single(&spi->dev, buf, - t->len, DMA_TO_DEVICE); - if (dma_mapping_error(&spi->dev, t->tx_dma)) { - ret = -EFAULT; - goto err_tx_map; + if (!t->tx_buf) { + t->tx_dma = dma_map_single(&spi->dev, (void *)t->tx_buf, + t->len, DMA_TO_DEVICE); + if (dma_mapping_error(&spi->dev, t->tx_dma)) { + ret = -EFAULT; + goto err_tx_map; + } + sg_dma_address(&sg_tx) = t->tx_dma; + sg_dma_len(&sg_tx) = t->len; } - sg_dma_address(&sg_tx) = t->tx_dma; - sg_dma_len(&sg_tx) = t->len; rxdesc = dmaengine_prep_slave_sg(dspi->dma_rx, - &sg_rx, 1, DMA_DEV_TO_MEM, + t->rx_sg.sgl ?: &sg_rx, t->rx_sg.nents ?: 1, + DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); if (!rxdesc) goto err_desc; txdesc = dmaengine_prep_slave_sg(dspi->dma_tx, - &sg_tx, 1, DMA_MEM_TO_DEV, + t->tx_sg.sgl ?: &sg_tx, t->tx_sg.nents ?: 1, + DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); if (!txdesc) goto err_desc; @@ -713,10 +710,12 @@ static int davinci_spi_bufs(struct spi_device *spi, struct spi_transfer *t) if (spicfg->io_type == SPI_IO_TYPE_DMA) { clear_io_bits(dspi->base + SPIINT, SPIINT_DMA_REQ_EN); - dma_unmap_single(&spi->dev, t->rx_dma, - t->len, DMA_FROM_DEVICE); - dma_unmap_single(&spi->dev, t->tx_dma, - t->len, DMA_TO_DEVICE); + if (!t->rx_buf) + dma_unmap_single(&spi->dev, t->rx_dma, + t->len, DMA_FROM_DEVICE); + if (!t->tx_buf) + dma_unmap_single(&spi->dev, t->tx_dma, + t->len, DMA_TO_DEVICE); kfree(dummy_buf); } @@ -742,9 +741,11 @@ static int davinci_spi_bufs(struct spi_device *spi, struct spi_transfer *t) return t->len; err_desc: - dma_unmap_single(&spi->dev, t->tx_dma, t->len, DMA_TO_DEVICE); + if (!t->tx_buf) + dma_unmap_single(&spi->dev, t->tx_dma, t->len, DMA_TO_DEVICE); err_tx_map: - dma_unmap_single(&spi->dev, t->rx_dma, t->len, DMA_FROM_DEVICE); + if (!t->rx_buf) + dma_unmap_single(&spi->dev, t->rx_dma, t->len, DMA_FROM_DEVICE); err_rx_map: kfree(dummy_buf); err_alloc_dummy_buf: @@ -898,6 +899,18 @@ static struct davinci_spi_platform_data } #endif +static bool davinci_spi_can_dma(struct spi_master *master, + struct spi_device *spi, + struct spi_transfer *xfer) +{ + struct davinci_spi_config *spicfg = spi->controller_data; + + if (!spicfg) + spicfg = &davinci_spi_default_cfg; + + return spicfg->io_type == SPI_IO_TYPE_DMA; +} + /** * davinci_spi_probe - probe function for SPI Master Controller * @pdev: platform_device structure which contains plateform specific data @@ -990,6 +1003,7 @@ static int davinci_spi_probe(struct platform_device *pdev) master->bits_per_word_mask = SPI_BPW_RANGE_MASK(2, 16); master->setup = davinci_spi_setup; master->cleanup = davinci_spi_cleanup; + master->can_dma = davinci_spi_can_dma; dspi->bitbang.chipselect = davinci_spi_chipselect; dspi->bitbang.setup_transfer = davinci_spi_setup_transfer;