From patchwork Wed Jan 10 11:13:44 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Brown X-Patchwork-Id: 10154893 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id E974B605BA for ; Wed, 10 Jan 2018 11:14:30 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DB1E027C05 for ; Wed, 10 Jan 2018 11:14:30 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id CF86527F60; Wed, 10 Jan 2018 11:14:30 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DF05627DA4 for ; Wed, 10 Jan 2018 11:14:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S965238AbeAJLO1 (ORCPT ); Wed, 10 Jan 2018 06:14:27 -0500 Received: from heliosphere.sirena.org.uk ([172.104.155.198]:57920 "EHLO heliosphere.sirena.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755575AbeAJLOU (ORCPT ); Wed, 10 Jan 2018 06:14:20 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sirena.org.uk; s=20170815-heliosphere; h=Date:Message-Id:In-Reply-To: Subject:Cc:To:From:Sender:Reply-To:MIME-Version:Content-Type: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:References: List-Id:List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner: List-Archive; bh=oLI3jA44uHMMo1Z59YQaBzleb822Sd0wW6J9zm8JWuE=; b=H9vrCo3s83// oJNm+nQmbNUl0HWTvszZ9hzKl/CMt9v+FLRQ6Rq7uvg5dUhv24lK9DIk54vjGjw2golaaAoHzaxn/ u5jv3o3UbAM3OK9y3JbImpUHdkY6GLMeWT7sUR+JKlqfAzP+NAPnOHzTw+o/2KrQNdbocV9QZAjI4 /bnAk=; Received: from debutante.sirena.org.uk ([2001:470:1f1d:6b5::3] helo=debutante) by heliosphere.sirena.org.uk with esmtpsa (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.89) (envelope-from ) id 1eZEKH-0000lV-Jb; Wed, 10 Jan 2018 11:13:45 +0000 Received: from broonie by debutante with local (Exim 4.90) (envelope-from ) id 1eZEKG-000552-6y; Wed, 10 Jan 2018 11:13:44 +0000 From: Mark Brown To: Lars-Peter Clausen Cc: Arnaud Pouliquen , Mark Brown , Rob Herring , Mark Rutland , Jonathan Cameron , Hartmut Knaack , Peter Meerwald-Stadler , Jaroslav Kysela , Takashi Iwai , Liam Girdwood , Mark Brown , devicetree@vger.kernel.org, alsa-devel@alsa-project.org, Alexandre Torgue , linux-iio@vger.kernel.org, arnaud.pouliquen@st.com, Maxime Coquelin , linux-arm-kernel@lists.infradead.org, alsa-devel@alsa-project.org Subject: Applied "iio: Add hardware consumer buffer support" to the asoc tree In-Reply-To: <1512744566-13233-2-git-send-email-arnaud.pouliquen@st.com> Message-Id: Date: Wed, 10 Jan 2018 11:13:44 +0000 Sender: linux-iio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The patch iio: Add hardware consumer buffer support has been applied to the asoc tree at https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted. You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed. If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced. Please add any relevant lists and maintainers to the CCs when replying to this mail. Thanks, Mark From 48b66f8f936f369bb1a43c12aedbfeb2975baf4c Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 10 Jan 2018 11:13:03 +0100 Subject: [PATCH] iio: Add hardware consumer buffer support Hardware consumer interface can be used when one IIO device has a direct connection to another device in hardware. Signed-off-by: Lars-Peter Clausen Signed-off-by: Arnaud Pouliquen Reviewed-by: Jonathan Cameron Signed-off-by: Mark Brown --- drivers/iio/buffer/Kconfig | 10 ++ drivers/iio/buffer/Makefile | 1 + drivers/iio/buffer/industrialio-hw-consumer.c | 181 ++++++++++++++++++++++++++ include/linux/iio/hw-consumer.h | 19 +++ 4 files changed, 211 insertions(+) create mode 100644 drivers/iio/buffer/industrialio-hw-consumer.c create mode 100644 include/linux/iio/hw-consumer.h diff --git a/drivers/iio/buffer/Kconfig b/drivers/iio/buffer/Kconfig index 4ffd3db7817f..338774cba19b 100644 --- a/drivers/iio/buffer/Kconfig +++ b/drivers/iio/buffer/Kconfig @@ -29,6 +29,16 @@ config IIO_BUFFER_DMAENGINE Should be selected by drivers that want to use this functionality. +config IIO_BUFFER_HW_CONSUMER + tristate "Industrial I/O HW buffering" + help + Provides a way to bonding when an IIO device has a direct connection + to another device in hardware. In this case buffers for data transfers + are handled by hardware. + + Should be selected by drivers that want to use the generic Hw consumer + interface. + config IIO_KFIFO_BUF tristate "Industrial I/O buffering based on kfifo" help diff --git a/drivers/iio/buffer/Makefile b/drivers/iio/buffer/Makefile index 95f9f41c58b7..1403eb2f9409 100644 --- a/drivers/iio/buffer/Makefile +++ b/drivers/iio/buffer/Makefile @@ -7,5 +7,6 @@ obj-$(CONFIG_IIO_BUFFER_CB) += industrialio-buffer-cb.o obj-$(CONFIG_IIO_BUFFER_DMA) += industrialio-buffer-dma.o obj-$(CONFIG_IIO_BUFFER_DMAENGINE) += industrialio-buffer-dmaengine.o +obj-$(CONFIG_IIO_BUFFER_HW_CONSUMER) += industrialio-hw-consumer.o obj-$(CONFIG_IIO_TRIGGERED_BUFFER) += industrialio-triggered-buffer.o obj-$(CONFIG_IIO_KFIFO_BUF) += kfifo_buf.o diff --git a/drivers/iio/buffer/industrialio-hw-consumer.c b/drivers/iio/buffer/industrialio-hw-consumer.c new file mode 100644 index 000000000000..993ecdcdab64 --- /dev/null +++ b/drivers/iio/buffer/industrialio-hw-consumer.c @@ -0,0 +1,181 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2017 Analog Devices Inc. + * Author: Lars-Peter Clausen + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +/** + * struct iio_hw_consumer - IIO hw consumer block + * @buffers: hardware buffers list head. + * @channels: IIO provider channels. + */ +struct iio_hw_consumer { + struct list_head buffers; + struct iio_channel *channels; +}; + +struct hw_consumer_buffer { + struct list_head head; + struct iio_dev *indio_dev; + struct iio_buffer buffer; + long scan_mask[]; +}; + +static struct hw_consumer_buffer *iio_buffer_to_hw_consumer_buffer( + struct iio_buffer *buffer) +{ + return container_of(buffer, struct hw_consumer_buffer, buffer); +} + +static void iio_hw_buf_release(struct iio_buffer *buffer) +{ + struct hw_consumer_buffer *hw_buf = + iio_buffer_to_hw_consumer_buffer(buffer); + kfree(hw_buf); +} + +static const struct iio_buffer_access_funcs iio_hw_buf_access = { + .release = &iio_hw_buf_release, + .modes = INDIO_BUFFER_HARDWARE, +}; + +static struct hw_consumer_buffer *iio_hw_consumer_get_buffer( + struct iio_hw_consumer *hwc, struct iio_dev *indio_dev) +{ + size_t mask_size = BITS_TO_LONGS(indio_dev->masklength) * sizeof(long); + struct hw_consumer_buffer *buf; + + list_for_each_entry(buf, &hwc->buffers, head) { + if (buf->indio_dev == indio_dev) + return buf; + } + + buf = kzalloc(sizeof(*buf) + mask_size, GFP_KERNEL); + if (!buf) + return NULL; + + buf->buffer.access = &iio_hw_buf_access; + buf->indio_dev = indio_dev; + buf->buffer.scan_mask = buf->scan_mask; + + iio_buffer_init(&buf->buffer); + list_add_tail(&buf->head, &hwc->buffers); + + return buf; +} + +/** + * iio_hw_consumer_alloc() - Allocate IIO hardware consumer + * @dev: Pointer to consumer device. + * + * Returns a valid iio_hw_consumer on success or a ERR_PTR() on failure. + */ +struct iio_hw_consumer *iio_hw_consumer_alloc(struct device *dev) +{ + struct hw_consumer_buffer *buf; + struct iio_hw_consumer *hwc; + struct iio_channel *chan; + int ret; + + hwc = kzalloc(sizeof(*hwc), GFP_KERNEL); + if (!hwc) + return ERR_PTR(-ENOMEM); + + INIT_LIST_HEAD(&hwc->buffers); + + hwc->channels = iio_channel_get_all(dev); + if (IS_ERR(hwc->channels)) { + ret = PTR_ERR(hwc->channels); + goto err_free_hwc; + } + + chan = &hwc->channels[0]; + while (chan->indio_dev) { + buf = iio_hw_consumer_get_buffer(hwc, chan->indio_dev); + if (!buf) { + ret = -ENOMEM; + goto err_put_buffers; + } + set_bit(chan->channel->scan_index, buf->buffer.scan_mask); + chan++; + } + + return hwc; + +err_put_buffers: + list_for_each_entry(buf, &hwc->buffers, head) + iio_buffer_put(&buf->buffer); + iio_channel_release_all(hwc->channels); +err_free_hwc: + kfree(hwc); + return ERR_PTR(ret); +} +EXPORT_SYMBOL_GPL(iio_hw_consumer_alloc); + +/** + * iio_hw_consumer_free() - Free IIO hardware consumer + * @hwc: hw consumer to free. + */ +void iio_hw_consumer_free(struct iio_hw_consumer *hwc) +{ + struct hw_consumer_buffer *buf, *n; + + iio_channel_release_all(hwc->channels); + list_for_each_entry_safe(buf, n, &hwc->buffers, head) + iio_buffer_put(&buf->buffer); + kfree(hwc); +} +EXPORT_SYMBOL_GPL(iio_hw_consumer_free); + +/** + * iio_hw_consumer_enable() - Enable IIO hardware consumer + * @hwc: iio_hw_consumer to enable. + * + * Returns 0 on success. + */ +int iio_hw_consumer_enable(struct iio_hw_consumer *hwc) +{ + struct hw_consumer_buffer *buf; + int ret; + + list_for_each_entry(buf, &hwc->buffers, head) { + ret = iio_update_buffers(buf->indio_dev, &buf->buffer, NULL); + if (ret) + goto err_disable_buffers; + } + + return 0; + +err_disable_buffers: + list_for_each_entry_continue_reverse(buf, &hwc->buffers, head) + iio_update_buffers(buf->indio_dev, NULL, &buf->buffer); + return ret; +} +EXPORT_SYMBOL_GPL(iio_hw_consumer_enable); + +/** + * iio_hw_consumer_disable() - Disable IIO hardware consumer + * @hwc: iio_hw_consumer to disable. + */ +void iio_hw_consumer_disable(struct iio_hw_consumer *hwc) +{ + struct hw_consumer_buffer *buf; + + list_for_each_entry(buf, &hwc->buffers, head) + iio_update_buffers(buf->indio_dev, NULL, &buf->buffer); +} +EXPORT_SYMBOL_GPL(iio_hw_consumer_disable); + +MODULE_AUTHOR("Lars-Peter Clausen "); +MODULE_DESCRIPTION("Hardware consumer buffer the IIO framework"); +MODULE_LICENSE("GPL v2"); diff --git a/include/linux/iio/hw-consumer.h b/include/linux/iio/hw-consumer.h new file mode 100644 index 000000000000..db8c00b9c7a5 --- /dev/null +++ b/include/linux/iio/hw-consumer.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Industrial I/O in kernel hardware consumer interface + * + * Copyright 2017 Analog Devices Inc. + * Author: Lars-Peter Clausen + */ + +#ifndef LINUX_IIO_HW_CONSUMER_H +#define LINUX_IIO_HW_CONSUMER_H + +struct iio_hw_consumer; + +struct iio_hw_consumer *iio_hw_consumer_alloc(struct device *dev); +void iio_hw_consumer_free(struct iio_hw_consumer *hwc); +int iio_hw_consumer_enable(struct iio_hw_consumer *hwc); +void iio_hw_consumer_disable(struct iio_hw_consumer *hwc); + +#endif