From patchwork Fri Feb 17 10:38:19 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Frode Isaksen X-Patchwork-Id: 9579547 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 8A11E600F6 for ; Fri, 17 Feb 2017 10:38:40 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7A86628383 for ; Fri, 17 Feb 2017 10:38:40 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6D81A28389; Fri, 17 Feb 2017 10:38:40 +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 63736280B0 for ; Fri, 17 Feb 2017 10:38:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933507AbdBQKii (ORCPT ); Fri, 17 Feb 2017 05:38:38 -0500 Received: from mail-wm0-f43.google.com ([74.125.82.43]:35105 "EHLO mail-wm0-f43.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932269AbdBQKih (ORCPT ); Fri, 17 Feb 2017 05:38:37 -0500 Received: by mail-wm0-f43.google.com with SMTP id v186so10930711wmd.0 for ; Fri, 17 Feb 2017 02:38:36 -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:in-reply-to:references; bh=ONt5Nsa9keTptEddk1FBzaqLJGFpZBEmhLcxz8GhU48=; b=GfOkh7dvLVFUNrJ/PASSJ2Algu6LZXAonc4AMuqLc77nS9J18cT1DwS3Qq2IbuHCgD HtYm9DeguqFRtw/C/uEvVWoGqYLkb8IFMVd2ajP8bNsa+dGFMCVrCdPpC6xOvFUEK/Us zJIujaQ+wzOeYwyV8c1DaWz2W5Y10jrsTimXIng5yRQQP+Uwk97DFr/uwralsdvtD2sq xLQqf+4FlkzhoJips0pndeITFsUpuzlVpqsHeSXo+le1obgWjSl96OR+luF8wmZ9BZ/A L+2znyP1/0kgPP1zpmHKu6GhVk2EmsxUDVtNG+7Chfs9TVCCVNmMlQPTjBqf1eH7H5Fi aAUA== 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:in-reply-to :references; bh=ONt5Nsa9keTptEddk1FBzaqLJGFpZBEmhLcxz8GhU48=; b=CtPow2SOv2vSZ7jz2gY2rA15nVfCmIOwZIDvbFr64o8Jy7HTd8kiHuF8KdBsmpZF4r 2Fw4nPhTJMeno4ZwUF0LYBWDqcizl9/nuPa2Sb55dCyuAMKF1nBlIYtOKu0rtx1a7zNY t8oGrYPomPtEG+WR2dEkoOydgFNqbYuPMlihbtxU4t+2GtmsHlPgozxia9mgrVMNbNKM TUEG4IXewTQNFD1pv1CxjjcIlBjjGYnOTK/AryFq2vkNtNRVp741UhHrif47UdkYeJH1 JhfQfs/iTP356za7Rsa+0TVsxMM3u2w4k6h7aXojucL6n+r35jUAHlxNqC+GSUT/q/wm f12g== X-Gm-Message-State: AMke39lsutojlDA9Gsja3UMb/g2SljW1+0llN2g+6LzSFmyI/AtndFloC5qnwzwdo5QIad3q X-Received: by 10.28.185.77 with SMTP id j74mr1572402wmf.76.1487327915558; Fri, 17 Feb 2017 02:38:35 -0800 (PST) Received: from localhost.localdomain ([90.63.244.31]) by smtp.gmail.com with ESMTPSA id y80sm12531459wrb.12.2017.02.17.02.38.34 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 17 Feb 2017 02:38:35 -0800 (PST) From: Frode Isaksen To: nsekhar@ti.com, khilman@baylibre.com, ptitiano@baylibre.com, linux-arm-kernel@lists.infradead.org Cc: broonie@kernel.org, linux-spi@vger.kernel.org, Fabien Parent , Frode Isaksen Subject: [PATCH v2 1/6] spi: davinci: Use SPI framework to handle DMA mapping Date: Fri, 17 Feb 2017 11:38:19 +0100 Message-Id: <1487327904-28311-2-git-send-email-fisaksen@baylibre.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1487327904-28311-1-git-send-email-fisaksen@baylibre.com> References: <1487327904-28311-1-git-send-email-fisaksen@baylibre.com> 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 From: Fabien Parent 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 Signed-off-by: Frode Isaksen --- drivers/spi/spi-davinci.c | 70 +++++++++++++---------------------------------- 1 file changed, 19 insertions(+), 51 deletions(-) diff --git a/drivers/spi/spi-davinci.c b/drivers/spi/spi-davinci.c index 02fb967..5b164e5 100644 --- a/drivers/spi/spi-davinci.c +++ b/drivers/spi/spi-davinci.c @@ -467,6 +467,20 @@ static void davinci_spi_cleanup(struct spi_device *spi) kfree(spicfg); } +static inline bool __davinci_spi_can_dma(struct spi_device *spi) +{ + struct davinci_spi_config *spicfg = spi->controller_data; + + return spicfg ? spicfg->io_type == SPI_IO_TYPE_DMA : false; +} + +static bool davinci_spi_can_dma(struct spi_master *master, + struct spi_device *spi, + struct spi_transfer *xfer) +{ + return __davinci_spi_can_dma(spi); +} + static int davinci_spi_check_error(struct davinci_spi *dspi, int int_status) { struct device *sdev = dspi->bitbang.master->dev.parent; @@ -581,8 +595,6 @@ static int davinci_spi_bufs(struct spi_device *spi, struct spi_transfer *t) struct davinci_spi_config *spicfg; struct davinci_spi_platform_data *pdata; unsigned uninitialized_var(rx_buf_count); - void *dummy_buf = NULL; - struct scatterlist sg_rx, sg_tx; dspi = spi_master_get_devdata(spi->master); pdata = &dspi->pdata; @@ -630,51 +642,18 @@ 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) - goto err_alloc_dummy_buf; 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; - } - 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; - } - 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, t->rx_sg.nents, 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, t->tx_sg.nents, DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); if (!txdesc) goto err_desc; @@ -710,16 +689,9 @@ static int davinci_spi_bufs(struct spi_device *spi, struct spi_transfer *t) } clear_io_bits(dspi->base + SPIINT, SPIINT_MASKALL); - if (spicfg->io_type == SPI_IO_TYPE_DMA) { + 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); - kfree(dummy_buf); - } - clear_io_bits(dspi->base + SPIGCR1, SPIGCR1_SPIENA_MASK); set_io_bits(dspi->base + SPIGCR1, SPIGCR1_POWERDOWN_MASK); @@ -742,12 +714,6 @@ 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); -err_tx_map: - dma_unmap_single(&spi->dev, t->rx_dma, t->len, DMA_FROM_DEVICE); -err_rx_map: - kfree(dummy_buf); -err_alloc_dummy_buf: return ret; } @@ -988,8 +954,10 @@ static int davinci_spi_probe(struct platform_device *pdev) master->bus_num = pdev->id; master->num_chipselect = pdata->num_chipselect; master->bits_per_word_mask = SPI_BPW_RANGE_MASK(2, 16); + master->flags = (SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX); 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;