From patchwork Mon Apr 3 15:47:50 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Cercueil X-Patchwork-Id: 78617 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp2416925vqo; Mon, 3 Apr 2023 09:11:26 -0700 (PDT) X-Google-Smtp-Source: AKy350bbeGQyygLmbiAz5tmTpZNqJrB4dGyJ19Xl2O48eGuR+lwMurYUrG+wRE+YlhzpuF6MlkCu X-Received: by 2002:a05:6402:1390:b0:502:2382:5c24 with SMTP id b16-20020a056402139000b0050223825c24mr31742117edv.39.1680538286167; Mon, 03 Apr 2023 09:11:26 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1680538286; cv=none; d=google.com; s=arc-20160816; b=ovPPBHMuLPumnreh0R9Tq/bXxwBeG81L/AYk/pG7rKkgqlvdp0R/XZeURG4USbbfr6 hJrEwPoqcM3nrjC0RhbNkel0vO4wbnR47lq3aE9cj5BNPfWf4Ua1zFeIbe76oefZn2Vo WDyuifvqNeF9x+YQI5IbSJoUNvycvkK5OhCi5AGX4AHD34StKUaRNY3P0bg3pDnuJ/Wn B/jXOeIKu+jmPGjoMZxDtJWj9czzGDWtSrx5/CBGomDDlQKtCLyD7zyjJwl+PeYG/A9B 0ECA1/0j0emUFtfkzFFfmQ2ETzIgQ0qMVCKl9pdib65fn4Nw3qa/QnOtRRWgNqo2b2Mn 503Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=Dku4wXuwudT4q34STxa4FMfMek4fO2ojnwUzBKSuXjA=; b=F7jguF+7l1nK+4Q5Lj0iICuqaFT++45Kra3ua2BdS0ejP8PiNBfqiG1udrN+GB2ugw WUWK/Ujl36kJezeAmyN3ljiPAg0L2WqXv/jbKlQAA7LdQRr0BFMvzvSDkOlJZ6LvHiJM RJj7seeGeRfxPaFRnrGvzLtu6EgyuD/8dx+6RY1iU0LCCr8ljXay6UReQx98VZv2WctS OQ//VlVJ8sPZj4oio8akLU5cTifX79r5V14BbFc33mfNlNGi457S311NDLJtmUPZtWYy FZdu+/N56Ftyzirr0p/e9We62l7UvP4050eYIYbIw1ML+yLTWD55/0nCSRkwdMV8M0jn Gztw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@crapouillou.net header.s=mail header.b=ecN8+hUA; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=crapouillou.net Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id h13-20020a50ed8d000000b004aad0c7e385si9029940edr.270.2023.04.03.09.11.01; Mon, 03 Apr 2023 09:11:26 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@crapouillou.net header.s=mail header.b=ecN8+hUA; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=crapouillou.net Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232390AbjDCPtp (ORCPT + 99 others); Mon, 3 Apr 2023 11:49:45 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59208 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232181AbjDCPtl (ORCPT ); Mon, 3 Apr 2023 11:49:41 -0400 Received: from aposti.net (aposti.net [89.234.176.197]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 82AD640F2; Mon, 3 Apr 2023 08:49:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=crapouillou.net; s=mail; t=1680536890; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Dku4wXuwudT4q34STxa4FMfMek4fO2ojnwUzBKSuXjA=; b=ecN8+hUAzZ3PoWqKSNgaK36hhfmHEAL9q+kQOHkW6Xy1qm2ThwiFt1rf+FyO66SEq6ps3E XRiKDUUYLbEOIC2dIXXyQmp5xjVMBM+BNUcZvgMI0LaDHcIMDkJ4KonmDEz5mxYRKkJNSf ThVDFZ59kByB/lZJ8kyH48P0wXH40/U= From: Paul Cercueil To: Jonathan Cameron , Lars-Peter Clausen , Vinod Koul , Michael Hennerich , =?utf-8?q?Nuno_S=C3=A1?= , Sumit Semwal , =?utf-8?q?Christian_K=C3=B6nig?= Cc: linux-kernel@vger.kernel.org, dmaengine@vger.kernel.org, linux-iio@vger.kernel.org, linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org, Paul Cercueil Subject: [PATCH v3 01/11] dmaengine: Add API function dmaengine_prep_slave_dma_array() Date: Mon, 3 Apr 2023 17:47:50 +0200 Message-Id: <20230403154800.215924-2-paul@crapouillou.net> In-Reply-To: <20230403154800.215924-1-paul@crapouillou.net> References: <20230403154800.215924-1-paul@crapouillou.net> MIME-Version: 1.0 X-Spam: Yes X-Spam-Status: No, score=-0.2 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_PASS,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1762172114304684248?= X-GMAIL-MSGID: =?utf-8?q?1762172114304684248?= This function can be used to initiate a scatter-gather DMA transfer where the DMA addresses and lengths are located inside arrays. The major difference with dmaengine_prep_slave_sg() is that it supports specifying the lengths of each DMA transfer; as trying to override the length of the transfer with dmaengine_prep_slave_sg() is a very tedious process. The introduction of a new API function is also justified by the fact that scatterlists are on their way out. Signed-off-by: Paul Cercueil --- v3: New patch --- include/linux/dmaengine.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index c3656e590213..62efa28c009a 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -912,6 +912,11 @@ struct dma_device { struct dma_async_tx_descriptor *(*device_prep_dma_interrupt)( struct dma_chan *chan, unsigned long flags); + struct dma_async_tx_descriptor *(*device_prep_slave_dma_array)( + struct dma_chan *chan, dma_addr_t *addrs, + size_t *lengths, size_t nb, + enum dma_transfer_direction direction, + unsigned long flags); struct dma_async_tx_descriptor *(*device_prep_slave_sg)( struct dma_chan *chan, struct scatterlist *sgl, unsigned int sg_len, enum dma_transfer_direction direction, @@ -974,6 +979,17 @@ static inline struct dma_async_tx_descriptor *dmaengine_prep_slave_single( dir, flags, NULL); } +static inline struct dma_async_tx_descriptor *dmaengine_prep_slave_dma_array( + struct dma_chan *chan, dma_addr_t *addrs, size_t *lengths, + size_t nb, enum dma_transfer_direction dir, unsigned long flags) +{ + if (!chan || !chan->device || !chan->device->device_prep_slave_dma_array) + return NULL; + + return chan->device->device_prep_slave_dma_array(chan, addrs, lengths, + nb, dir, flags); +} + static inline struct dma_async_tx_descriptor *dmaengine_prep_slave_sg( struct dma_chan *chan, struct scatterlist *sgl, unsigned int sg_len, enum dma_transfer_direction dir, unsigned long flags) From patchwork Mon Apr 3 15:47:51 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Cercueil X-Patchwork-Id: 78611 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp2415826vqo; Mon, 3 Apr 2023 09:09:58 -0700 (PDT) X-Google-Smtp-Source: AK7set9q0zXfalxDy1mJe28wMnX9Nj9ITgRL69Nb9ZkX6HdBfEtR8g/9NfAL7+1CETxXZfGdMX50 X-Received: by 2002:a05:6a20:b2f:b0:d9:9e33:7218 with SMTP id x47-20020a056a200b2f00b000d99e337218mr30076260pzf.1.1680538198186; Mon, 03 Apr 2023 09:09:58 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1680538198; cv=none; d=google.com; s=arc-20160816; b=LHQT1siBj1wwpPTpYGsAaelt9AD3hKY89x+zx7xWARxwEf945I0eqoiSngmUZsQp2H MSMk1gdJwD2QwzqFw3KxKtUBLY0grClQ1M/WEJAw9/WrhjIsWvLVUQ0HiRQPdrMkC1FD jXCH11gx5JZY/LhtsFYGCtsHLvh7uavmvaNtokkh4gNAZNJipkUeluSeOQk/h9a0w3it yaO9cBHbLUhQ7IedNDXd1I1rsqN1pLXQF+TXlbEa1pa4CSkxVF3tbDGr+edb1IrVDlmh SJxJfKfZsognftpSkkjqilmDrx0R86bys5xFd3cPjDsIYUYhnO6leWTMKir0Y7UBvbdg 5k2Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=nBi7PX/7n3UhrKXex6m7UfXrnlhGP3WO/OYjpM7zL0o=; b=XII5SYOkiJWJcWGBx9xlkK7SH7CX25c3DNFrvqpFMHwpA3i1bs3xHgS51OB1rjhECS XzRuf5DTBFPvXfpLWiGqa4HTTVn2s7zahCZ2Ab7I7gkJThzFQ5lLVRB172iXk3/E+mTL AY+vgScxMutGDeByP8Aq249daGXOCmX7Fq75x+FPRToSBckVCupYkxfZOmnb/C/CW0hH T8yj7n+15UmX6WXWgBecjez9KFXWc+9PDLPle29A9Yn1zCv/K3Owqo1kiiIStF2sEzv9 mIOwRw4/qGkIo+67qmjrkmUamAWVrLXEUIcuxVWUbg0QTgqt3QGD+7lz61BO2PrVBY2/ Uogw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@crapouillou.net header.s=mail header.b=QW2FI1x4; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=crapouillou.net Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id r9-20020aa79889000000b00625dc9792a6si8475478pfl.300.2023.04.03.09.09.45; Mon, 03 Apr 2023 09:09:58 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@crapouillou.net header.s=mail header.b=QW2FI1x4; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=crapouillou.net Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232800AbjDCPuV (ORCPT + 99 others); Mon, 3 Apr 2023 11:50:21 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60204 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232672AbjDCPuJ (ORCPT ); Mon, 3 Apr 2023 11:50:09 -0400 Received: from aposti.net (aposti.net [89.234.176.197]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D8B663AB1; Mon, 3 Apr 2023 08:49:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=crapouillou.net; s=mail; t=1680536891; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=nBi7PX/7n3UhrKXex6m7UfXrnlhGP3WO/OYjpM7zL0o=; b=QW2FI1x44F8Zk1JtxUeC1uKCao8FhfoJddmDLG200LbZ6MiogX5rGWrXhlIhSP9w7IWGeT h8wDfNhQW7P/fOr2orBwPD215WIhvGp6p/oT1Qp5GAZTQwTcneLKHtu3nlaIWA8TuvfaZN /g+CFxG9a3QwUlJqgjTZMaXVDkI185M= From: Paul Cercueil To: Jonathan Cameron , Lars-Peter Clausen , Vinod Koul , Michael Hennerich , =?utf-8?q?Nuno_S=C3=A1?= , Sumit Semwal , =?utf-8?q?Christian_K=C3=B6nig?= Cc: linux-kernel@vger.kernel.org, dmaengine@vger.kernel.org, linux-iio@vger.kernel.org, linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org, Paul Cercueil Subject: [PATCH v3 02/11] dmaengine: dma-axi-dmac: Implement device_prep_slave_dma_array Date: Mon, 3 Apr 2023 17:47:51 +0200 Message-Id: <20230403154800.215924-3-paul@crapouillou.net> In-Reply-To: <20230403154800.215924-1-paul@crapouillou.net> References: <20230403154800.215924-1-paul@crapouillou.net> MIME-Version: 1.0 X-Spam: Yes X-Spam-Status: No, score=-0.2 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_PASS,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1762172022035191838?= X-GMAIL-MSGID: =?utf-8?q?1762172022035191838?= Add implementation of the .device_prep_slave_dma_array() callback. Signed-off-by: Paul Cercueil --- v3: New patch --- drivers/dma/dma-axi-dmac.c | 41 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/drivers/dma/dma-axi-dmac.c b/drivers/dma/dma-axi-dmac.c index a812b9b00e6b..61a796aca631 100644 --- a/drivers/dma/dma-axi-dmac.c +++ b/drivers/dma/dma-axi-dmac.c @@ -536,6 +536,46 @@ static struct axi_dmac_sg *axi_dmac_fill_linear_sg(struct axi_dmac_chan *chan, return sg; } +static struct dma_async_tx_descriptor * +axi_dmac_prep_slave_dma_array(struct dma_chan *c, dma_addr_t *addrs, + size_t *lengths, size_t nb, + enum dma_transfer_direction direction, + unsigned long flags) +{ + struct axi_dmac_chan *chan = to_axi_dmac_chan(c); + struct axi_dmac_desc *desc; + unsigned int num_sgs = 0; + struct axi_dmac_sg *dsg; + size_t i; + + if (direction != chan->direction) + return NULL; + + for (i = 0; i < nb; i++) + num_sgs += DIV_ROUND_UP(lengths[i], chan->max_length); + + desc = axi_dmac_alloc_desc(num_sgs); + if (!desc) + return NULL; + + dsg = desc->sg; + + for (i = 0; i < nb; i++) { + if (!axi_dmac_check_addr(chan, addrs[i]) || + !axi_dmac_check_len(chan, lengths[i])) { + kfree(desc); + return NULL; + } + + dsg = axi_dmac_fill_linear_sg(chan, direction, addrs[i], 1, + lengths[i], dsg); + } + + desc->cyclic = false; + + return vchan_tx_prep(&chan->vchan, &desc->vdesc, flags); +} + static struct dma_async_tx_descriptor *axi_dmac_prep_slave_sg( struct dma_chan *c, struct scatterlist *sgl, unsigned int sg_len, enum dma_transfer_direction direction, @@ -958,6 +998,7 @@ static int axi_dmac_probe(struct platform_device *pdev) dma_dev->device_tx_status = dma_cookie_status; dma_dev->device_issue_pending = axi_dmac_issue_pending; dma_dev->device_prep_slave_sg = axi_dmac_prep_slave_sg; + dma_dev->device_prep_slave_dma_array = axi_dmac_prep_slave_dma_array; dma_dev->device_prep_dma_cyclic = axi_dmac_prep_dma_cyclic; dma_dev->device_prep_interleaved_dma = axi_dmac_prep_interleaved; dma_dev->device_terminate_all = axi_dmac_terminate_all; From patchwork Mon Apr 3 15:47:52 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Cercueil X-Patchwork-Id: 78600 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp2402920vqo; Mon, 3 Apr 2023 08:53:44 -0700 (PDT) X-Google-Smtp-Source: AKy350alWBy3moHyxYvmYAcJmrMLb5AblUjTxfHwJpmW1ko4iFxUYHhxhUubVyJLTEakdPeh4xFq X-Received: by 2002:aa7:c382:0:b0:4fb:59bb:ce71 with SMTP id k2-20020aa7c382000000b004fb59bbce71mr32463468edq.36.1680537224533; Mon, 03 Apr 2023 08:53:44 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1680537224; cv=none; d=google.com; s=arc-20160816; b=mNlizzPCL5Y7G7eyXNRo/jELKTdnC9mEL2gJUjZR3Y7UMvDYkBsyNBkKrF1OSp+799 wVQY/EBO+oTICl9eapqoAkVnatDxhCp0o7BbXmlMMg3JNdDdXukYr0fdNpFZnpdsf7Kp wDGLyI4WwIUZxiaIuTlEEZFdEEeKybjpMooy4NQuLscPPV7D0kjy9TUICf2njYGFTmOr YVWolr4jCCDkBFxzJ5pb5Xsbu7fgMWNROSOGLxNgjHabdsSZgu2bbCXIFGP4zkgGBibN PeEBT35ExwyOtmGH0IkNioTDPZ+yaVcvFnhANsWGx8jYJWq2n74hhTaWAcg9XW6EqHsv NbwQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=k9gemWsc7PvO9DQl/cvzAOKCJcJzw7kdycHeRQrlu/8=; b=DwJo6DtcW7P+YO7wsqsM4ylsgxacsRBF+HpRBKFNhDhmImES1MQqKY/xfTwnBiQl1v GzvNRVdzCWXJzmElDFVcRdQsK16dNATjxEUpSbsXDN4GaXUaFOeqd+adCQduMyL+/rAa bjLmAOnvEHruVdUjbi7wfeafX1WQXg//lBCMFvD5Sy67sb+WYVQXoABsGbvK84RtS7AH J/gQg7kvPnr92As9yUGMyhRjhWi8Aqe1Z7a9eA9h++sTfpHIC1hieXy5yuenB4AXn4qs DleFCMs3q0/wlduu5YrJ1llvxXuoccjQWTRAL/6Rr3dOYl2+YAwNPmcTKbH8Ixowm1sm Ih1A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@crapouillou.net header.s=mail header.b=HuM2vzD5; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=crapouillou.net Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id p1-20020a170906a00100b00947702d0ba2si8093533ejy.983.2023.04.03.08.52.56; Mon, 03 Apr 2023 08:53:44 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@crapouillou.net header.s=mail header.b=HuM2vzD5; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=crapouillou.net Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233034AbjDCPu7 (ORCPT + 99 others); Mon, 3 Apr 2023 11:50:59 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60060 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232761AbjDCPuh (ORCPT ); Mon, 3 Apr 2023 11:50:37 -0400 Received: from aposti.net (aposti.net [89.234.176.197]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0F00D3C27; Mon, 3 Apr 2023 08:50:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=crapouillou.net; s=mail; t=1680536893; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=k9gemWsc7PvO9DQl/cvzAOKCJcJzw7kdycHeRQrlu/8=; b=HuM2vzD5LdtfHrGyBpDU0yd7VnO9Jmb5TbLiOEoPnhOvazR8pGNAkup+i2cEnmVBjOjuTC SflHyhly7eP+f7lAovS9SzHcasOHuL1bFwaNetD7uMOGmgTsP6X5ZDOiMTAiYTa2iwRWrA nGYblAcEFIKI3azdg2TU3aiky2cgi20= From: Paul Cercueil To: Jonathan Cameron , Lars-Peter Clausen , Vinod Koul , Michael Hennerich , =?utf-8?q?Nuno_S=C3=A1?= , Sumit Semwal , =?utf-8?q?Christian_K=C3=B6nig?= Cc: linux-kernel@vger.kernel.org, dmaengine@vger.kernel.org, linux-iio@vger.kernel.org, linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org, Paul Cercueil Subject: [PATCH v3 03/11] iio: buffer-dma: Get rid of outgoing queue Date: Mon, 3 Apr 2023 17:47:52 +0200 Message-Id: <20230403154800.215924-4-paul@crapouillou.net> In-Reply-To: <20230403154800.215924-1-paul@crapouillou.net> References: <20230403154800.215924-1-paul@crapouillou.net> MIME-Version: 1.0 X-Spam: Yes X-Spam-Status: No, score=-0.2 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_PASS,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1762171000472633579?= X-GMAIL-MSGID: =?utf-8?q?1762171000472633579?= The buffer-dma code was using two queues, incoming and outgoing, to manage the state of the blocks in use. While this totally works, it adds some complexity to the code, especially since the code only manages 2 blocks. It is much easier to just check each block's state manually, and keep a counter for the next block to dequeue. Since the new DMABUF based API wouldn't use the outgoing queue anyway, getting rid of it now makes the upcoming changes simpler. With this change, the IIO_BLOCK_STATE_DEQUEUED is now useless, and can be removed. Signed-off-by: Paul Cercueil --- v2: - Only remove the outgoing queue, and keep the incoming queue, as we want the buffer to start streaming data as soon as it is enabled. - Remove IIO_BLOCK_STATE_DEQUEUED, since it is now functionally the same as IIO_BLOCK_STATE_DONE. --- drivers/iio/buffer/industrialio-buffer-dma.c | 44 ++++++++++---------- include/linux/iio/buffer-dma.h | 7 ++-- 2 files changed, 26 insertions(+), 25 deletions(-) diff --git a/drivers/iio/buffer/industrialio-buffer-dma.c b/drivers/iio/buffer/industrialio-buffer-dma.c index d348af8b9705..1fc91467d1aa 100644 --- a/drivers/iio/buffer/industrialio-buffer-dma.c +++ b/drivers/iio/buffer/industrialio-buffer-dma.c @@ -179,7 +179,7 @@ static struct iio_dma_buffer_block *iio_dma_buffer_alloc_block( } block->size = size; - block->state = IIO_BLOCK_STATE_DEQUEUED; + block->state = IIO_BLOCK_STATE_DONE; block->queue = queue; INIT_LIST_HEAD(&block->head); kref_init(&block->kref); @@ -191,16 +191,8 @@ static struct iio_dma_buffer_block *iio_dma_buffer_alloc_block( static void _iio_dma_buffer_block_done(struct iio_dma_buffer_block *block) { - struct iio_dma_buffer_queue *queue = block->queue; - - /* - * The buffer has already been freed by the application, just drop the - * reference. - */ - if (block->state != IIO_BLOCK_STATE_DEAD) { + if (block->state != IIO_BLOCK_STATE_DEAD) block->state = IIO_BLOCK_STATE_DONE; - list_add_tail(&block->head, &queue->outgoing); - } } /** @@ -261,7 +253,6 @@ static bool iio_dma_block_reusable(struct iio_dma_buffer_block *block) * not support abort and has not given back the block yet. */ switch (block->state) { - case IIO_BLOCK_STATE_DEQUEUED: case IIO_BLOCK_STATE_QUEUED: case IIO_BLOCK_STATE_DONE: return true; @@ -317,7 +308,6 @@ int iio_dma_buffer_request_update(struct iio_buffer *buffer) * dead. This means we can reset the lists without having to fear * corrution. */ - INIT_LIST_HEAD(&queue->outgoing); spin_unlock_irq(&queue->list_lock); INIT_LIST_HEAD(&queue->incoming); @@ -456,14 +446,20 @@ static struct iio_dma_buffer_block *iio_dma_buffer_dequeue( struct iio_dma_buffer_queue *queue) { struct iio_dma_buffer_block *block; + unsigned int idx; spin_lock_irq(&queue->list_lock); - block = list_first_entry_or_null(&queue->outgoing, struct - iio_dma_buffer_block, head); - if (block != NULL) { - list_del(&block->head); - block->state = IIO_BLOCK_STATE_DEQUEUED; + + idx = queue->fileio.next_dequeue; + block = queue->fileio.blocks[idx]; + + if (block->state == IIO_BLOCK_STATE_DONE) { + idx = (idx + 1) % ARRAY_SIZE(queue->fileio.blocks); + queue->fileio.next_dequeue = idx; + } else { + block = NULL; } + spin_unlock_irq(&queue->list_lock); return block; @@ -539,6 +535,7 @@ size_t iio_dma_buffer_data_available(struct iio_buffer *buf) struct iio_dma_buffer_queue *queue = iio_buffer_to_queue(buf); struct iio_dma_buffer_block *block; size_t data_available = 0; + unsigned int i; /* * For counting the available bytes we'll use the size of the block not @@ -552,8 +549,15 @@ size_t iio_dma_buffer_data_available(struct iio_buffer *buf) data_available += queue->fileio.active_block->size; spin_lock_irq(&queue->list_lock); - list_for_each_entry(block, &queue->outgoing, head) - data_available += block->size; + + for (i = 0; i < ARRAY_SIZE(queue->fileio.blocks); i++) { + block = queue->fileio.blocks[i]; + + if (block != queue->fileio.active_block + && block->state == IIO_BLOCK_STATE_DONE) + data_available += block->size; + } + spin_unlock_irq(&queue->list_lock); mutex_unlock(&queue->lock); @@ -617,7 +621,6 @@ int iio_dma_buffer_init(struct iio_dma_buffer_queue *queue, queue->ops = ops; INIT_LIST_HEAD(&queue->incoming); - INIT_LIST_HEAD(&queue->outgoing); mutex_init(&queue->lock); spin_lock_init(&queue->list_lock); @@ -645,7 +648,6 @@ void iio_dma_buffer_exit(struct iio_dma_buffer_queue *queue) continue; queue->fileio.blocks[i]->state = IIO_BLOCK_STATE_DEAD; } - INIT_LIST_HEAD(&queue->outgoing); spin_unlock_irq(&queue->list_lock); INIT_LIST_HEAD(&queue->incoming); diff --git a/include/linux/iio/buffer-dma.h b/include/linux/iio/buffer-dma.h index 6564bdcdac66..18d3702fa95d 100644 --- a/include/linux/iio/buffer-dma.h +++ b/include/linux/iio/buffer-dma.h @@ -19,14 +19,12 @@ struct device; /** * enum iio_block_state - State of a struct iio_dma_buffer_block - * @IIO_BLOCK_STATE_DEQUEUED: Block is not queued * @IIO_BLOCK_STATE_QUEUED: Block is on the incoming queue * @IIO_BLOCK_STATE_ACTIVE: Block is currently being processed by the DMA * @IIO_BLOCK_STATE_DONE: Block is on the outgoing queue * @IIO_BLOCK_STATE_DEAD: Block has been marked as to be freed */ enum iio_block_state { - IIO_BLOCK_STATE_DEQUEUED, IIO_BLOCK_STATE_QUEUED, IIO_BLOCK_STATE_ACTIVE, IIO_BLOCK_STATE_DONE, @@ -73,12 +71,15 @@ struct iio_dma_buffer_block { * @active_block: Block being used in read() * @pos: Read offset in the active block * @block_size: Size of each block + * @next_dequeue: index of next block that will be dequeued */ struct iio_dma_buffer_queue_fileio { struct iio_dma_buffer_block *blocks[2]; struct iio_dma_buffer_block *active_block; size_t pos; size_t block_size; + + unsigned int next_dequeue; }; /** @@ -93,7 +94,6 @@ struct iio_dma_buffer_queue_fileio { * list and typically also a list of active blocks in the part that handles * the DMA controller * @incoming: List of buffers on the incoming queue - * @outgoing: List of buffers on the outgoing queue * @active: Whether the buffer is currently active * @fileio: FileIO state */ @@ -105,7 +105,6 @@ struct iio_dma_buffer_queue { struct mutex lock; spinlock_t list_lock; struct list_head incoming; - struct list_head outgoing; bool active; From patchwork Mon Apr 3 15:47:53 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Cercueil X-Patchwork-Id: 78604 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp2413061vqo; Mon, 3 Apr 2023 09:06:29 -0700 (PDT) X-Google-Smtp-Source: AKy350ZE5rgyFA0EmnCZPyfwyi/OuSfaU/dpGyq3Jeuk9KnIdBar8iPl+rXPPCpWO4bKFqXYXDWN X-Received: by 2002:a05:6a20:63a3:b0:e3:8710:6848 with SMTP id m35-20020a056a2063a300b000e387106848mr14558186pzg.41.1680537988961; Mon, 03 Apr 2023 09:06:28 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1680537988; cv=none; d=google.com; s=arc-20160816; b=huQInMN8+bSTM6ZgIY9QpCbLnEJ1jK47/O+MRmXTmtZtBKqgW/KBIV5S0LH8rGs7q5 J68ppfYbNDLeP5QBa3axARtxzlUCohxlq0zLJVKsLONkMuX0gCCIlQ1hiuGygpoWGpxn VO1xRKp9Awzkiaoc1sBZ3/HmurpKygH+rgqHR7/75859pTVs3aSaD10ApH5V8PW1X1ln 5+N6t9oSY0ACec1pob33ar15RCysSTn2B7FSoqORiXfgEqOWhm3ZMfHXPG0lN4nSZJ8K wn+sAo8DUbJtUlWCLnyo/qWmIEsuWvmksTBL2jnZrzo73wG1cUSBN+nVrig7x6YNynY7 ee6Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=HdiZb0JavkoDqxk9mA7rDah7yJ9YxJPEz9HPH/6qmHo=; b=zfNsNKjgqQ6gnylsrbrxSxpRC1qpq6xBXV9TWa3AHilp1owBkU+k1odDHyraBrIyD+ zz4lI4ybX2ScygtU1+3pvoBRVeUE5iIl3QzpDC0OYqKHhVA+FzbxKwElEvqwf7uHOjh8 FrX9AiubjlH132mqDerNuGYvIYoS1IB/AykC8JdXHvFo/HnrDQ9XIeQqfna3JcSXM3ta FcKqGMI/32cSfQmeXl9Sa6n5RBFuHaHafebL2+2Wa8rpAfHYZPhrKsBzhT8nHXdHejHl NbJr4wlQ/d73W1YEpQhOBzfIgu4ojwG7I7ZbEPj4P2l3FN2Pj6gq2UcfK4ZVYqQ1QLYM eICQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@crapouillou.net header.s=mail header.b=lV75bMrv; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=crapouillou.net Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id w24-20020a634758000000b00502effd3bb9si5533635pgk.521.2023.04.03.09.06.12; Mon, 03 Apr 2023 09:06:28 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@crapouillou.net header.s=mail header.b=lV75bMrv; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=crapouillou.net Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232987AbjDCPvi (ORCPT + 99 others); Mon, 3 Apr 2023 11:51:38 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60056 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232869AbjDCPvP (ORCPT ); Mon, 3 Apr 2023 11:51:15 -0400 Received: from aposti.net (aposti.net [89.234.176.197]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 96FB244BD; Mon, 3 Apr 2023 08:50:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=crapouillou.net; s=mail; t=1680536894; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=HdiZb0JavkoDqxk9mA7rDah7yJ9YxJPEz9HPH/6qmHo=; b=lV75bMrvTMtRgSJsvgQi6Qg+qk35iFkofgaGdxueE3AQcWMW7BGe+wJdrrNMImWO4C4SQY W6qWht6ZOwgiQZ/ieAci8UfKh2SO8uCmG2Tf58t7NHz4UCyx8HytGFO1LZww0RXz/K97+a DHEF4b2okfkraHNADpKeIjII5iH/DLc= From: Paul Cercueil To: Jonathan Cameron , Lars-Peter Clausen , Vinod Koul , Michael Hennerich , =?utf-8?q?Nuno_S=C3=A1?= , Sumit Semwal , =?utf-8?q?Christian_K=C3=B6nig?= Cc: linux-kernel@vger.kernel.org, dmaengine@vger.kernel.org, linux-iio@vger.kernel.org, linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org, Paul Cercueil , Alexandru Ardelean Subject: [PATCH v3 04/11] iio: buffer-dma: Enable buffer write support Date: Mon, 3 Apr 2023 17:47:53 +0200 Message-Id: <20230403154800.215924-5-paul@crapouillou.net> In-Reply-To: <20230403154800.215924-1-paul@crapouillou.net> References: <20230403154800.215924-1-paul@crapouillou.net> MIME-Version: 1.0 X-Spam: Yes X-Spam-Status: No, score=-0.2 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_PASS,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1762171802031699121?= X-GMAIL-MSGID: =?utf-8?q?1762171802031699121?= Adding write support to the buffer-dma code is easy - the write() function basically needs to do the exact same thing as the read() function: dequeue a block, read or write the data, enqueue the block when entirely processed. Therefore, the iio_buffer_dma_read() and the new iio_buffer_dma_write() now both call a function iio_buffer_dma_io(), which will perform this task. The .space_available() callback can return the exact same value as the .data_available() callback for input buffers, since in both cases we count the exact same thing (the number of bytes in each available block). Note that we preemptively reset block->bytes_used to the buffer's size in iio_dma_buffer_request_update(), as in the future the iio_dma_buffer_enqueue() function won't reset it. Signed-off-by: Paul Cercueil Reviewed-by: Alexandru Ardelean --- v2: - Fix block->state not being reset in iio_dma_buffer_request_update() for output buffers. - Only update block->bytes_used once and add a comment about why we update it. - Add a comment about why we're setting a different state for output buffers in iio_dma_buffer_request_update() - Remove useless cast to bool (!!) in iio_dma_buffer_io() v3: - Reorganize arguments to iio_dma_buffer_io() - Change 'is_write' argument to 'is_from_user' - Change (__force char *) to (__force __user char *), in iio_dma_buffer_write(), since we only want to drop the "const". --- drivers/iio/buffer/industrialio-buffer-dma.c | 89 ++++++++++++++++---- include/linux/iio/buffer-dma.h | 7 ++ 2 files changed, 80 insertions(+), 16 deletions(-) diff --git a/drivers/iio/buffer/industrialio-buffer-dma.c b/drivers/iio/buffer/industrialio-buffer-dma.c index 1fc91467d1aa..86eced458236 100644 --- a/drivers/iio/buffer/industrialio-buffer-dma.c +++ b/drivers/iio/buffer/industrialio-buffer-dma.c @@ -195,6 +195,18 @@ static void _iio_dma_buffer_block_done(struct iio_dma_buffer_block *block) block->state = IIO_BLOCK_STATE_DONE; } +static void iio_dma_buffer_queue_wake(struct iio_dma_buffer_queue *queue) +{ + __poll_t flags; + + if (queue->buffer.direction == IIO_BUFFER_DIRECTION_IN) + flags = EPOLLIN | EPOLLRDNORM; + else + flags = EPOLLOUT | EPOLLWRNORM; + + wake_up_interruptible_poll(&queue->buffer.pollq, flags); +} + /** * iio_dma_buffer_block_done() - Indicate that a block has been completed * @block: The completed block @@ -212,7 +224,7 @@ void iio_dma_buffer_block_done(struct iio_dma_buffer_block *block) spin_unlock_irqrestore(&queue->list_lock, flags); iio_buffer_block_put_atomic(block); - wake_up_interruptible_poll(&queue->buffer.pollq, EPOLLIN | EPOLLRDNORM); + iio_dma_buffer_queue_wake(queue); } EXPORT_SYMBOL_GPL(iio_dma_buffer_block_done); @@ -241,7 +253,7 @@ void iio_dma_buffer_block_list_abort(struct iio_dma_buffer_queue *queue, } spin_unlock_irqrestore(&queue->list_lock, flags); - wake_up_interruptible_poll(&queue->buffer.pollq, EPOLLIN | EPOLLRDNORM); + iio_dma_buffer_queue_wake(queue); } EXPORT_SYMBOL_GPL(iio_dma_buffer_block_list_abort); @@ -335,8 +347,24 @@ int iio_dma_buffer_request_update(struct iio_buffer *buffer) queue->fileio.blocks[i] = block; } - block->state = IIO_BLOCK_STATE_QUEUED; - list_add_tail(&block->head, &queue->incoming); + /* + * block->bytes_used may have been modified previously, e.g. by + * iio_dma_buffer_block_list_abort(). Reset it here to the + * block's so that iio_dma_buffer_io() will work. + */ + block->bytes_used = block->size; + + /* + * If it's an input buffer, mark the block as queued, and + * iio_dma_buffer_enable() will submit it. Otherwise mark it as + * done, which means it's ready to be dequeued. + */ + if (queue->buffer.direction == IIO_BUFFER_DIRECTION_IN) { + block->state = IIO_BLOCK_STATE_QUEUED; + list_add_tail(&block->head, &queue->incoming); + } else { + block->state = IIO_BLOCK_STATE_DONE; + } } out_unlock: @@ -465,20 +493,12 @@ static struct iio_dma_buffer_block *iio_dma_buffer_dequeue( return block; } -/** - * iio_dma_buffer_read() - DMA buffer read callback - * @buffer: Buffer to read form - * @n: Number of bytes to read - * @user_buffer: Userspace buffer to copy the data to - * - * Should be used as the read callback for iio_buffer_access_ops - * struct for DMA buffers. - */ -int iio_dma_buffer_read(struct iio_buffer *buffer, size_t n, - char __user *user_buffer) +static int iio_dma_buffer_io(struct iio_buffer *buffer, size_t n, + char __user *user_buffer, bool is_from_user) { struct iio_dma_buffer_queue *queue = iio_buffer_to_queue(buffer); struct iio_dma_buffer_block *block; + void *addr; int ret; if (n < buffer->bytes_per_datum) @@ -501,8 +521,13 @@ int iio_dma_buffer_read(struct iio_buffer *buffer, size_t n, n = rounddown(n, buffer->bytes_per_datum); if (n > block->bytes_used - queue->fileio.pos) n = block->bytes_used - queue->fileio.pos; + addr = block->vaddr + queue->fileio.pos; - if (copy_to_user(user_buffer, block->vaddr + queue->fileio.pos, n)) { + if (is_from_user) + ret = copy_from_user(addr, user_buffer, n); + else + ret = copy_to_user(user_buffer, addr, n); + if (ret) { ret = -EFAULT; goto out_unlock; } @@ -521,8 +546,40 @@ int iio_dma_buffer_read(struct iio_buffer *buffer, size_t n, return ret; } + +/** + * iio_dma_buffer_read() - DMA buffer read callback + * @buffer: Buffer to read form + * @n: Number of bytes to read + * @user_buffer: Userspace buffer to copy the data to + * + * Should be used as the read callback for iio_buffer_access_ops + * struct for DMA buffers. + */ +int iio_dma_buffer_read(struct iio_buffer *buffer, size_t n, + char __user *user_buffer) +{ + return iio_dma_buffer_io(buffer, n, user_buffer, false); +} EXPORT_SYMBOL_GPL(iio_dma_buffer_read); +/** + * iio_dma_buffer_write() - DMA buffer write callback + * @buffer: Buffer to read form + * @n: Number of bytes to read + * @user_buffer: Userspace buffer to copy the data from + * + * Should be used as the write callback for iio_buffer_access_ops + * struct for DMA buffers. + */ +int iio_dma_buffer_write(struct iio_buffer *buffer, size_t n, + const char __user *user_buffer) +{ + return iio_dma_buffer_io(buffer, n, + (__force __user char *)user_buffer, true); +} +EXPORT_SYMBOL_GPL(iio_dma_buffer_write); + /** * iio_dma_buffer_data_available() - DMA buffer data_available callback * @buf: Buffer to check for data availability diff --git a/include/linux/iio/buffer-dma.h b/include/linux/iio/buffer-dma.h index 18d3702fa95d..490b93f76fa8 100644 --- a/include/linux/iio/buffer-dma.h +++ b/include/linux/iio/buffer-dma.h @@ -132,6 +132,8 @@ int iio_dma_buffer_disable(struct iio_buffer *buffer, struct iio_dev *indio_dev); int iio_dma_buffer_read(struct iio_buffer *buffer, size_t n, char __user *user_buffer); +int iio_dma_buffer_write(struct iio_buffer *buffer, size_t n, + const char __user *user_buffer); size_t iio_dma_buffer_data_available(struct iio_buffer *buffer); int iio_dma_buffer_set_bytes_per_datum(struct iio_buffer *buffer, size_t bpd); int iio_dma_buffer_set_length(struct iio_buffer *buffer, unsigned int length); @@ -142,4 +144,9 @@ int iio_dma_buffer_init(struct iio_dma_buffer_queue *queue, void iio_dma_buffer_exit(struct iio_dma_buffer_queue *queue); void iio_dma_buffer_release(struct iio_dma_buffer_queue *queue); +static inline size_t iio_dma_buffer_space_available(struct iio_buffer *buffer) +{ + return iio_dma_buffer_data_available(buffer); +} + #endif From patchwork Mon Apr 3 15:47:54 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Cercueil X-Patchwork-Id: 78612 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp2416114vqo; Mon, 3 Apr 2023 09:10:20 -0700 (PDT) X-Google-Smtp-Source: AKy350Y24u8tL8HHpphnSo+pjU8tXYgNsElQq6X4E68OO8uZNwvbzn24uAmNuQ/JrN3Lzv0Zc5f+ X-Received: by 2002:a17:90a:5105:b0:234:a88e:d67e with SMTP id t5-20020a17090a510500b00234a88ed67emr41078717pjh.34.1680538220555; Mon, 03 Apr 2023 09:10:20 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1680538220; cv=none; d=google.com; s=arc-20160816; b=CBu0q/C8LB8N+5AyXecDYu64UYXq1owuVfmUKS7lT6hbXPUJ+hVssYlFOLvAqRi4is jO6mRQjHPbAZEvzeuOWpW/3tjTcL5PTb+w6iuNQyvEihFu6i9wQUZQEWUbXaRuBZxeRv erAU4n/RfCneoF9a6wO2QspW2/T4hXDyRiFT7UPgqWvTsHmfqY9NAXhL6Wuxjfy2yG0O 7607S9EK9iu9bm505ILAgNq2EGpc1KBWu4OhbP/IiBOCN2MMy6H2OahnlIB6BoSE+Esm 9jDp4hMKgGKLibB2ld+HorUI7JVxNi2w1TXFG6AFJ8TzTB1Hf/EJx/8AFrqIKDyyMDNf Qx/Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=1izcu1WFEt9b1dtaujjpu20y6Ear8HIPhk9DR+eEyjM=; b=naHsilvcrs6/1zUdxvMm8NCyiqry/pz0+Coog/L0P1YONTqyzr/LCbIZ6uLqEIEqn6 5g9xYApHnMdUVMgGT2lCTBlg7u7xlZAPVZLf4O4KyzsWzj4MSbUvwn9ye5CVaJJh0OYJ 09E+bcVjTOL0vegaU+UHjUAY26e9y7KBl51iKwQIFa1g5A6y/Z9tSezcVjmfE//NDfwD OAus+UIFf/T+i//EIjqCGeahMX/I6UzkK6d+gfhPRtVdxSbDiezkNmwDNB9zr6w4HIB4 xzqA/k/UgrxCXAOl/qULn8uJESO/Kvdp0/BT0BpJe7vgAfQR/87+uHb9R66qAQYVeFnc 4QXw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@crapouillou.net header.s=mail header.b=ljgwlqlO; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=crapouillou.net Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id x19-20020a17090aca1300b00233dc8b7c82si6382461pjt.54.2023.04.03.09.10.08; Mon, 03 Apr 2023 09:10:20 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@crapouillou.net header.s=mail header.b=ljgwlqlO; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=crapouillou.net Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232761AbjDCPwW (ORCPT + 99 others); Mon, 3 Apr 2023 11:52:22 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60042 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231450AbjDCPwF (ORCPT ); Mon, 3 Apr 2023 11:52:05 -0400 Received: from aposti.net (aposti.net [89.234.176.197]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3D1B8E61; Mon, 3 Apr 2023 08:51:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=crapouillou.net; s=mail; t=1680536896; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=1izcu1WFEt9b1dtaujjpu20y6Ear8HIPhk9DR+eEyjM=; b=ljgwlqlOwZPST5STP6Sk4GHJKbrMKG5ReGJabr5s0M0POrNRwMlcE5iLbGkjAlBWFz08+P mzOQJUEgkqfIHSpAqJ2U48K6q3p9wQ4qBCRd2985d+9uzvma4lGF12cT+b0sXnwsdiV9Y9 YSOUIkyiHi6PxtZYIDww20BXOKiAr5s= From: Paul Cercueil To: Jonathan Cameron , Lars-Peter Clausen , Vinod Koul , Michael Hennerich , =?utf-8?q?Nuno_S=C3=A1?= , Sumit Semwal , =?utf-8?q?Christian_K=C3=B6nig?= Cc: linux-kernel@vger.kernel.org, dmaengine@vger.kernel.org, linux-iio@vger.kernel.org, linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org, Paul Cercueil , Alexandru Ardelean Subject: [PATCH v3 05/11] iio: buffer-dmaengine: Support specifying buffer direction Date: Mon, 3 Apr 2023 17:47:54 +0200 Message-Id: <20230403154800.215924-6-paul@crapouillou.net> In-Reply-To: <20230403154800.215924-1-paul@crapouillou.net> References: <20230403154800.215924-1-paul@crapouillou.net> MIME-Version: 1.0 X-Spam: Yes X-Spam-Status: No, score=-0.2 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_PASS,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1762172044885585749?= X-GMAIL-MSGID: =?utf-8?q?1762172044885585749?= Update the devm_iio_dmaengine_buffer_setup() function to support specifying the buffer direction. Update the iio_dmaengine_buffer_submit() function to handle input buffers as well as output buffers. Signed-off-by: Paul Cercueil Reviewed-by: Alexandru Ardelean --- drivers/iio/adc/adi-axi-adc.c | 3 ++- .../buffer/industrialio-buffer-dmaengine.c | 24 +++++++++++++++---- include/linux/iio/buffer-dmaengine.h | 5 +++- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/drivers/iio/adc/adi-axi-adc.c b/drivers/iio/adc/adi-axi-adc.c index e8a8ea4140f1..d33574b5417a 100644 --- a/drivers/iio/adc/adi-axi-adc.c +++ b/drivers/iio/adc/adi-axi-adc.c @@ -114,7 +114,8 @@ static int adi_axi_adc_config_dma_buffer(struct device *dev, dma_name = "rx"; return devm_iio_dmaengine_buffer_setup(indio_dev->dev.parent, - indio_dev, dma_name); + indio_dev, dma_name, + IIO_BUFFER_DIRECTION_IN); } static int adi_axi_adc_read_raw(struct iio_dev *indio_dev, diff --git a/drivers/iio/buffer/industrialio-buffer-dmaengine.c b/drivers/iio/buffer/industrialio-buffer-dmaengine.c index 5f85ba38e6f6..592d2aa9044c 100644 --- a/drivers/iio/buffer/industrialio-buffer-dmaengine.c +++ b/drivers/iio/buffer/industrialio-buffer-dmaengine.c @@ -64,14 +64,25 @@ static int iio_dmaengine_buffer_submit_block(struct iio_dma_buffer_queue *queue, struct dmaengine_buffer *dmaengine_buffer = iio_buffer_to_dmaengine_buffer(&queue->buffer); struct dma_async_tx_descriptor *desc; + enum dma_transfer_direction dma_dir; + size_t max_size; dma_cookie_t cookie; - block->bytes_used = min(block->size, dmaengine_buffer->max_size); - block->bytes_used = round_down(block->bytes_used, - dmaengine_buffer->align); + max_size = min(block->size, dmaengine_buffer->max_size); + max_size = round_down(max_size, dmaengine_buffer->align); + + if (queue->buffer.direction == IIO_BUFFER_DIRECTION_IN) { + block->bytes_used = max_size; + dma_dir = DMA_DEV_TO_MEM; + } else { + dma_dir = DMA_MEM_TO_DEV; + } + + if (!block->bytes_used || block->bytes_used > max_size) + return -EINVAL; desc = dmaengine_prep_slave_single(dmaengine_buffer->chan, - block->phys_addr, block->bytes_used, DMA_DEV_TO_MEM, + block->phys_addr, block->bytes_used, dma_dir, DMA_PREP_INTERRUPT); if (!desc) return -ENOMEM; @@ -275,7 +286,8 @@ static struct iio_buffer *devm_iio_dmaengine_buffer_alloc(struct device *dev, */ int devm_iio_dmaengine_buffer_setup(struct device *dev, struct iio_dev *indio_dev, - const char *channel) + const char *channel, + enum iio_buffer_direction dir) { struct iio_buffer *buffer; @@ -286,6 +298,8 @@ int devm_iio_dmaengine_buffer_setup(struct device *dev, indio_dev->modes |= INDIO_BUFFER_HARDWARE; + buffer->direction = dir; + return iio_device_attach_buffer(indio_dev, buffer); } EXPORT_SYMBOL_GPL(devm_iio_dmaengine_buffer_setup); diff --git a/include/linux/iio/buffer-dmaengine.h b/include/linux/iio/buffer-dmaengine.h index 5c355be89814..538d0479cdd6 100644 --- a/include/linux/iio/buffer-dmaengine.h +++ b/include/linux/iio/buffer-dmaengine.h @@ -7,11 +7,14 @@ #ifndef __IIO_DMAENGINE_H__ #define __IIO_DMAENGINE_H__ +#include + struct iio_dev; struct device; int devm_iio_dmaengine_buffer_setup(struct device *dev, struct iio_dev *indio_dev, - const char *channel); + const char *channel, + enum iio_buffer_direction dir); #endif From patchwork Mon Apr 3 15:47:55 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Cercueil X-Patchwork-Id: 78615 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp2416555vqo; Mon, 3 Apr 2023 09:10:55 -0700 (PDT) X-Google-Smtp-Source: AKy350aasxP73lLCgOBk9MscFLt/Mo24gxpz5ZL255vFwSQjTkE8H4Tz/Kr0bYFX+emKyneWuEFb X-Received: by 2002:a17:90b:38c8:b0:23f:81ac:80b8 with SMTP id nn8-20020a17090b38c800b0023f81ac80b8mr41063456pjb.40.1680538255192; Mon, 03 Apr 2023 09:10:55 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1680538255; cv=none; d=google.com; s=arc-20160816; b=wzQh0cPMVtefJ+H1BCU32LMI5bJ4nrgqk23wsX6IkrFJymeGNViyA0jyfAPkEbCl2y hdA0ZAl+UF1FwBXo7SHB4/iD2wYLG3oVbPD3eCMsVSusMzNWe/S8ODWtZ6zV0Wl61jEi uhtV2k2iv7vLwQMVeKyFUxvU05DuRQkL90FGA5MDQ8Qf3lcjnjswqyH+3hYglneGcuce TPDlrS7Eboh4g3dCJewYTMcKPBqVo+MLSmy5d6061CD5LTSw77Mwd9P+/Q8W7OXpoTVY ANSuVVu3M3PVoQg3E1Jr4CXWyP2U1Wj834r9Fthh8Ct9hbDES4bHGGLq3SNenaBthGn2 2wow== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=uVat1y3nUPAGrRVYX0c87LmQAN3Bo767mwQaGSvhkEU=; b=1DYw0wvQ77TAR0SF3FUfcAHo31L/e06Wh4af+kv9rfJdKNf3FYpCQEdIImJ3ZWuBTW oOt7cY4LFVSISLHKqcDXKbUKd4Jw9u3cVXMwpG7HHrf5BlAOIxJEUf1dkO021xn2QY99 q3ES5pEE67gNP0nrROn/ZQ8Q2/S7ToGeAnrqqL2QbiE3EA3Ta9+GIqYRL63EtXNWnvta R6Ye7QMeRTTjsMcf7DD2AThuQaMhZeLVR8JymCCtYImcy3uDXeYehgBQHyTn+qAyqPpI w36r501OVip7KhQYi2tNYxYC1jrPUDZZBu4qBtnmlL2brI3fcQJHAmiy0XEyC+6G48bH PRjw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@crapouillou.net header.s=mail header.b=FeodDPhq; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=crapouillou.net Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id kk2-20020a17090b4a0200b0022bec273f72si13518448pjb.3.2023.04.03.09.10.41; Mon, 03 Apr 2023 09:10:55 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@crapouillou.net header.s=mail header.b=FeodDPhq; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=crapouillou.net Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233100AbjDCPxz (ORCPT + 99 others); Mon, 3 Apr 2023 11:53:55 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37806 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232212AbjDCPxg (ORCPT ); Mon, 3 Apr 2023 11:53:36 -0400 Received: from aposti.net (aposti.net [89.234.176.197]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C12324209; Mon, 3 Apr 2023 08:53:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=crapouillou.net; s=mail; t=1680536898; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=uVat1y3nUPAGrRVYX0c87LmQAN3Bo767mwQaGSvhkEU=; b=FeodDPhqhSrgCY931wbpHE6ejF5oHVHcNN9LKo1irGAdS332/J9BWW1vxmLi9f6cPCDxUu BJmbaFoOLXJOLPjOx3Glsg+4nu0jshD/V6BZHWfI9pi6vy1psy5D0Q5+tCxIlOulXsLEk6 56bq7XLlenzXWg3DS2+///eQUHm2/HY= From: Paul Cercueil To: Jonathan Cameron , Lars-Peter Clausen , Vinod Koul , Michael Hennerich , =?utf-8?q?Nuno_S=C3=A1?= , Sumit Semwal , =?utf-8?q?Christian_K=C3=B6nig?= Cc: linux-kernel@vger.kernel.org, dmaengine@vger.kernel.org, linux-iio@vger.kernel.org, linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org, Paul Cercueil , Alexandru Ardelean Subject: [PATCH v3 06/11] iio: buffer-dmaengine: Enable write support Date: Mon, 3 Apr 2023 17:47:55 +0200 Message-Id: <20230403154800.215924-7-paul@crapouillou.net> In-Reply-To: <20230403154800.215924-1-paul@crapouillou.net> References: <20230403154800.215924-1-paul@crapouillou.net> MIME-Version: 1.0 X-Spam: Yes X-Spam-Status: No, score=-0.2 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_PASS,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1762172081523969153?= X-GMAIL-MSGID: =?utf-8?q?1762172081523969153?= Use the iio_dma_buffer_write() and iio_dma_buffer_space_available() functions provided by the buffer-dma core, to enable write support in the buffer-dmaengine code. Signed-off-by: Paul Cercueil Reviewed-by: Alexandru Ardelean --- drivers/iio/buffer/industrialio-buffer-dmaengine.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/iio/buffer/industrialio-buffer-dmaengine.c b/drivers/iio/buffer/industrialio-buffer-dmaengine.c index 592d2aa9044c..866c8b84bb24 100644 --- a/drivers/iio/buffer/industrialio-buffer-dmaengine.c +++ b/drivers/iio/buffer/industrialio-buffer-dmaengine.c @@ -123,12 +123,14 @@ static void iio_dmaengine_buffer_release(struct iio_buffer *buf) static const struct iio_buffer_access_funcs iio_dmaengine_buffer_ops = { .read = iio_dma_buffer_read, + .write = iio_dma_buffer_write, .set_bytes_per_datum = iio_dma_buffer_set_bytes_per_datum, .set_length = iio_dma_buffer_set_length, .request_update = iio_dma_buffer_request_update, .enable = iio_dma_buffer_enable, .disable = iio_dma_buffer_disable, .data_available = iio_dma_buffer_data_available, + .space_available = iio_dma_buffer_space_available, .release = iio_dmaengine_buffer_release, .modes = INDIO_BUFFER_HARDWARE, From patchwork Mon Apr 3 15:47:56 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Cercueil X-Patchwork-Id: 78618 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp2417073vqo; Mon, 3 Apr 2023 09:11:37 -0700 (PDT) X-Google-Smtp-Source: AKy350bGyX06xjKN6dVSUdo/rU0oDaHHTe+3VvvWJbcE0bWMLnO6ncugcayMvJmhqAag0S8Uu5jo X-Received: by 2002:a17:903:41c8:b0:19a:7758:e5e6 with SMTP id u8-20020a17090341c800b0019a7758e5e6mr45373774ple.48.1680538297458; Mon, 03 Apr 2023 09:11:37 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1680538297; cv=none; d=google.com; s=arc-20160816; b=hu/Qll6Lo+vr+nc0YZjRPjpWnKi1o/z7xmT9FeLpPk8jDU5cTFvkSxj5M0liOx2zkk ZZA7iNK9bffUxycxhPNAwGHNvHk/+4GPkhwoWAnscbQgFw411Iqsxp2yEH3h6HRjLvLc AlvuswHzfNKU4UDLUZ46y3jSlEGx1KPdszWlyiM86L2SQ8hps69JB5WbYoK5CvPCYV+w Gt4fUm/F6fVoy5mIMMDr0TUrb0TPtaPDYWoFAjitRzant5cbRDuH0nUZDZFGxGgYHWL0 dUjwUE+g9rZy5MkSXdAh1noR/poFelShg5pWqvhHg6rWa4p6ctIiW+ELSdugeG1+U2vf MYwg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=nz7fAmV2pnrsQXoD+Pm7KxzmimP2P/9gJ/rPeNI46aA=; b=yS09NEUz+tQRaLf9o5FtVzIAKcKXv+dtTYOpGnL+a256fjiMuY5EWv+WQAh0PwGHWU xEa9lyz7W9kI9rY7yOkTy1mqNQOvY6JeWebPw9MEqpO6EUyudPD3Kw+dlpd0AHoCEp6A 2/EA6n1M7FRBOHCgZrp4QqRUjgq7ssBzColQsIwZR+urhUFmnEhKJCyHrD1x+UQf2q6i z00L569Xu3gNZU6QDWWR9azRUP/iBqPVGaeo3zEMiITEEZ9WPg9Q/W9aFmc/Iql04Asg 3PHzFtQXByofecfgIGbcHbU8O1yi9y258VKATR7gSgto9fDQiZTF0WPrzaTwlTYpGbq5 6Uaw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@crapouillou.net header.s=mail header.b=HqsAH+p5; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=crapouillou.net Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id kr6-20020a170903080600b0019a74a00baesi5396760plb.87.2023.04.03.09.11.24; Mon, 03 Apr 2023 09:11:37 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@crapouillou.net header.s=mail header.b=HqsAH+p5; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=crapouillou.net Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233130AbjDCPyt (ORCPT + 99 others); Mon, 3 Apr 2023 11:54:49 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41330 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232841AbjDCPyV (ORCPT ); Mon, 3 Apr 2023 11:54:21 -0400 Received: from aposti.net (aposti.net [89.234.176.197]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5EEC63AA9; Mon, 3 Apr 2023 08:53:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=crapouillou.net; s=mail; t=1680536899; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=nz7fAmV2pnrsQXoD+Pm7KxzmimP2P/9gJ/rPeNI46aA=; b=HqsAH+p5v6BE+qZRaoUswP1MfXOIFXLtc+6jkhPXjbKrcpw+1NRONU/W5dPkQVcIc9I+nB otO1GZ2kHVZfgMn2EGZc0Il3mv0+pdsg5rvM/1zA8c2EcGd+YnmvGmyK3iF0Pd8E8lEMIo 19O2WWzsR+0Kf1S5nbS64f0UWCt4di4= From: Paul Cercueil To: Jonathan Cameron , Lars-Peter Clausen , Vinod Koul , Michael Hennerich , =?utf-8?q?Nuno_S=C3=A1?= , Sumit Semwal , =?utf-8?q?Christian_K=C3=B6nig?= Cc: linux-kernel@vger.kernel.org, dmaengine@vger.kernel.org, linux-iio@vger.kernel.org, linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org, Paul Cercueil Subject: [PATCH v3 07/11] iio: core: Add new DMABUF interface infrastructure Date: Mon, 3 Apr 2023 17:47:56 +0200 Message-Id: <20230403154800.215924-8-paul@crapouillou.net> In-Reply-To: <20230403154800.215924-1-paul@crapouillou.net> References: <20230403154800.215924-1-paul@crapouillou.net> MIME-Version: 1.0 X-Spam: Yes X-Spam-Status: No, score=-0.2 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_PASS,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1762172125901359426?= X-GMAIL-MSGID: =?utf-8?q?1762172125901359426?= Add the necessary infrastructure to the IIO core to support a new optional DMABUF based interface. With this new interface, DMABUF objects (externally created) can be attached to a IIO buffer, and subsequently used for data transfer. A userspace application can then use this interface to share DMABUF objects between several interfaces, allowing it to transfer data in a zero-copy fashion, for instance between IIO and the USB stack. The userspace application can also memory-map the DMABUF objects, and access the sample data directly. The advantage of doing this vs. the read() interface is that it avoids an extra copy of the data between the kernel and userspace. This is particularly userful for high-speed devices which produce several megabytes or even gigabytes of data per second. As part of the interface, 3 new IOCTLs have been added: IIO_BUFFER_DMABUF_ATTACH_IOCTL(int fd): Attach the DMABUF object identified by the given file descriptor to the buffer. IIO_BUFFER_DMABUF_DETACH_IOCTL(int fd): Detach the DMABUF object identified by the given file descriptor from the buffer. Note that closing the IIO buffer's file descriptor will automatically detach all previously attached DMABUF objects. IIO_BUFFER_DMABUF_ENQUEUE_IOCTL(struct iio_dmabuf *): Request a data transfer to/from the given DMABUF object. Its file descriptor, as well as the transfer size and flags are provided in the "iio_dmabuf" structure. These three IOCTLs have to be performed on the IIO buffer's file descriptor, obtained using the IIO_BUFFER_GET_FD_IOCTL() ioctl. Signed-off-by: Paul Cercueil --- v2: Only allow the new IOCTLs on the buffer FD created with IIO_BUFFER_GET_FD_IOCTL(). v3: - Get rid of the old IOCTLs. The IIO subsystem does not create or manage DMABUFs anymore, and only attaches/detaches externally created DMABUFs. - Add IIO_BUFFER_DMABUF_CYCLIC to the supported flags. --- drivers/iio/industrialio-buffer.c | 402 ++++++++++++++++++++++++++++++ include/linux/iio/buffer_impl.h | 22 ++ include/uapi/linux/iio/buffer.h | 22 ++ 3 files changed, 446 insertions(+) diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index 80c78bd6bbef..5d88e098b3e7 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -13,10 +13,14 @@ #include #include #include +#include +#include +#include #include #include #include #include +#include #include #include @@ -28,11 +32,41 @@ #include #include +#define DMABUF_ENQUEUE_TIMEOUT_MS 5000 + +struct iio_dma_fence; + +struct iio_dmabuf_priv { + struct list_head entry; + struct kref ref; + + struct iio_buffer *buffer; + struct iio_dma_buffer_block *block; + + u64 context; + spinlock_t lock; + + struct dma_buf_attachment *attach; + struct iio_dma_fence *fence; +}; + +struct iio_dma_fence { + struct dma_fence base; + struct iio_dmabuf_priv *priv; + struct sg_table *sgt; + enum dma_data_direction dir; +}; + static const char * const iio_endian_prefix[] = { [IIO_BE] = "be", [IIO_LE] = "le", }; +static inline struct iio_dma_fence *to_iio_dma_fence(struct dma_fence *fence) +{ + return container_of(fence, struct iio_dma_fence, base); +} + static bool iio_buffer_is_active(struct iio_buffer *buf) { return !list_empty(&buf->buffer_list); @@ -329,6 +363,7 @@ void iio_buffer_init(struct iio_buffer *buffer) { INIT_LIST_HEAD(&buffer->demux_list); INIT_LIST_HEAD(&buffer->buffer_list); + INIT_LIST_HEAD(&buffer->dmabufs); init_waitqueue_head(&buffer->pollq); kref_init(&buffer->ref); if (!buffer->watermark) @@ -1500,14 +1535,55 @@ static void iio_buffer_unregister_legacy_sysfs_groups(struct iio_dev *indio_dev) kfree(iio_dev_opaque->legacy_scan_el_group.attrs); } +static void iio_buffer_dmabuf_release(struct kref *ref) +{ + struct iio_dmabuf_priv *priv = container_of(ref, struct iio_dmabuf_priv, ref); + struct dma_buf_attachment *attach = priv->attach; + struct iio_buffer *buffer = priv->buffer; + struct dma_buf *dmabuf = attach->dmabuf; + + buffer->access->detach_dmabuf(buffer, priv->block); + + dma_buf_detach(attach->dmabuf, attach); + dma_buf_put(dmabuf); + kfree(priv); +} + +void iio_buffer_dmabuf_get(struct dma_buf_attachment *attach) +{ + struct iio_dmabuf_priv *priv = attach->importer_priv; + + kref_get(&priv->ref); +} +EXPORT_SYMBOL_GPL(iio_buffer_dmabuf_get); + +void iio_buffer_dmabuf_put(struct dma_buf_attachment *attach) +{ + struct iio_dmabuf_priv *priv = attach->importer_priv; + + kref_put(&priv->ref, iio_buffer_dmabuf_release); +} +EXPORT_SYMBOL_GPL(iio_buffer_dmabuf_put); + static int iio_buffer_chrdev_release(struct inode *inode, struct file *filep) { struct iio_dev_buffer_pair *ib = filep->private_data; struct iio_dev *indio_dev = ib->indio_dev; struct iio_buffer *buffer = ib->buffer; + struct iio_dmabuf_priv *priv, *tmp; wake_up(&buffer->pollq); + /* Close all attached DMABUFs */ + list_for_each_entry_safe(priv, tmp, &buffer->dmabufs, entry) { + list_del_init(&priv->entry); + iio_buffer_dmabuf_put(priv->attach); + } + + /* TODO: Is it safe? Can "ib" be freed here? */ + if (!list_empty(&buffer->dmabufs)) + dev_warn(&indio_dev->dev, "Buffer FD closed with active transfers\n"); + kfree(ib); clear_bit(IIO_BUSY_BIT_POS, &buffer->flags); iio_device_put(indio_dev); @@ -1515,11 +1591,337 @@ static int iio_buffer_chrdev_release(struct inode *inode, struct file *filep) return 0; } +int iio_dma_resv_lock(struct dma_buf *dmabuf, bool nonblock) +{ + int ret; + + ret = dma_resv_lock_interruptible(dmabuf->resv, NULL); + if (ret) { + if (ret != -EDEADLK) + goto out; + if (nonblock) { + ret = -EBUSY; + goto out; + } + + ret = dma_resv_lock_slow_interruptible(dmabuf->resv, NULL); + } + +out: + return ret; +} +EXPORT_SYMBOL_GPL(iio_dma_resv_lock); + +static struct dma_buf_attachment * +iio_buffer_find_attachment(struct iio_dev *indio_dev, struct dma_buf *dmabuf) +{ + struct dma_buf_attachment *elm, *attach = NULL; + int ret; + + ret = iio_dma_resv_lock(dmabuf, false); + if (ret) + return ERR_PTR(ret); + + list_for_each_entry(elm, &dmabuf->attachments, node) { + if (elm->dev == indio_dev->dev.parent) { + attach = elm; + break; + } + } + + if (attach) + iio_buffer_dmabuf_get(elm); + + dma_resv_unlock(dmabuf->resv); + + return attach ?: ERR_PTR(-EPERM); +} + +static int iio_buffer_attach_dmabuf(struct iio_dev_buffer_pair *ib, + int __user *user_fd) +{ + struct iio_dev *indio_dev = ib->indio_dev; + struct iio_buffer *buffer = ib->buffer; + struct dma_buf_attachment *attach; + struct iio_dmabuf_priv *priv; + struct dma_buf *dmabuf; + int err, fd; + + if (!buffer->access->attach_dmabuf + || !buffer->access->detach_dmabuf + || !buffer->access->enqueue_dmabuf) + return -EPERM; + + if (copy_from_user(&fd, user_fd, sizeof(fd))) + return -EFAULT; + + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + spin_lock_init(&priv->lock); + priv->context = dma_fence_context_alloc(1); + + dmabuf = dma_buf_get(fd); + if (IS_ERR(dmabuf)) { + err = PTR_ERR(dmabuf); + goto err_free_priv; + } + + attach = dma_buf_attach(dmabuf, indio_dev->dev.parent); + if (IS_ERR(attach)) { + err = PTR_ERR(attach); + goto err_dmabuf_put; + } + + kref_init(&priv->ref); + priv->buffer = buffer; + priv->attach = attach; + attach->importer_priv = priv; + + priv->block = buffer->access->attach_dmabuf(buffer, attach); + if (IS_ERR(priv->block)) { + err = PTR_ERR(priv->block); + goto err_dmabuf_detach; + } + + list_add(&priv->entry, &buffer->dmabufs); + + return 0; + +err_dmabuf_detach: + dma_buf_detach(dmabuf, attach); +err_dmabuf_put: + dma_buf_put(dmabuf); +err_free_priv: + kfree(priv); + + return err; +} + +static int iio_buffer_detach_dmabuf(struct iio_dev_buffer_pair *ib, int *user_req) +{ + struct dma_buf_attachment *attach; + struct iio_dmabuf_priv *priv; + struct dma_buf *dmabuf; + int dmabuf_fd, ret = 0; + + if (copy_from_user(&dmabuf_fd, user_req, sizeof(dmabuf_fd))) + return -EFAULT; + + dmabuf = dma_buf_get(dmabuf_fd); + if (IS_ERR(dmabuf)) + return PTR_ERR(dmabuf); + + attach = iio_buffer_find_attachment(ib->indio_dev, dmabuf); + if (IS_ERR(attach)) { + ret = PTR_ERR(attach); + goto out_dmabuf_put; + } + + priv = attach->importer_priv; + list_del_init(&priv->entry); + + iio_buffer_dmabuf_put(attach); + iio_buffer_dmabuf_put(attach); + +out_dmabuf_put: + dma_buf_put(dmabuf); + + return ret; +} + +static const char * +iio_buffer_dma_fence_get_driver_name(struct dma_fence *fence) +{ + return "iio"; +} + +static void iio_buffer_dma_fence_release(struct dma_fence *fence) +{ + struct iio_dma_fence *iio_fence = to_iio_dma_fence(fence); + + kfree(iio_fence); +} + +static const struct dma_fence_ops iio_buffer_dma_fence_ops = { + .get_driver_name = iio_buffer_dma_fence_get_driver_name, + .get_timeline_name = iio_buffer_dma_fence_get_driver_name, + .release = iio_buffer_dma_fence_release, +}; + +static int iio_buffer_enqueue_dmabuf(struct iio_dev_buffer_pair *ib, + struct iio_dmabuf __user *iio_dmabuf_req, + bool nonblock) +{ + struct iio_buffer *buffer = ib->buffer; + struct iio_dmabuf iio_dmabuf; + struct dma_buf_attachment *attach; + struct iio_dmabuf_priv *priv; + enum dma_data_direction dir; + struct iio_dma_fence *fence; + struct dma_buf *dmabuf; + struct sg_table *sgt; + unsigned long timeout; + bool dma_to_ram; + bool cyclic; + int ret; + + if (copy_from_user(&iio_dmabuf, iio_dmabuf_req, sizeof(iio_dmabuf))) + return -EFAULT; + + if (iio_dmabuf.flags & ~IIO_BUFFER_DMABUF_SUPPORTED_FLAGS) + return -EINVAL; + + cyclic = iio_dmabuf.flags & IIO_BUFFER_DMABUF_CYCLIC; + + /* Cyclic flag is only supported on output buffers */ + if (cyclic && buffer->direction != IIO_BUFFER_DIRECTION_OUT) + return -EINVAL; + + dmabuf = dma_buf_get(iio_dmabuf.fd); + if (IS_ERR(dmabuf)) + return PTR_ERR(dmabuf); + + if (!iio_dmabuf.bytes_used || iio_dmabuf.bytes_used > dmabuf->size) { + ret = -EINVAL; + goto err_dmabuf_put; + } + + attach = iio_buffer_find_attachment(ib->indio_dev, dmabuf); + if (IS_ERR(attach)) { + ret = PTR_ERR(attach); + goto err_dmabuf_put; + } + + priv = attach->importer_priv; + + dma_to_ram = buffer->direction == IIO_BUFFER_DIRECTION_IN; + dir = dma_to_ram ? DMA_FROM_DEVICE : DMA_TO_DEVICE; + + sgt = dma_buf_map_attachment(attach, dir); + if (IS_ERR(sgt)) { + ret = PTR_ERR(sgt); + pr_err("Unable to map attachment: %d\n", ret); + goto err_attachment_put; + } + + fence = kmalloc(sizeof(*fence), GFP_KERNEL); + if (!fence) { + ret = -ENOMEM; + goto err_unmap_attachment; + } + + fence->priv = priv; + fence->sgt = sgt; + fence->dir = dir; + priv->fence = fence; + + dma_fence_init(&fence->base, &iio_buffer_dma_fence_ops, + &priv->lock, priv->context, 0); + + ret = iio_dma_resv_lock(dmabuf, nonblock); + if (ret) + goto err_fence_put; + + timeout = nonblock ? 0 : msecs_to_jiffies(DMABUF_ENQUEUE_TIMEOUT_MS); + + /* Make sure we don't have writers */ + ret = (int) dma_resv_wait_timeout(dmabuf->resv, DMA_RESV_USAGE_WRITE, + true, timeout); + if (ret == 0) + ret = -EBUSY; + if (ret < 0) + goto err_resv_unlock; + + if (dma_to_ram) { + /* + * If we're writing to the DMABUF, make sure we don't have + * readers + */ + ret = (int) dma_resv_wait_timeout(dmabuf->resv, + DMA_RESV_USAGE_READ, true, + timeout); + if (ret == 0) + ret = -EBUSY; + if (ret < 0) + goto err_resv_unlock; + } + + ret = dma_resv_reserve_fences(dmabuf->resv, 1); + if (ret) + goto err_resv_unlock; + + dma_resv_add_fence(dmabuf->resv, &fence->base, + dma_resv_usage_rw(dma_to_ram)); + dma_resv_unlock(dmabuf->resv); + + ret = buffer->access->enqueue_dmabuf(buffer, priv->block, sgt, + iio_dmabuf.bytes_used, cyclic); + if (ret) + iio_buffer_signal_dmabuf_done(attach, ret); + + dma_buf_put(dmabuf); + + return ret; + +err_resv_unlock: + dma_resv_unlock(dmabuf->resv); +err_fence_put: + dma_fence_put(&fence->base); +err_unmap_attachment: + dma_buf_unmap_attachment(attach, sgt, dir); +err_attachment_put: + iio_buffer_dmabuf_put(attach); +err_dmabuf_put: + dma_buf_put(dmabuf); + + return ret; +} + +void iio_buffer_signal_dmabuf_done(struct dma_buf_attachment *attach, int ret) +{ + struct iio_dmabuf_priv *priv = attach->importer_priv; + struct iio_dma_fence *fence = priv->fence; + enum dma_data_direction dir = fence->dir; + struct sg_table *sgt = fence->sgt; + + dma_fence_get(&fence->base); + fence->base.error = ret; + dma_fence_signal(&fence->base); + dma_fence_put(&fence->base); + + dma_buf_unmap_attachment(attach, sgt, dir); + iio_buffer_dmabuf_put(attach); +} +EXPORT_SYMBOL_GPL(iio_buffer_signal_dmabuf_done); + +static long iio_buffer_chrdev_ioctl(struct file *filp, + unsigned int cmd, unsigned long arg) +{ + struct iio_dev_buffer_pair *ib = filp->private_data; + void __user *_arg = (void __user *)arg; + + switch (cmd) { + case IIO_BUFFER_DMABUF_ATTACH_IOCTL: + return iio_buffer_attach_dmabuf(ib, _arg); + case IIO_BUFFER_DMABUF_DETACH_IOCTL: + return iio_buffer_detach_dmabuf(ib, _arg); + case IIO_BUFFER_DMABUF_ENQUEUE_IOCTL: + return iio_buffer_enqueue_dmabuf(ib, _arg, + filp->f_flags & O_NONBLOCK); + default: + return IIO_IOCTL_UNHANDLED; + } +} + static const struct file_operations iio_buffer_chrdev_fileops = { .owner = THIS_MODULE, .llseek = noop_llseek, .read = iio_buffer_read, .write = iio_buffer_write, + .unlocked_ioctl = iio_buffer_chrdev_ioctl, + .compat_ioctl = compat_ptr_ioctl, .poll = iio_buffer_poll, .release = iio_buffer_chrdev_release, }; diff --git a/include/linux/iio/buffer_impl.h b/include/linux/iio/buffer_impl.h index 89c3fd7c29ca..a8a490091277 100644 --- a/include/linux/iio/buffer_impl.h +++ b/include/linux/iio/buffer_impl.h @@ -9,8 +9,11 @@ #include #include +struct dma_buf_attachment; struct iio_dev; +struct iio_dma_buffer_block; struct iio_buffer; +struct sg_table; /** * INDIO_BUFFER_FLAG_FIXED_WATERMARK - Watermark level of the buffer can not be @@ -39,6 +42,9 @@ struct iio_buffer; * device stops sampling. Calles are balanced with @enable. * @release: called when the last reference to the buffer is dropped, * should free all resources allocated by the buffer. + * @alloc_dmabuf: called from userspace via ioctl to allocate one DMABUF. + * @enqueue_dmabuf: called from userspace via ioctl to queue this DMABUF + * object to this buffer. Requires a valid DMABUF fd. * @modes: Supported operating modes by this buffer type * @flags: A bitmask combination of INDIO_BUFFER_FLAG_* * @@ -68,6 +74,14 @@ struct iio_buffer_access_funcs { void (*release)(struct iio_buffer *buffer); + struct iio_dma_buffer_block * (*attach_dmabuf)(struct iio_buffer *buffer, + struct dma_buf_attachment *attach); + void (*detach_dmabuf)(struct iio_buffer *buffer, + struct iio_dma_buffer_block *block); + int (*enqueue_dmabuf)(struct iio_buffer *buffer, + struct iio_dma_buffer_block *block, + struct sg_table *sgt, size_t size, bool cyclic); + unsigned int modes; unsigned int flags; }; @@ -136,6 +150,9 @@ struct iio_buffer { /* @ref: Reference count of the buffer. */ struct kref ref; + + /* @dmabufs: List of DMABUF attachments */ + struct list_head dmabufs; }; /** @@ -156,9 +173,14 @@ int iio_update_buffers(struct iio_dev *indio_dev, **/ void iio_buffer_init(struct iio_buffer *buffer); +void iio_buffer_dmabuf_get(struct dma_buf_attachment *attach); +void iio_buffer_dmabuf_put(struct dma_buf_attachment *attach); + struct iio_buffer *iio_buffer_get(struct iio_buffer *buffer); void iio_buffer_put(struct iio_buffer *buffer); +void iio_buffer_signal_dmabuf_done(struct dma_buf_attachment *attach, int ret); + #else /* CONFIG_IIO_BUFFER */ static inline void iio_buffer_get(struct iio_buffer *buffer) {} diff --git a/include/uapi/linux/iio/buffer.h b/include/uapi/linux/iio/buffer.h index 13939032b3f6..c666aa95e532 100644 --- a/include/uapi/linux/iio/buffer.h +++ b/include/uapi/linux/iio/buffer.h @@ -5,6 +5,28 @@ #ifndef _UAPI_IIO_BUFFER_H_ #define _UAPI_IIO_BUFFER_H_ +#include + +/* Flags for iio_dmabuf.flags */ +#define IIO_BUFFER_DMABUF_CYCLIC (1 << 0) +#define IIO_BUFFER_DMABUF_SUPPORTED_FLAGS 0x00000001 + +/** + * struct iio_dmabuf - Descriptor for a single IIO DMABUF object + * @fd: file descriptor of the DMABUF object + * @flags: one or more IIO_BUFFER_DMABUF_* flags + * @bytes_used: number of bytes used in this DMABUF for the data transfer. + * Should generally be set to the DMABUF's size. + */ +struct iio_dmabuf { + __u32 fd; + __u32 flags; + __u64 bytes_used; +}; + #define IIO_BUFFER_GET_FD_IOCTL _IOWR('i', 0x91, int) +#define IIO_BUFFER_DMABUF_ATTACH_IOCTL _IOW('i', 0x92, int) +#define IIO_BUFFER_DMABUF_DETACH_IOCTL _IOW('i', 0x93, int) +#define IIO_BUFFER_DMABUF_ENQUEUE_IOCTL _IOW('i', 0x94, struct iio_dmabuf) #endif /* _UAPI_IIO_BUFFER_H_ */ From patchwork Mon Apr 3 15:47:57 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Cercueil X-Patchwork-Id: 78605 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp2413129vqo; Mon, 3 Apr 2023 09:06:34 -0700 (PDT) X-Google-Smtp-Source: AKy350YxtO0Gd2PpoJ8R6bSpL/BaSDxEj5hptJI+RdzweHzvqsBWjmDRaexituv3ew8KufN4sRfr X-Received: by 2002:a17:902:cf51:b0:19f:3b86:4715 with SMTP id e17-20020a170902cf5100b0019f3b864715mr32913683plg.8.1680537994187; Mon, 03 Apr 2023 09:06:34 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1680537994; cv=none; d=google.com; s=arc-20160816; b=kfnMkAT70UdFhezMCJyIWBqMQFTXtQ2mlq+EGXQ6BWh8rZREAKWL5OvFCAs5n1IH8K Ac8PeXK+VwhrM7v9327PQkq4OGa/6qrZ0Cs1jnuS6K1wqN6EODNEFdu4fhdCqAtFpamK P64pQDpvBKstzBstJdWlDApH7JvBHm1YolWUlFBil+yUH1wfpudvFZMEDHSQTuky8OwJ cyOgzuGKTeMl3tjEF3Q4hsQstjKNq8a+ExJGs/s2AbywbP1jo0/RkdakGJ24u+LGcMuF xHD1fSrm0GlSLo6LS4zivDkSQiQJIau/bgrHIkOcawqoNnu56KHPcy8o3443qXvuzSrW mcgA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=beF+K1NHWP/zsnX7POz8yyiiOBr7zCFi5ikb61FvcI4=; b=JpkW4CoFYyiIRq9F+NN/Vdm1Ei6txp6QrFAcafWqpgAH4gPjZ+UrpsXkCxsi6cZCcp 0EGeKQOYXsrZWUayjM70oBFIfyAWxVzc2qBA1LJrSqUPi/WRpScK1kTzBdltPOqQYbN1 H28ABK9lfqRCRlYGUCN0uzOZj5JApBQqHUeO4yx46VTRnVm4GdI9izLyGA5AVVpRvpVs 6ylYkLuOf50p0Vq9w86Wt9fwnwofetrnnkznaA1IYoiLPX/8QLYyPz7G47Ztps+WCx/W q9BC/QW8IOIILz6f4rkckTnH8WfXap8nqabnI0ex4YbSpiyp1PzgfY0l3holtucgoJZa axPQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@crapouillou.net header.s=mail header.b=rEQlu75p; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=crapouillou.net Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id u16-20020a170903125000b001a2a9bfdfb4si6374499plh.297.2023.04.03.09.06.20; Mon, 03 Apr 2023 09:06:34 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@crapouillou.net header.s=mail header.b=rEQlu75p; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=crapouillou.net Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233113AbjDCPz2 (ORCPT + 99 others); Mon, 3 Apr 2023 11:55:28 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38240 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232582AbjDCPzN (ORCPT ); Mon, 3 Apr 2023 11:55:13 -0400 Received: from aposti.net (aposti.net [89.234.176.197]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0C64844AC; Mon, 3 Apr 2023 08:54:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=crapouillou.net; s=mail; t=1680536901; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=beF+K1NHWP/zsnX7POz8yyiiOBr7zCFi5ikb61FvcI4=; b=rEQlu75pE1XlxvEiW2Vp6Q2DrJqFlXQRWGAGO/qViDKRDquUpd4KRJ2jtCkCphUkqIMmkc kCibghuDBjplYnoTYkLj+VJLDOiOKickpRJaP+TywS3SWmlYLN2xIf8YpVNxnxU3wY3Pj7 8OG7sKOHPKMOxagqrUvT8h8+0YtaZik= From: Paul Cercueil To: Jonathan Cameron , Lars-Peter Clausen , Vinod Koul , Michael Hennerich , =?utf-8?q?Nuno_S=C3=A1?= , Sumit Semwal , =?utf-8?q?Christian_K=C3=B6nig?= Cc: linux-kernel@vger.kernel.org, dmaengine@vger.kernel.org, linux-iio@vger.kernel.org, linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org, Alexandru Ardelean , Alexandru Ardelean , Paul Cercueil Subject: [PATCH v3 08/11] iio: buffer-dma: split iio_dma_buffer_fileio_free() function Date: Mon, 3 Apr 2023 17:47:57 +0200 Message-Id: <20230403154800.215924-9-paul@crapouillou.net> In-Reply-To: <20230403154800.215924-1-paul@crapouillou.net> References: <20230403154800.215924-1-paul@crapouillou.net> MIME-Version: 1.0 X-Spam: Yes X-Spam-Status: No, score=-0.2 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_PASS,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1762171807846666896?= X-GMAIL-MSGID: =?utf-8?q?1762171807846666896?= From: Alexandru Ardelean This change splits the logic into a separate function, which will be re-used later. Signed-off-by: Alexandru Ardelean Cc: Alexandru Ardelean Signed-off-by: Paul Cercueil --- drivers/iio/buffer/industrialio-buffer-dma.c | 43 +++++++++++--------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/drivers/iio/buffer/industrialio-buffer-dma.c b/drivers/iio/buffer/industrialio-buffer-dma.c index 86eced458236..e14814e0d4c8 100644 --- a/drivers/iio/buffer/industrialio-buffer-dma.c +++ b/drivers/iio/buffer/industrialio-buffer-dma.c @@ -374,6 +374,29 @@ int iio_dma_buffer_request_update(struct iio_buffer *buffer) } EXPORT_SYMBOL_GPL(iio_dma_buffer_request_update); +static void iio_dma_buffer_fileio_free(struct iio_dma_buffer_queue *queue) +{ + unsigned int i; + + spin_lock_irq(&queue->list_lock); + for (i = 0; i < ARRAY_SIZE(queue->fileio.blocks); i++) { + if (!queue->fileio.blocks[i]) + continue; + queue->fileio.blocks[i]->state = IIO_BLOCK_STATE_DEAD; + } + spin_unlock_irq(&queue->list_lock); + + INIT_LIST_HEAD(&queue->incoming); + + for (i = 0; i < ARRAY_SIZE(queue->fileio.blocks); i++) { + if (!queue->fileio.blocks[i]) + continue; + iio_buffer_block_put(queue->fileio.blocks[i]); + queue->fileio.blocks[i] = NULL; + } + queue->fileio.active_block = NULL; +} + static void iio_dma_buffer_submit_block(struct iio_dma_buffer_queue *queue, struct iio_dma_buffer_block *block) { @@ -695,27 +718,9 @@ EXPORT_SYMBOL_GPL(iio_dma_buffer_init); */ void iio_dma_buffer_exit(struct iio_dma_buffer_queue *queue) { - unsigned int i; - mutex_lock(&queue->lock); - spin_lock_irq(&queue->list_lock); - for (i = 0; i < ARRAY_SIZE(queue->fileio.blocks); i++) { - if (!queue->fileio.blocks[i]) - continue; - queue->fileio.blocks[i]->state = IIO_BLOCK_STATE_DEAD; - } - spin_unlock_irq(&queue->list_lock); - - INIT_LIST_HEAD(&queue->incoming); - - for (i = 0; i < ARRAY_SIZE(queue->fileio.blocks); i++) { - if (!queue->fileio.blocks[i]) - continue; - iio_buffer_block_put(queue->fileio.blocks[i]); - queue->fileio.blocks[i] = NULL; - } - queue->fileio.active_block = NULL; + iio_dma_buffer_fileio_free(queue); queue->ops = NULL; mutex_unlock(&queue->lock); From patchwork Mon Apr 3 15:47:58 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Cercueil X-Patchwork-Id: 78614 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp2416168vqo; Mon, 3 Apr 2023 09:10:25 -0700 (PDT) X-Google-Smtp-Source: AK7set9kR9HZ0T32g5lsgjomtvr4AZwHQLRJq7cO5mwwKwR4hDDXrCTLrOlkzOfHXiqFf+xvoIO9 X-Received: by 2002:a05:6a20:4d92:b0:da:aaec:9455 with SMTP id gj18-20020a056a204d9200b000daaaec9455mr32562036pzb.43.1680538225120; Mon, 03 Apr 2023 09:10:25 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1680538225; cv=none; d=google.com; s=arc-20160816; b=Fb+RCrZKJHpDK6hNdedor01ExbqSwfaIGtKiZ2GEW0C/4WJqC1lYo2UDgeeZp/6szx fEtfH3uBeF+TFPkJzSlWyotVj4UIj7j35HNs78uDzZU1J20Lqda+UcUF0F6Kkf1mB3+D 8t/WN/xRSMl09RWkIw6gSb5BqRotmQfdZ69+gdmmYfqY1l8ht+IB7XrtDyOYdxY8WeOK /UowJ4TNYzKjxwh/6bFyei+vLwMXDXNcc+/D/ywucXbo5CFeZUtYh8MNcDa6tzOkHRis Lk9Ad3VZoekgBhspfdsi0Xl4V8JnwHSrZk1/BwqBu0+itZG7KdcNj8YnKanVO6KMcC0C Hpzw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=8PmkZdIE9FdBhRGx72/sSOhDClhx1FbzE4O+lf4iMcM=; b=s15safP4/YMa0v7NtHiU7uswtUdVlYovqHjOg9MknmD8tjcksCR5CNtcA5J+0Uih9X 7WDFLAQS07SzsnylCvF/ggYgBEYx8ltPi9UKWlpoiP2PZvKLu4lFZS7s9gKrtcdgAtro tkhOPZOBogXOs891SZ3+MmLZ8xlRz8eVEzn0PJulwRskVqjAiAh38Em0Fgstt40CJJiS sdauCmutGr9PnWH/Hw+7Q9cW6XHPZQgm7rPgMUDb5tXAj3g3AlUqe2MPZYemkowJYT3H eAe0r+68INHCE2BMWQsC5wRXy07YkhYIUdGjiF+Jw+8aiq/EWmeItOFdXtjIPuO/f/YX dd4Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@crapouillou.net header.s=mail header.b=v87Qroxu; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=crapouillou.net Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id r9-20020aa79889000000b00625dc9792a6si8475478pfl.300.2023.04.03.09.10.11; Mon, 03 Apr 2023 09:10:25 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@crapouillou.net header.s=mail header.b=v87Qroxu; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=crapouillou.net Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232791AbjDCP4M (ORCPT + 99 others); Mon, 3 Apr 2023 11:56:12 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43394 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232711AbjDCPzy (ORCPT ); Mon, 3 Apr 2023 11:55:54 -0400 Received: from aposti.net (aposti.net [89.234.176.197]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0FCD83A85; Mon, 3 Apr 2023 08:55:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=crapouillou.net; s=mail; t=1680536903; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=8PmkZdIE9FdBhRGx72/sSOhDClhx1FbzE4O+lf4iMcM=; b=v87QroxueeO0YCfxdu0pF1xJuArsC0IP3ZOO9nK0wsf3sliLSUuDXcMoFI4vtoWFKqIXci pwNK4YZimP0gO1fZER+tmONttpzCVbXYeafzeiKzS18/7WPikxoICX0hFErjvw63SKc7dV VSH1pzCWw0WqB3OJpK8ExkY/vxBXhr4= From: Paul Cercueil To: Jonathan Cameron , Lars-Peter Clausen , Vinod Koul , Michael Hennerich , =?utf-8?q?Nuno_S=C3=A1?= , Sumit Semwal , =?utf-8?q?Christian_K=C3=B6nig?= Cc: linux-kernel@vger.kernel.org, dmaengine@vger.kernel.org, linux-iio@vger.kernel.org, linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org, Paul Cercueil Subject: [PATCH v3 09/11] iio: buffer-dma: Enable support for DMABUFs Date: Mon, 3 Apr 2023 17:47:58 +0200 Message-Id: <20230403154800.215924-10-paul@crapouillou.net> In-Reply-To: <20230403154800.215924-1-paul@crapouillou.net> References: <20230403154800.215924-1-paul@crapouillou.net> MIME-Version: 1.0 X-Spam: Yes X-Spam-Status: No, score=-0.2 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_PASS,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1762172049941720966?= X-GMAIL-MSGID: =?utf-8?q?1762172049941720966?= Implement iio_dma_buffer_attach_dmabuf(), iio_dma_buffer_detach_dmabuf() and iio_dma_buffer_transfer_dmabuf(), which can then be used by the IIO DMA buffer implementations. Signed-off-by: Paul Cercueil --- v3: Update code to provide the functions that will be used as callbacks for the new IOCTLs. --- drivers/iio/buffer/industrialio-buffer-dma.c | 157 +++++++++++++++++-- include/linux/iio/buffer-dma.h | 24 +++ 2 files changed, 168 insertions(+), 13 deletions(-) diff --git a/drivers/iio/buffer/industrialio-buffer-dma.c b/drivers/iio/buffer/industrialio-buffer-dma.c index e14814e0d4c8..422bd784fd1e 100644 --- a/drivers/iio/buffer/industrialio-buffer-dma.c +++ b/drivers/iio/buffer/industrialio-buffer-dma.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -94,14 +95,24 @@ static void iio_buffer_block_release(struct kref *kref) { struct iio_dma_buffer_block *block = container_of(kref, struct iio_dma_buffer_block, kref); + struct iio_dma_buffer_queue *queue = block->queue; - WARN_ON(block->state != IIO_BLOCK_STATE_DEAD); + WARN_ON(block->fileio && block->state != IIO_BLOCK_STATE_DEAD); - dma_free_coherent(block->queue->dev, PAGE_ALIGN(block->size), - block->vaddr, block->phys_addr); + mutex_lock(&queue->lock); - iio_buffer_put(&block->queue->buffer); + if (block->fileio) { + dma_free_coherent(queue->dev, PAGE_ALIGN(block->size), + block->vaddr, block->phys_addr); + queue->num_fileio_blocks--; + } + + queue->num_blocks--; kfree(block); + + mutex_unlock(&queue->lock); + + iio_buffer_put(&queue->buffer); } static void iio_buffer_block_get(struct iio_dma_buffer_block *block) @@ -163,7 +174,7 @@ static struct iio_dma_buffer_queue *iio_buffer_to_queue(struct iio_buffer *buf) } static struct iio_dma_buffer_block *iio_dma_buffer_alloc_block( - struct iio_dma_buffer_queue *queue, size_t size) + struct iio_dma_buffer_queue *queue, size_t size, bool fileio) { struct iio_dma_buffer_block *block; @@ -171,13 +182,16 @@ static struct iio_dma_buffer_block *iio_dma_buffer_alloc_block( if (!block) return NULL; - block->vaddr = dma_alloc_coherent(queue->dev, PAGE_ALIGN(size), - &block->phys_addr, GFP_KERNEL); - if (!block->vaddr) { - kfree(block); - return NULL; + if (fileio) { + block->vaddr = dma_alloc_coherent(queue->dev, PAGE_ALIGN(size), + &block->phys_addr, GFP_KERNEL); + if (!block->vaddr) { + kfree(block); + return NULL; + } } + block->fileio = fileio; block->size = size; block->state = IIO_BLOCK_STATE_DONE; block->queue = queue; @@ -186,6 +200,9 @@ static struct iio_dma_buffer_block *iio_dma_buffer_alloc_block( iio_buffer_get(&queue->buffer); + queue->num_blocks++; + queue->num_fileio_blocks += fileio; + return block; } @@ -223,6 +240,9 @@ void iio_dma_buffer_block_done(struct iio_dma_buffer_block *block) _iio_dma_buffer_block_done(block); spin_unlock_irqrestore(&queue->list_lock, flags); + if (!block->fileio) + iio_buffer_signal_dmabuf_done(block->attach, 0); + iio_buffer_block_put_atomic(block); iio_dma_buffer_queue_wake(queue); } @@ -249,10 +269,14 @@ void iio_dma_buffer_block_list_abort(struct iio_dma_buffer_queue *queue, list_del(&block->head); block->bytes_used = 0; _iio_dma_buffer_block_done(block); + + if (!block->fileio) + iio_buffer_signal_dmabuf_done(block->attach, -EINTR); iio_buffer_block_put_atomic(block); } spin_unlock_irqrestore(&queue->list_lock, flags); + queue->fileio.enabled = false; iio_dma_buffer_queue_wake(queue); } EXPORT_SYMBOL_GPL(iio_dma_buffer_block_list_abort); @@ -273,6 +297,12 @@ static bool iio_dma_block_reusable(struct iio_dma_buffer_block *block) } } +static bool iio_dma_buffer_fileio_mode(struct iio_dma_buffer_queue *queue) +{ + return queue->fileio.enabled || + queue->num_blocks == queue->num_fileio_blocks; +} + /** * iio_dma_buffer_request_update() - DMA buffer request_update callback * @buffer: The buffer which to request an update @@ -299,6 +329,12 @@ int iio_dma_buffer_request_update(struct iio_buffer *buffer) mutex_lock(&queue->lock); + queue->fileio.enabled = iio_dma_buffer_fileio_mode(queue); + + /* If DMABUFs were created, disable fileio interface */ + if (!queue->fileio.enabled) + goto out_unlock; + /* Allocations are page aligned */ if (PAGE_ALIGN(queue->fileio.block_size) == PAGE_ALIGN(size)) try_reuse = true; @@ -329,7 +365,7 @@ int iio_dma_buffer_request_update(struct iio_buffer *buffer) block = queue->fileio.blocks[i]; if (block->state == IIO_BLOCK_STATE_DEAD) { /* Could not reuse it */ - iio_buffer_block_put(block); + iio_buffer_block_put_atomic(block); block = NULL; } else { block->size = size; @@ -339,7 +375,7 @@ int iio_dma_buffer_request_update(struct iio_buffer *buffer) } if (!block) { - block = iio_dma_buffer_alloc_block(queue, size); + block = iio_dma_buffer_alloc_block(queue, size, true); if (!block) { ret = -ENOMEM; goto out_unlock; @@ -391,7 +427,7 @@ static void iio_dma_buffer_fileio_free(struct iio_dma_buffer_queue *queue) for (i = 0; i < ARRAY_SIZE(queue->fileio.blocks); i++) { if (!queue->fileio.blocks[i]) continue; - iio_buffer_block_put(queue->fileio.blocks[i]); + iio_buffer_block_put_atomic(queue->fileio.blocks[i]); queue->fileio.blocks[i] = NULL; } queue->fileio.active_block = NULL; @@ -412,8 +448,12 @@ static void iio_dma_buffer_submit_block(struct iio_dma_buffer_queue *queue, block->state = IIO_BLOCK_STATE_ACTIVE; iio_buffer_block_get(block); + ret = queue->ops->submit(queue, block); if (ret) { + if (!block->fileio) + iio_buffer_signal_dmabuf_done(block->attach, ret); + /* * This is a bit of a problem and there is not much we can do * other then wait for the buffer to be disabled and re-enabled @@ -645,6 +685,97 @@ size_t iio_dma_buffer_data_available(struct iio_buffer *buf) } EXPORT_SYMBOL_GPL(iio_dma_buffer_data_available); +struct iio_dma_buffer_block * +iio_dma_buffer_attach_dmabuf(struct iio_buffer *buffer, + struct dma_buf_attachment *attach) +{ + struct iio_dma_buffer_queue *queue = iio_buffer_to_queue(buffer); + struct iio_dma_buffer_block *block; + int err; + + mutex_lock(&queue->lock); + + /* + * If the buffer is enabled and in fileio mode new blocks can't be + * allocated. + */ + if (queue->fileio.enabled) { + err = -EBUSY; + goto err_unlock; + } + + block = iio_dma_buffer_alloc_block(queue, attach->dmabuf->size, false); + if (!block) { + err = -ENOMEM; + goto err_unlock; + } + + block->attach = attach; + + /* Free memory that might be in use for fileio mode */ + iio_dma_buffer_fileio_free(queue); + + mutex_unlock(&queue->lock); + + return block; + +err_unlock: + mutex_unlock(&queue->lock); + return ERR_PTR(err); +} +EXPORT_SYMBOL_GPL(iio_dma_buffer_attach_dmabuf); + +void iio_dma_buffer_detach_dmabuf(struct iio_buffer *buffer, + struct iio_dma_buffer_block *block) +{ + block->state = IIO_BLOCK_STATE_DEAD; + iio_buffer_block_put_atomic(block); +} +EXPORT_SYMBOL_GPL(iio_dma_buffer_detach_dmabuf); + +static int iio_dma_can_enqueue_block(struct iio_dma_buffer_block *block) +{ + struct iio_dma_buffer_queue *queue = block->queue; + + /* If in fileio mode buffers can't be enqueued. */ + if (queue->fileio.enabled) + return -EBUSY; + + switch (block->state) { + case IIO_BLOCK_STATE_QUEUED: + return -EPERM; + case IIO_BLOCK_STATE_DONE: + return 0; + default: + return -EBUSY; + } +} + +int iio_dma_buffer_enqueue_dmabuf(struct iio_buffer *buffer, + struct iio_dma_buffer_block *block, + struct sg_table *sgt, + size_t size, bool cyclic) +{ + struct iio_dma_buffer_queue *queue = iio_buffer_to_queue(buffer); + int ret = 0; + + mutex_lock(&queue->lock); + ret = iio_dma_can_enqueue_block(block); + if (ret < 0) + goto out_mutex_unlock; + + block->bytes_used = size; + block->cyclic = cyclic; + block->sg_table = sgt; + + iio_dma_buffer_enqueue(queue, block); + +out_mutex_unlock: + mutex_unlock(&queue->lock); + return ret; +} +EXPORT_SYMBOL_GPL(iio_dma_buffer_enqueue_dmabuf); + /** * iio_dma_buffer_set_bytes_per_datum() - DMA buffer set_bytes_per_datum callback * @buffer: Buffer to set the bytes-per-datum for diff --git a/include/linux/iio/buffer-dma.h b/include/linux/iio/buffer-dma.h index 490b93f76fa8..e5e5817e99db 100644 --- a/include/linux/iio/buffer-dma.h +++ b/include/linux/iio/buffer-dma.h @@ -16,6 +16,8 @@ struct iio_dma_buffer_queue; struct iio_dma_buffer_ops; struct device; +struct dma_buf_attachment; +struct sg_table; /** * enum iio_block_state - State of a struct iio_dma_buffer_block @@ -41,6 +43,7 @@ enum iio_block_state { * @queue: Parent DMA buffer queue * @kref: kref used to manage the lifetime of block * @state: Current state of the block + * @fileio: True if this buffer is used for fileio mode */ struct iio_dma_buffer_block { /* May only be accessed by the owner of the block */ @@ -63,6 +66,11 @@ struct iio_dma_buffer_block { * queue->list_lock if the block is not owned by the core. */ enum iio_block_state state; + + bool fileio; + + struct dma_buf_attachment *attach; + struct sg_table *sg_table; }; /** @@ -72,6 +80,7 @@ struct iio_dma_buffer_block { * @pos: Read offset in the active block * @block_size: Size of each block * @next_dequeue: index of next block that will be dequeued + * @enabled: Whether the buffer is operating in fileio mode */ struct iio_dma_buffer_queue_fileio { struct iio_dma_buffer_block *blocks[2]; @@ -80,6 +89,7 @@ struct iio_dma_buffer_queue_fileio { size_t block_size; unsigned int next_dequeue; + bool enabled; }; /** @@ -95,6 +105,8 @@ struct iio_dma_buffer_queue_fileio { * the DMA controller * @incoming: List of buffers on the incoming queue * @active: Whether the buffer is currently active + * @num_blocks: Total number of DMA blocks + * @num_fileio_blocks: Number of DMA blocks for fileio mode * @fileio: FileIO state */ struct iio_dma_buffer_queue { @@ -107,6 +119,8 @@ struct iio_dma_buffer_queue { struct list_head incoming; bool active; + unsigned int num_blocks; + unsigned int num_fileio_blocks; struct iio_dma_buffer_queue_fileio fileio; }; @@ -149,4 +163,14 @@ static inline size_t iio_dma_buffer_space_available(struct iio_buffer *buffer) return iio_dma_buffer_data_available(buffer); } +struct iio_dma_buffer_block * +iio_dma_buffer_attach_dmabuf(struct iio_buffer *buffer, + struct dma_buf_attachment *attach); +void iio_dma_buffer_detach_dmabuf(struct iio_buffer *buffer, + struct iio_dma_buffer_block *block); +int iio_dma_buffer_enqueue_dmabuf(struct iio_buffer *buffer, + struct iio_dma_buffer_block *block, + struct sg_table *sgt, + size_t size, bool cyclic); + #endif From patchwork Mon Apr 3 15:49:54 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Cercueil X-Patchwork-Id: 78607 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp2413867vqo; Mon, 3 Apr 2023 09:07:29 -0700 (PDT) X-Google-Smtp-Source: AKy350b/tv2v/lwb+H0XwKZB54Fb5Wbo11+S5wfq4r096i1JxApcdQ9BKMMgRHnvNnK0bM1TjCJn X-Received: by 2002:a62:1ac9:0:b0:62d:b4aa:79f9 with SMTP id a192-20020a621ac9000000b0062db4aa79f9mr20991385pfa.28.1680538049249; Mon, 03 Apr 2023 09:07:29 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1680538049; cv=none; d=google.com; s=arc-20160816; b=q7p9Ln9YBEGrDaBY5VbBxBrffy3FQ7OSPfSjkAuT8+LBmCn+6cisVWE2tUr5TR5owo AUwSXTktJFsV2QMahhnozXiKdHcQmjN28riOQjOXZPEXVCGSuU4/5GkHEHLG96CX1Fmh BbKjZXIrIZLomHhphy5baKcKPJ3Htdpm7FRgk9k1hoyt12//p2Gbxad8lyRnRzTMXjNP 4Qbxs0S+mw7megxvsPNoWVqm9oYkCbAaYO/R2v/hqGo6hPd8gy08qiKUWUIWiI/stj7w Vhx+W5yDOOJO1KdmrOgh310XDDMqC6VREd1hLHra9p1zoZAmAbs+9C6OQEc5VGls/pUO 02+g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=wA4riywwKKpvJAgChQaqtpae762HoiQ3X43R1omKQq4=; b=f6mQMJIaU8T0IEro0cI4ZTtjWE5SbVZfCKko3WKkyFVSZwOYpJSB3/Az+eWOf+FKLw /NuU3fZiu4gDcCaM6+Qm4xdoaGePFbmo+PFQA9Th7Td3mh1la90SJ31kgzFqip0wa8Oc 68Md+x3z9h40pmMHp6ueTup8MPccwcTtJ/in1GDzpk3hhM7QXBAVu8TIpUPxwLeShEzX amlgUt1IjaaNg8U+m3LV/dtr2SL5JsJ7yzVS8JiYazkdTv9MbHfCslZSIQe+uDGtnCjm iuT9KtSrejMZ3+DdZCTt4gumZ/TDKc4yldkmIvLAfeWF9HhOqmmWnlgbLo8ynEsh7RsK QA8w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@crapouillou.net header.s=mail header.b=w2Vbrqzj; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=crapouillou.net Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id r9-20020aa79889000000b00625dc9792a6si8475478pfl.300.2023.04.03.09.07.16; Mon, 03 Apr 2023 09:07:29 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@crapouillou.net header.s=mail header.b=w2Vbrqzj; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=crapouillou.net Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233066AbjDCP4u (ORCPT + 99 others); Mon, 3 Apr 2023 11:56:50 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45146 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233028AbjDCP4h (ORCPT ); Mon, 3 Apr 2023 11:56:37 -0400 Received: from aposti.net (aposti.net [89.234.176.197]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9E7A9180; Mon, 3 Apr 2023 08:56:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=crapouillou.net; s=mail; t=1680537005; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=wA4riywwKKpvJAgChQaqtpae762HoiQ3X43R1omKQq4=; b=w2Vbrqzju+FpRpVjzxZ2RLYiP3a1YX0fUt98d/TwX/8ordZETUPCJEcVcrO40kky/ffb9S crFaELFhXS+K44RKouzy6bUJopS6o5LK2G4sSwcSpNycj2XHVf7p/0YKpt+mQ99jEQKCwj YMLN5v0VHzBRjP/xQ0K8kCdC+HOP350= From: Paul Cercueil To: Jonathan Cameron , Lars-Peter Clausen , Vinod Koul , Michael Hennerich , =?utf-8?q?Nuno_S=C3=A1?= , Sumit Semwal , =?utf-8?q?Christian_K=C3=B6nig?= Cc: linux-kernel@vger.kernel.org, dmaengine@vger.kernel.org, linux-iio@vger.kernel.org, linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org, Paul Cercueil Subject: [PATCH v3 10/11] iio: buffer-dmaengine: Support new DMABUF based userspace API Date: Mon, 3 Apr 2023 17:49:54 +0200 Message-Id: <20230403154955.216148-1-paul@crapouillou.net> In-Reply-To: <20230403154800.215924-1-paul@crapouillou.net> References: <20230403154800.215924-1-paul@crapouillou.net> MIME-Version: 1.0 X-Spam: Yes X-Spam-Status: No, score=-0.2 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_PASS,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1762171865424914289?= X-GMAIL-MSGID: =?utf-8?q?1762171865424914289?= Use the functions provided by the buffer-dma core to implement the DMABUF userspace API in the buffer-dmaengine IIO buffer implementation. Since we want to be able to transfer an arbitrary number of bytes and not necesarily the full DMABUF, the associated scatterlist is converted to an array of DMA addresses + lengths, which is then passed to dmaengine_prep_slave_dma_array(). Signed-off-by: Paul Cercueil --- v3: Use the new dmaengine_prep_slave_dma_array(), and adapt the code to work with the new functions introduced in industrialio-buffer-dma.c. --- .../buffer/industrialio-buffer-dmaengine.c | 69 ++++++++++++++++--- include/linux/iio/buffer-dma.h | 2 + 2 files changed, 60 insertions(+), 11 deletions(-) diff --git a/drivers/iio/buffer/industrialio-buffer-dmaengine.c b/drivers/iio/buffer/industrialio-buffer-dmaengine.c index 866c8b84bb24..faed9c2b089c 100644 --- a/drivers/iio/buffer/industrialio-buffer-dmaengine.c +++ b/drivers/iio/buffer/industrialio-buffer-dmaengine.c @@ -65,25 +65,68 @@ static int iio_dmaengine_buffer_submit_block(struct iio_dma_buffer_queue *queue, iio_buffer_to_dmaengine_buffer(&queue->buffer); struct dma_async_tx_descriptor *desc; enum dma_transfer_direction dma_dir; + unsigned int i, nents, *lenghts; + struct scatterlist *sgl; + unsigned long flags; + dma_addr_t *addrs; size_t max_size; dma_cookie_t cookie; + size_t len_total; - max_size = min(block->size, dmaengine_buffer->max_size); - max_size = round_down(max_size, dmaengine_buffer->align); + if (!block->bytes_used) + return -EINVAL; - if (queue->buffer.direction == IIO_BUFFER_DIRECTION_IN) { - block->bytes_used = max_size; + if (queue->buffer.direction == IIO_BUFFER_DIRECTION_IN) dma_dir = DMA_DEV_TO_MEM; - } else { + else dma_dir = DMA_MEM_TO_DEV; - } - if (!block->bytes_used || block->bytes_used > max_size) - return -EINVAL; + if (block->sg_table) { + sgl = block->sg_table->sgl; + nents = sg_nents_for_len(sgl, block->bytes_used); + + addrs = kmalloc_array(nents, sizeof(*addrs), GFP_KERNEL); + if (!addrs) + return -ENOMEM; + + lenghts = kmalloc_array(nents, sizeof(*lenghts), GFP_KERNEL); + if (!lenghts) { + kfree(addrs); + return -ENOMEM; + } + + len_total = block->bytes_used; - desc = dmaengine_prep_slave_single(dmaengine_buffer->chan, - block->phys_addr, block->bytes_used, dma_dir, - DMA_PREP_INTERRUPT); + for (i = 0; i < nents; i++) { + addrs[i] = sg_dma_address(sgl); + lenghts[i] = min(sg_dma_len(sgl), len_total); + len_total -= lenghts[i]; + + sgl = sg_next(sgl); + } + + flags = block->cyclic ? DMA_PREP_REPEAT : DMA_PREP_INTERRUPT; + + desc = dmaengine_prep_slave_dma_array(dmaengine_buffer->chan, + addrs, lenghts, nents, + dma_dir, flags); + kfree(addrs); + kfree(lenghts); + } else { + max_size = min(block->size, dmaengine_buffer->max_size); + max_size = round_down(max_size, dmaengine_buffer->align); + + if (queue->buffer.direction == IIO_BUFFER_DIRECTION_IN) + block->bytes_used = max_size; + + if (block->bytes_used > max_size) + return -EINVAL; + + desc = dmaengine_prep_slave_single(dmaengine_buffer->chan, + block->phys_addr, + block->bytes_used, dma_dir, + DMA_PREP_INTERRUPT); + } if (!desc) return -ENOMEM; @@ -133,6 +176,10 @@ static const struct iio_buffer_access_funcs iio_dmaengine_buffer_ops = { .space_available = iio_dma_buffer_space_available, .release = iio_dmaengine_buffer_release, + .enqueue_dmabuf = iio_dma_buffer_enqueue_dmabuf, + .attach_dmabuf = iio_dma_buffer_attach_dmabuf, + .detach_dmabuf = iio_dma_buffer_detach_dmabuf, + .modes = INDIO_BUFFER_HARDWARE, .flags = INDIO_BUFFER_FLAG_FIXED_WATERMARK, }; diff --git a/include/linux/iio/buffer-dma.h b/include/linux/iio/buffer-dma.h index e5e5817e99db..48f7ffaf0867 100644 --- a/include/linux/iio/buffer-dma.h +++ b/include/linux/iio/buffer-dma.h @@ -43,6 +43,7 @@ enum iio_block_state { * @queue: Parent DMA buffer queue * @kref: kref used to manage the lifetime of block * @state: Current state of the block + * @cyclic: True if this is a cyclic buffer * @fileio: True if this buffer is used for fileio mode */ struct iio_dma_buffer_block { @@ -67,6 +68,7 @@ struct iio_dma_buffer_block { */ enum iio_block_state state; + bool cyclic; bool fileio; struct dma_buf_attachment *attach; From patchwork Mon Apr 3 15:49:55 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Cercueil X-Patchwork-Id: 78602 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp2412521vqo; Mon, 3 Apr 2023 09:05:53 -0700 (PDT) X-Google-Smtp-Source: AKy350ZXZAQh0FXkws0xCtY9qJp53E0yTjlxf6EUbtpFJlWc7uJehW10N15LLFp4wRXnEaoZ2MQN X-Received: by 2002:a17:90b:1c02:b0:23f:48b9:266d with SMTP id oc2-20020a17090b1c0200b0023f48b9266dmr39407156pjb.21.1680537953494; Mon, 03 Apr 2023 09:05:53 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1680537953; cv=none; d=google.com; s=arc-20160816; b=jh3XvZmXaDap5f0yZR9AxqOKR0Z0CYeMOVn63lj9NdB1X/6TKbWf5vic/SrDc/1E/K FneiXftRVnbQDlvtX8RaXYwQzt6WNN6qgmeAdMfbvXu6iQrYUkBF5X4mf6LLA1Qm14By U/SNlK7FSdZoqm9mW/lFnOdKdlB1P9dt1MsLggDz7+Ffx6WFmj/otoE67hm42slM0UsC dQ2Fq84WwAjH1Q9EiBIxdVlQUWkdyCNmuZib88TA0ipC0c+1Ikes/UvHUsx2DPj66Fsb pmifETmgrQCEo2uzrYUiQqkm7uOcT7r1JJWqkupEpcMyrh8MEX6qKHGhpNuVugKyO8n6 oTcw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=WQ7k7KsV39QPGYjokDQtx5Buy0HkE7q//zbkWOqAhK8=; b=V61fYwLdxyRspmIBnSHAv7efr75J89UIdfcK+/pLg9j+oT+osxEw+591oBUHqvwxDA p2cOpj0phhWmMji6FQO+mjBFKD1gkvghBNzxi9YueKM7bWmO9s6qMIj7kLWnYeVCEPnS wpaZ3crUQUYcRd6s0hykHeVUIfB5IHNcID20Iuzu9QBpQ0KMV9+qGiylVGrL1fuuCGpB sP4z8MHhAMAsy6hsmbISTJiqOw+Hvuf/55VbUl2f1TsNcQF9YFvD7J43dOwQ7e8G58Cd y7ofGAw8tWz4pR9sFII/VPOtjcG0D8WmKMgtZKKfoxLTwmbGG64OvMm8PdjNyhQ+pH4X TO/A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@crapouillou.net header.s=mail header.b=DEzFQ5dH; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=crapouillou.net Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id x4-20020a17090a8a8400b00240e633e032si6857103pjn.8.2023.04.03.09.05.31; Mon, 03 Apr 2023 09:05:53 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@crapouillou.net header.s=mail header.b=DEzFQ5dH; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=crapouillou.net Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232950AbjDCP5k (ORCPT + 99 others); Mon, 3 Apr 2023 11:57:40 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46818 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232932AbjDCP5Z (ORCPT ); Mon, 3 Apr 2023 11:57:25 -0400 Received: from aposti.net (aposti.net [89.234.176.197]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DC66C448E; Mon, 3 Apr 2023 08:56:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=crapouillou.net; s=mail; t=1680537006; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=WQ7k7KsV39QPGYjokDQtx5Buy0HkE7q//zbkWOqAhK8=; b=DEzFQ5dHQ52MTjpnNy7RIpuyYfglVdd9G+QCmQAVvx+THx1Dg3RcG9JdnozS0UiT+lI+RR CwJVsJsAsQoVJKd/Og7/j2Tt0PnG/Sny+C9Ea9H9gfozB95dYUVccWs0aEeC/OjeWUzyfq tjjtxRST8Z3B0Ek776+YV19sFnLRNGg= From: Paul Cercueil To: Jonathan Cameron , Lars-Peter Clausen , Vinod Koul , Michael Hennerich , =?utf-8?q?Nuno_S=C3=A1?= , Sumit Semwal , =?utf-8?q?Christian_K=C3=B6nig?= Cc: linux-kernel@vger.kernel.org, dmaengine@vger.kernel.org, linux-iio@vger.kernel.org, linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org, Paul Cercueil , Jonathan Corbet , linux-doc@vger.kernel.org Subject: [PATCH v3 11/11] Documentation: iio: Document high-speed DMABUF based API Date: Mon, 3 Apr 2023 17:49:55 +0200 Message-Id: <20230403154955.216148-2-paul@crapouillou.net> In-Reply-To: <20230403154955.216148-1-paul@crapouillou.net> References: <20230403154800.215924-1-paul@crapouillou.net> <20230403154955.216148-1-paul@crapouillou.net> MIME-Version: 1.0 X-Spam: Yes X-Spam-Status: No, score=-0.2 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_PASS,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1762171765273453622?= X-GMAIL-MSGID: =?utf-8?q?1762171765273453622?= Document the new DMABUF based API. Signed-off-by: Paul Cercueil Cc: Jonathan Corbet Cc: linux-doc@vger.kernel.org --- v2: - Explicitly state that the new interface is optional and is not implemented by all drivers. - The IOCTLs can now only be called on the buffer FD returned by IIO_BUFFER_GET_FD_IOCTL. - Move the page up a bit in the index since it is core stuff and not driver-specific. v3: Update the documentation to reflect the new API. --- Documentation/iio/dmabuf_api.rst | 59 ++++++++++++++++++++++++++++++++ Documentation/iio/index.rst | 2 ++ 2 files changed, 61 insertions(+) create mode 100644 Documentation/iio/dmabuf_api.rst diff --git a/Documentation/iio/dmabuf_api.rst b/Documentation/iio/dmabuf_api.rst new file mode 100644 index 000000000000..4d70372c7ebd --- /dev/null +++ b/Documentation/iio/dmabuf_api.rst @@ -0,0 +1,59 @@ +.. SPDX-License-Identifier: GPL-2.0 + +=================================== +High-speed DMABUF interface for IIO +=================================== + +1. Overview +=========== + +The Industrial I/O subsystem supports access to buffers through a +file-based interface, with read() and write() access calls through the +IIO device's dev node. + +It additionally supports a DMABUF based interface, where the userspace +can attach DMABUF objects (externally created) to a IIO buffer, and +subsequently use them for data transfers. + +A userspace application can then use this interface to share DMABUF +objects between several interfaces, allowing it to transfer data in a +zero-copy fashion, for instance between IIO and the USB stack. + +The userspace application can also memory-map the DMABUF objects, and +access the sample data directly. The advantage of doing this vs. the +read() interface is that it avoids an extra copy of the data between the +kernel and userspace. This is particularly useful for high-speed devices +which produce several megabytes or even gigabytes of data per second. +It does however increase the userspace-kernelspace synchronization +overhead, as the DMA_BUF_SYNC_START and DMA_BUF_SYNC_END IOCTLs have to +be used for data integrity. + +2. User API +=========== + +As part of this interface, three new IOCTLs have been added. These three +IOCTLs have to be performed on the IIO buffer's file descriptor, +obtained using the IIO_BUFFER_GET_FD_IOCTL() ioctl. + +``IIO_BUFFER_DMABUF_ATTACH_IOCTL(int)`` +---------------------------------------------------------------- + +Attach the DMABUF object, identified by its file descriptor, to the IIO +buffer. Returns zero on success, and a negative errno value on error. + +``IIO_BUFFER_DMABUF_DETACH_IOCTL(int)`` +-------------------------------------------------------- + +Detach the given DMABUF object, identified by its file descriptor, from +the IIO buffer. Returns zero on success, and a negative errno value on +error. + +Note that closing the IIO buffer's file descriptor will automatically +detach all previously attached DMABUF objects. + +``IIO_BUFFER_DMABUF_ENQUEUE_IOCTL(struct iio_dmabuf *iio_dmabuf)`` +-------------------------------------------------------- + +Enqueue a previously attached DMABUF object to the buffer queue. +Enqueued DMABUFs will be read from (if output buffer) or written to +(if input buffer) as long as the buffer is enabled. diff --git a/Documentation/iio/index.rst b/Documentation/iio/index.rst index 1b7292c58cd0..3eae8fcb1938 100644 --- a/Documentation/iio/index.rst +++ b/Documentation/iio/index.rst @@ -9,6 +9,8 @@ Industrial I/O iio_configfs + dmabuf_api + ep93xx_adc bno055