From patchwork Thu Feb 23 18:01:56 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Frode Isaksen X-Patchwork-Id: 9588747 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 B705760210 for ; Thu, 23 Feb 2017 18:02:58 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id ABDF52877E for ; Thu, 23 Feb 2017 18:02:58 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A08BB2878B; Thu, 23 Feb 2017 18:02:58 +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 D1CCD2877E for ; Thu, 23 Feb 2017 18:02:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751156AbdBWSC5 (ORCPT ); Thu, 23 Feb 2017 13:02:57 -0500 Received: from mail-wr0-f179.google.com ([209.85.128.179]:36308 "EHLO mail-wr0-f179.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751049AbdBWSC5 (ORCPT ); Thu, 23 Feb 2017 13:02:57 -0500 Received: by mail-wr0-f179.google.com with SMTP id 89so26604539wrr.3 for ; Thu, 23 Feb 2017 10:02:56 -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=T+P+N2wWuFEgb30pK7eWoJBl7ERbsvSxXF9Hv93QCB0=; b=jBTqYAJ2tQWiUQ7CLuEC1zfNkMTpM+AlEnpMUZJvv+BcT4/xxEkAF6J/2PdtgD3bm9 Gaa0x54qQkOXoBkE5Y+llW+zv3pmX6kSTVzeDGOMCrRxB7eA1L7nc96luFtQyEzJ997l iKGm27LERIupZBCKvG8OKXcqq6QZew4NPA4g5OXsgUf9L06PJpgZI5iuABECH/7XaDJa dQOjcQ2xahEhE6WDV0r3d7v1COC3QdnannylKRwU4JaeH/S+ynbxWdvrNCP9om853WGk ZyavBhCpftF9fPmzEXZef1EI/34j5iGx+Ae/fHoaMfGjEBbJs4MOzbFFZ223QtdbcLFs XBFQ== 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=T+P+N2wWuFEgb30pK7eWoJBl7ERbsvSxXF9Hv93QCB0=; b=NQX/+8tTLr66OO9pIkESAnCc9M/DRGbPUiTAz8s+MHqn3A+7lwtDJeuSsif3mOegKN xyKExm7tlDmR5bjce796i2FAmy1qRvXBynPy75sg+TO3kpZaeIVzF1IHmSZgfN8T7DYK +cFklVn04yNk3ViqPm2l8AGYWU8MBLm362hUSamhLJpC2MnD2cuSoOVU3WJcaK/4PHn2 2z7EAWN7oKetKir7SIcgjyD8vF0aq7ilHJHOWtKsAo6gXvx1XGXpnLAtpdA1/tf1pYGW kkkUzstF8B0NwKgbIUM7289OnEWbSdSaT2HEmi28Ld+0lIdx5s54e+0BPoOKdblOTFXQ i7tg== X-Gm-Message-State: AMke39kfqfYC6bFOJ7IqFkM+3HuWRtc79mwIjn5UGMvoc/ShgPVtMFwkfh/mA1ZEQqJuK9Hc X-Received: by 10.223.135.186 with SMTP id b55mr30483550wrb.170.1487872975142; Thu, 23 Feb 2017 10:02:55 -0800 (PST) Received: from localhost.localdomain ([90.63.244.31]) by smtp.gmail.com with ESMTPSA id z134sm7739182wmc.20.2017.02.23.10.02.54 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 23 Feb 2017 10:02:54 -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 v3 1/6] spi: davinci: Use SPI framework to handle DMA mapping Date: Thu, 23 Feb 2017 19:01:56 +0100 Message-Id: <1487872921-26628-2-git-send-email-fisaksen@baylibre.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1487872921-26628-1-git-send-email-fisaksen@baylibre.com> References: <1487872921-26628-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 | 69 +++++++++++++---------------------------------- 1 file changed, 18 insertions(+), 51 deletions(-) diff --git a/drivers/spi/spi-davinci.c b/drivers/spi/spi-davinci.c index 02fb967..164cc71 100644 --- a/drivers/spi/spi-davinci.c +++ b/drivers/spi/spi-davinci.c @@ -467,6 +467,19 @@ static void davinci_spi_cleanup(struct spi_device *spi) kfree(spicfg); } +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; + bool can_dma = false; + + if (spicfg) + can_dma = spicfg->io_type == SPI_IO_TYPE_DMA; + + return can_dma; +} + static int davinci_spi_check_error(struct davinci_spi *dspi, int int_status) { struct device *sdev = dspi->bitbang.master->dev.parent; @@ -581,8 +594,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 +641,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 +688,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 +713,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 +953,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;