Re: [PATCH v2 8/9] ALSA: virtio: introduce PCM channel map support

2021-01-26 Thread Guennadi Liakhovetski



On Sun, 24 Jan 2021, Anton Yakovlev wrote:


Enumerate all available PCM channel maps and create ALSA controls.

Signed-off-by: Anton Yakovlev 
---
sound/virtio/Makefile   |   1 +
sound/virtio/virtio_card.c  |  15 +++
sound/virtio/virtio_card.h  |   8 ++
sound/virtio/virtio_chmap.c | 237 
sound/virtio/virtio_pcm.h   |   4 +
5 files changed, 265 insertions(+)
create mode 100644 sound/virtio/virtio_chmap.c


[snip]


diff --git a/sound/virtio/virtio_chmap.c b/sound/virtio/virtio_chmap.c
new file mode 100644
index ..8a2ddc4dcffb
--- /dev/null
+++ b/sound/virtio/virtio_chmap.c
@@ -0,0 +1,237 @@


[snip]


+/**
+ * virtsnd_chmap_parse_cfg() - Parse the channel map configuration.
+ * @snd: VirtIO sound device.
+ *
+ * This function is called during initial device initialization.
+ *
+ * Context: Any context that permits to sleep.
+ * Return: 0 on success, -errno on failure.
+ */
+int virtsnd_chmap_parse_cfg(struct virtio_snd *snd)
+{
+   struct virtio_device *vdev = snd->vdev;
+   unsigned int i;
+   int rc;
+
+   virtio_cread(vdev, struct virtio_snd_config, chmaps, &snd->nchmaps);
+   if (!snd->nchmaps)
+   return 0;
+
+   snd->chmaps = devm_kcalloc(&vdev->dev, snd->nchmaps,
+  sizeof(*snd->chmaps), GFP_KERNEL);
+   if (!snd->chmaps)
+   return -ENOMEM;
+
+   rc = virtsnd_ctl_query_info(snd, VIRTIO_SND_R_CHMAP_INFO, 0,
+   snd->nchmaps, sizeof(*snd->chmaps),
+   snd->chmaps);
+   if (rc)
+   return rc;
+
+   /* Count the number of channel maps per each PCM device/stream. */
+   for (i = 0; i < snd->nchmaps; ++i) {
+   struct virtio_snd_chmap_info *info = &snd->chmaps[i];
+   unsigned int nid = le32_to_cpu(info->hdr.hda_fn_nid);
+   struct virtio_pcm *pcm;
+   struct virtio_pcm_stream *stream;
+
+   pcm = virtsnd_pcm_find_or_create(snd, nid);
+   if (IS_ERR(pcm))
+   return PTR_ERR(pcm);
+
+   switch (info->direction) {
+   case VIRTIO_SND_D_OUTPUT: {
+   stream = &pcm->streams[SNDRV_PCM_STREAM_PLAYBACK];
+   break;
+   }
+   case VIRTIO_SND_D_INPUT: {
+   stream = &pcm->streams[SNDRV_PCM_STREAM_CAPTURE];
+   break;
+   }
+   default: {
+   dev_err(&vdev->dev,
+   "chmap #%u: unknown direction (%u)\n", i,
+   info->direction);
+   return -EINVAL;
+   }
+   }
+
+   stream->nchmaps++;
+   }
+
+   return 0;
+}
+
+/**
+ * virtsnd_chmap_add_ctls() - Create an ALSA control for channel maps.
+ * @pcm: ALSA PCM device.
+ * @direction: PCM stream direction (SNDRV_PCM_STREAM_XXX).
+ * @stream: VirtIO PCM stream.
+ *
+ * Context: Any context.
+ * Return: 0 on success, -errno on failure.
+ */
+static int virtsnd_chmap_add_ctls(struct snd_pcm *pcm, int direction,
+ struct virtio_pcm_stream *stream)
+{
+   unsigned int i;
+   int max_channels = 0;
+
+   for (i = 0; i < stream->nchmaps; i++)
+   if (max_channels < stream->chmaps[i].channels)
+   max_channels = stream->chmaps[i].channels;
+
+   return snd_pcm_add_chmap_ctls(pcm, direction, stream->chmaps,
+ max_channels, 0, NULL);
+}
+
+/**
+ * virtsnd_chmap_build_devs() - Build ALSA controls for channel maps.
+ * @snd: VirtIO sound device.
+ *
+ * Context: Any context.
+ * Return: 0 on success, -errno on failure.
+ */
+int virtsnd_chmap_build_devs(struct virtio_snd *snd)
+{
+   struct virtio_device *vdev = snd->vdev;
+   struct virtio_pcm *pcm;
+   struct virtio_pcm_stream *stream;
+   unsigned int i;
+   int rc;
+
+   /* Allocate channel map elements per each PCM device/stream. */
+   list_for_each_entry(pcm, &snd->pcm_list, list) {
+   for (i = 0; i < ARRAY_SIZE(pcm->streams); ++i) {
+   stream = &pcm->streams[i];
+
+   if (!stream->nchmaps)
+   continue;
+
+   stream->chmaps = devm_kcalloc(&vdev->dev,
+ stream->nchmaps + 1,
+ sizeof(*stream->chmaps),
+ GFP_KERNEL);
+   if (!stream->chmaps)
+   return -ENOMEM;
+
+   stream->nchmaps = 0;
+   }
+   }
+
+   /* Initialize channel maps per each PCM device/stream. */
+   for (i = 0; i < snd->nchmaps; ++i) {
+   struct virtio_snd_chma

Re: [PATCH v2 7/9] ALSA: virtio: introduce jack support

2021-01-26 Thread Guennadi Liakhovetski



On Sun, 24 Jan 2021, Anton Yakovlev wrote:


Enumerate all available jacks and create ALSA controls.

At the moment jacks have a simple implementation and can only be used
to receive notifications about a plugged in/out device.

Signed-off-by: Anton Yakovlev 
---
sound/virtio/Makefile  |   1 +
sound/virtio/virtio_card.c |  18 +++
sound/virtio/virtio_card.h |  12 ++
sound/virtio/virtio_jack.c | 255 +
4 files changed, 286 insertions(+)
create mode 100644 sound/virtio/virtio_jack.c


[snip]


diff --git a/sound/virtio/virtio_jack.c b/sound/virtio/virtio_jack.c
new file mode 100644
index ..83593c59f6bf
--- /dev/null
+++ b/sound/virtio/virtio_jack.c
@@ -0,0 +1,255 @@


[snip]


+/**
+ * virtsnd_jack_parse_cfg() - Parse the jack configuration.
+ * @snd: VirtIO sound device.
+ *
+ * This function is called during initial device initialization.
+ *
+ * Context: Any context that permits to sleep.
+ * Return: 0 on success, -errno on failure.
+ */
+int virtsnd_jack_parse_cfg(struct virtio_snd *snd)
+{
+   struct virtio_device *vdev = snd->vdev;
+   struct virtio_snd_jack_info *info;
+   unsigned int i;
+   int rc;
+
+   virtio_cread(vdev, struct virtio_snd_config, jacks, &snd->njacks);
+   if (!snd->njacks)
+   return 0;
+
+   snd->jacks = devm_kcalloc(&vdev->dev, snd->njacks, sizeof(*snd->jacks),
+ GFP_KERNEL);
+   if (!snd->jacks)
+   return -ENOMEM;
+
+   info = devm_kcalloc(&vdev->dev, snd->njacks, sizeof(*info), GFP_KERNEL);


just kcalloc()


+   if (!info)
+   return -ENOMEM;
+
+   rc = virtsnd_ctl_query_info(snd, VIRTIO_SND_R_JACK_INFO, 0, snd->njacks,
+   sizeof(*info), info);
+   if (rc)
+   return rc;
+
+   for (i = 0; i < snd->njacks; ++i) {
+   struct virtio_jack *jack = &snd->jacks[i];
+   struct virtio_pcm *pcm;
+
+   jack->nid = le32_to_cpu(info[i].hdr.hda_fn_nid);
+   jack->features = le32_to_cpu(info[i].features);
+   jack->defconf = le32_to_cpu(info[i].hda_reg_defconf);
+   jack->caps = le32_to_cpu(info[i].hda_reg_caps);
+   jack->connected = info[i].connected;
+
+   pcm = virtsnd_pcm_find_or_create(snd, jack->nid);
+   if (IS_ERR(pcm))
+   return PTR_ERR(pcm);
+   }
+
+   devm_kfree(&vdev->dev, info);
+
+   return 0;
+}


Thanks
Guennadi


Re: [PATCH v2 6/9] ALSA: virtio: PCM substream operators

2021-01-26 Thread Guennadi Liakhovetski

One more thing I missed yesterday:

On Mon, 25 Jan 2021, Guennadi Liakhovetski wrote:



On Sun, 24 Jan 2021, Anton Yakovlev wrote:


Introduce the operators required for the operation of substreams.

Signed-off-by: Anton Yakovlev 
---
sound/virtio/Makefile |   3 +-
sound/virtio/virtio_pcm.c |   5 +-
sound/virtio/virtio_pcm.h |   2 +
sound/virtio/virtio_pcm_ops.c | 513 ++
4 files changed, 521 insertions(+), 2 deletions(-)
create mode 100644 sound/virtio/virtio_pcm_ops.c


[snip]


diff --git a/sound/virtio/virtio_pcm_ops.c b/sound/virtio/virtio_pcm_ops.c
new file mode 100644
index ..19882777fcd6
--- /dev/null
+++ b/sound/virtio/virtio_pcm_ops.c
@@ -0,0 +1,513 @@


[snip]


+/**
+ * virtsnd_pcm_release() - Release the PCM substream on the device side.
+ * @substream: VirtIO substream.
+ *
+ * Context: Any context that permits to sleep.
+ * Return: 0 on success, -errno on failure.
+ */
+static inline bool virtsnd_pcm_released(struct virtio_pcm_substream 
*substream)

+{
+   /*
+	 * The spec states that upon receipt of the RELEASE command "the 
device
+	 * MUST complete all pending I/O messages for the specified stream 
ID".

+* Thus, we consider the absence of I/O messages in the queue as an
+* indication that the substream has been released.
+*/
+   return atomic_read(&substream->msg_count) == 0;


Also here having it atomic doesn't really seem to help. This just means, that 
at some point of time it was == 0.



+}
+
+static int virtsnd_pcm_release(struct virtio_pcm_substream *substream)


kernel-doc missing


+{
+   struct virtio_snd *snd = substream->snd;
+   struct virtio_snd_msg *msg;
+   unsigned int js = msecs_to_jiffies(msg_timeout_ms);
+   int rc;
+
+   msg = virtsnd_pcm_ctl_msg_alloc(substream, VIRTIO_SND_R_PCM_RELEASE,
+   GFP_KERNEL);
+   if (IS_ERR(msg))
+   return PTR_ERR(msg);
+
+   rc = virtsnd_ctl_msg_send_sync(snd, msg);
+   if (rc)
+   return rc;
+
+   return wait_event_interruptible_timeout(substream->msg_empty,
+   virtsnd_pcm_released(substream),
+   js);


wait_event_interruptible_timeout() will return a positive number in 
success cases, 0 means a timeout and condition still false. Whereas when 
you call this function you interpret 0 as success and you expect any != 0 
to be a negative error. Wondering how this worked during your tests?


Thanks
Guennadi


Re: [PATCH v2 3/9] ALSA: virtio: handling control messages

2021-01-25 Thread Guennadi Liakhovetski
I think the use of (devm_)kmalloc() and friends needs some refinement in 
several patches in the series.


On Sun, 24 Jan 2021, Anton Yakovlev wrote:


The control queue can be used by different parts of the driver to send
commands to the device. Control messages can be either synchronous or
asynchronous. The lifetime of a message is controlled by a reference
count.

Introduce a module parameter to set the message completion timeout:
 msg_timeout_ms [=1000]

Signed-off-by: Anton Yakovlev 
---
sound/virtio/Makefile |   3 +-
sound/virtio/virtio_card.c|  20 +++
sound/virtio/virtio_card.h|   7 +
sound/virtio/virtio_ctl_msg.c | 293 ++
sound/virtio/virtio_ctl_msg.h | 122 ++
5 files changed, 444 insertions(+), 1 deletion(-)
create mode 100644 sound/virtio/virtio_ctl_msg.c
create mode 100644 sound/virtio/virtio_ctl_msg.h


[snip]


diff --git a/sound/virtio/virtio_ctl_msg.c b/sound/virtio/virtio_ctl_msg.c
new file mode 100644
index ..c1701756bc32
--- /dev/null
+++ b/sound/virtio/virtio_ctl_msg.c
@@ -0,0 +1,293 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Sound card driver for virtio
+ * Copyright (C) 2020  OpenSynergy GmbH
+ *
+ * This program is free software; you can redistribute it and/or modify


Same comment about licence, and in other patches as well.


+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see .
+ */
+#include 
+#include 
+
+#include "virtio_card.h"
+#include "virtio_ctl_msg.h"
+
+/**
+ * virtsnd_ctl_msg_alloc_ext() - Allocate and initialize a control message.
+ * @vdev: VirtIO parent device.
+ * @request_size: Size of request header (pointed to by sg_request field).
+ * @response_size: Size of response header (pointed to by sg_response field).
+ * @sgs: Additional data to attach to the message (may be NULL).
+ * @out_sgs: Number of scattergather elements to attach to the request header.
+ * @in_sgs: Number of scattergather elements to attach to the response header.
+ * @gfp: Kernel flags for memory allocation.
+ *
+ * The message will be automatically freed when the ref_count value is 0.
+ *
+ * Context: Any context. May sleep if @gfp flags permit.
+ * Return: Allocated message on success, ERR_PTR(-errno) on failure.
+ */
+struct virtio_snd_msg *virtsnd_ctl_msg_alloc_ext(struct virtio_device *vdev,
+size_t request_size,
+size_t response_size,
+struct scatterlist *sgs,
+unsigned int out_sgs,
+unsigned int in_sgs, gfp_t gfp)
+{
+   struct virtio_snd_msg *msg;
+   size_t msg_size =
+   sizeof(*msg) + (1 + out_sgs + 1 + in_sgs) * sizeof(*msg->sgs);
+   unsigned int i;
+
+   msg = devm_kzalloc(&vdev->dev, msg_size + request_size + response_size,
+  gfp);


Messages are short-lived, right? So, I think their allocation and freeing 
has to be explicit, no need for devm_.



+   if (!msg)
+   return ERR_PTR(-ENOMEM);
+
+   sg_init_one(&msg->sg_request, (u8 *)msg + msg_size, request_size);
+   sg_init_one(&msg->sg_response, (u8 *)msg + msg_size + request_size,
+   response_size);
+
+   INIT_LIST_HEAD(&msg->list);
+   init_completion(&msg->notify);
+   atomic_set(&msg->ref_count, 1);
+
+   msg->sgs[msg->out_sgs++] = &msg->sg_request;
+   if (sgs)
+   for (i = 0; i < out_sgs; ++i)
+   msg->sgs[msg->out_sgs++] = &sgs[i];
+
+   msg->sgs[msg->out_sgs + msg->in_sgs++] = &msg->sg_response;
+   if (sgs)
+   for (i = out_sgs; i < out_sgs + in_sgs; ++i)
+   msg->sgs[msg->out_sgs + msg->in_sgs++] = &sgs[i];
+
+   return msg;
+}
+
+/**
+ * virtsnd_ctl_msg_send() - Send an (asynchronous) control message.
+ * @snd: VirtIO sound device.
+ * @msg: Control message.
+ *
+ * If a message is failed to be enqueued, it will be deleted. If message 
content
+ * is still needed, the caller must additionally to virtsnd_ctl_msg_ref/unref()
+ * it.
+ *
+ * Context: Any context. Takes and releases the control queue spinlock.
+ * Return: 0 on success, -errno on failure.
+ */
+int virtsnd_ctl_msg_send(struct virtio_snd *snd, struct virtio_snd_msg *msg)
+{
+   struct virtio_device *vdev = snd->vdev;
+   struct virti

Re: [PATCH v2 2/9] ALSA: virtio: add virtio sound driver

2021-01-25 Thread Guennadi Liakhovetski

Hi Anton,

A couple of mostly cosmetic comments inline.

On Sun, 24 Jan 2021, Anton Yakovlev wrote:


Introduce skeleton of the virtio sound driver. The driver implements
the virtio sound device specification, which has become part of the
virtio standard.

Initial initialization of the device, virtqueues and creation of an
empty ALSA sound device. Also, handling DEVICE_NEEDS_RESET device
status.

Signed-off-by: Anton Yakovlev 
---
MAINTAINERS |   9 +
include/uapi/linux/virtio_snd.h | 361 +++
sound/Kconfig   |   2 +
sound/Makefile  |   3 +-
sound/virtio/Kconfig|  10 +
sound/virtio/Makefile   |   7 +
sound/virtio/virtio_card.c  | 415 
sound/virtio/virtio_card.h  |  76 ++
8 files changed, 882 insertions(+), 1 deletion(-)
create mode 100644 include/uapi/linux/virtio_snd.h
create mode 100644 sound/virtio/Kconfig
create mode 100644 sound/virtio/Makefile
create mode 100644 sound/virtio/virtio_card.c
create mode 100644 sound/virtio/virtio_card.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 00836f6452f0..3f509d54a457 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -18936,6 +18936,15 @@ W: https://virtio-mem.gitlab.io/
F:  drivers/virtio/virtio_mem.c
F:  include/uapi/linux/virtio_mem.h

+VIRTIO SOUND DRIVER
+M: Anton Yakovlev 
+M: "Michael S. Tsirkin" 
+L: virtualizat...@lists.linux-foundation.org
+L: alsa-de...@alsa-project.org (moderated for non-subscribers)
+S: Maintained
+F: include/uapi/linux/virtio_snd.h
+F: sound/virtio/*
+
VIRTUAL BOX GUEST DEVICE DRIVER
M:  Hans de Goede 
M:  Arnd Bergmann 
diff --git a/include/uapi/linux/virtio_snd.h b/include/uapi/linux/virtio_snd.h
new file mode 100644
index ..1ff6310e54d6
--- /dev/null
+++ b/include/uapi/linux/virtio_snd.h
@@ -0,0 +1,361 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Copyright (C) 2020  OpenSynergy GmbH
+ *
+ * This header is BSD licensed so anyone can use the definitions to
+ * implement compatible drivers/servers.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:


Can a BSD licence actually be further restricted?


+ * 1. Redistributions of source code must retain the above copyright
+ *notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *notice, this list of conditions and the following disclaimer in the
+ *documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of OpenSynergy GmbH nor the names of its contributors
+ *may be used to endorse or promote products derived from this software
+ *without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL IBM OR


IBM? Also no idea whether this warranty disclaimer is appropriate here. I 
thought we were transitioning to those SPDX identifiers to eliminate all 
these headers.



+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */


[snip]


diff --git a/sound/virtio/virtio_card.c b/sound/virtio/virtio_card.c
new file mode 100644
index ..532d823fdf6f
--- /dev/null
+++ b/sound/virtio/virtio_card.c
@@ -0,0 +1,415 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Sound card driver for virtio
+ * Copyright (C) 2020  OpenSynergy GmbH
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.


Same here, I think SPDX means you don't need all this here any more.


+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see .
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "virtio_card.h"
+
+sta

Re: [PATCH v2 4/9] ALSA: virtio: build PCM devices and substream hardware descriptors

2021-01-25 Thread Guennadi Liakhovetski



On Sun, 24 Jan 2021, Anton Yakovlev wrote:


Like the HDA specification, the virtio sound device specification links
PCM substreams, jacks and PCM channel maps into functional groups. For
each discovered group, a PCM device is created, the number of which
coincides with the group number.

Introduce the module parameters for setting the hardware buffer
parameters:
 pcm_buffer_ms [=160]
 pcm_periods_min [=2]
 pcm_periods_max [=16]
 pcm_period_ms_min [=10]
 pcm_period_ms_max [=80]

Signed-off-by: Anton Yakovlev 
---
sound/virtio/Makefile  |   3 +-
sound/virtio/virtio_card.c |  45 
sound/virtio/virtio_card.h |   9 +
sound/virtio/virtio_pcm.c  | 536 +
sound/virtio/virtio_pcm.h  |  89 ++
5 files changed, 681 insertions(+), 1 deletion(-)
create mode 100644 sound/virtio/virtio_pcm.c
create mode 100644 sound/virtio/virtio_pcm.h

diff --git a/sound/virtio/Makefile b/sound/virtio/Makefile
index dc551e637441..69162a545a41 100644
--- a/sound/virtio/Makefile
+++ b/sound/virtio/Makefile
@@ -4,5 +4,6 @@ obj-$(CONFIG_SND_VIRTIO) += virtio_snd.o

virtio_snd-objs := \
virtio_card.o \
-   virtio_ctl_msg.o
+   virtio_ctl_msg.o \
+   virtio_pcm.o

diff --git a/sound/virtio/virtio_card.c b/sound/virtio/virtio_card.c
index 955eadc2d858..39fe13b43dd1 100644
--- a/sound/virtio/virtio_card.c
+++ b/sound/virtio/virtio_card.c
@@ -92,6 +92,17 @@ static void virtsnd_event_notify_cb(struct virtqueue *vqueue)
if (!event)
break;

+   switch (le32_to_cpu(event->hdr.code)) {
+   case VIRTIO_SND_EVT_PCM_PERIOD_ELAPSED:
+   case VIRTIO_SND_EVT_PCM_XRUN: {


In the previous patch you had a switch-case statement complying to the 
common kernel coding style. It isn't specified in coding-style.rst, but 
these superfluous braces really don't seem to be good for anything - in 
this and multiple other switch-case statements in the series.



+   virtsnd_pcm_event(snd, event);
+   break;
+   }
+   default: {
+   break;


An empty default doesn't seem very useful either. So the above could've 
just been


+   switch (le32_to_cpu(event->hdr.code)) {
+   case VIRTIO_SND_EVT_PCM_PERIOD_ELAPSED:
+   case VIRTIO_SND_EVT_PCM_XRUN:
+   virtsnd_pcm_event(snd, event);
+   }


+   }
+   }
+
virtsnd_event_send(queue->vqueue, event, true,
   GFP_ATOMIC);
}
@@ -274,6 +285,16 @@ static int virtsnd_build_devs(struct virtio_snd *snd)
strscpy(snd->card->longname, "VirtIO Sound Card",
sizeof(snd->card->longname));

+   rc = virtsnd_pcm_parse_cfg(snd);
+   if (rc)
+   return rc;
+
+   if (snd->nsubstreams) {
+   rc = virtsnd_pcm_build_devs(snd);
+   if (rc)
+   return rc;
+   }
+
return snd_card_register(snd->card);
}

@@ -302,6 +323,9 @@ static int virtsnd_validate(struct virtio_device *vdev)
return -EINVAL;
}

+   if (virtsnd_pcm_validate(vdev))
+   return -EINVAL;
+
return 0;
}

@@ -325,6 +349,7 @@ static int virtsnd_probe(struct virtio_device *vdev)
snd->vdev = vdev;
INIT_WORK(&snd->reset_work, virtsnd_reset_fn);
INIT_LIST_HEAD(&snd->ctl_msgs);
+   INIT_LIST_HEAD(&snd->pcm_list);

vdev->priv = snd;

@@ -359,6 +384,8 @@ static int virtsnd_probe(struct virtio_device *vdev)
static void virtsnd_remove(struct virtio_device *vdev)
{
struct virtio_snd *snd = vdev->priv;
+   struct virtio_pcm *pcm;
+   struct virtio_pcm *pcm_next;

if (!snd)
return;
@@ -376,6 +403,24 @@ static void virtsnd_remove(struct virtio_device *vdev)
vdev->config->reset(vdev);
vdev->config->del_vqs(vdev);

+   list_for_each_entry_safe(pcm, pcm_next, &snd->pcm_list, list) {
+   unsigned int i;
+
+   list_del(&pcm->list);
+
+   for (i = 0; i < ARRAY_SIZE(pcm->streams); ++i) {
+   struct virtio_pcm_stream *stream = &pcm->streams[i];
+
+   if (stream->substreams)
+   devm_kfree(&vdev->dev, stream->substreams);
+   }
+
+   devm_kfree(&vdev->dev, pcm);


Please double-check both devm_kfree() calls above. Probably they aren't 
needed in the .remove() method.



+   }
+
+   if (snd->substreams)
+   devm_kfree(&vdev->dev, snd->substreams);
+
devm_kfree(&vdev->dev, snd);

vdev->priv = NULL;
diff --git a/sound/virtio/virtio_card.h b/sound/virtio/virtio_card.h
index 37b734a92134..

Re: [PATCH v2 6/9] ALSA: virtio: PCM substream operators

2021-01-25 Thread Guennadi Liakhovetski



On Sun, 24 Jan 2021, Anton Yakovlev wrote:


Introduce the operators required for the operation of substreams.

Signed-off-by: Anton Yakovlev 
---
sound/virtio/Makefile |   3 +-
sound/virtio/virtio_pcm.c |   5 +-
sound/virtio/virtio_pcm.h |   2 +
sound/virtio/virtio_pcm_ops.c | 513 ++
4 files changed, 521 insertions(+), 2 deletions(-)
create mode 100644 sound/virtio/virtio_pcm_ops.c


[snip]


diff --git a/sound/virtio/virtio_pcm_ops.c b/sound/virtio/virtio_pcm_ops.c
new file mode 100644
index ..19882777fcd6
--- /dev/null
+++ b/sound/virtio/virtio_pcm_ops.c
@@ -0,0 +1,513 @@


[snip]


+/**
+ * virtsnd_pcm_release() - Release the PCM substream on the device side.
+ * @substream: VirtIO substream.
+ *
+ * Context: Any context that permits to sleep.
+ * Return: 0 on success, -errno on failure.
+ */
+static inline bool virtsnd_pcm_released(struct virtio_pcm_substream *substream)
+{
+   /*
+* The spec states that upon receipt of the RELEASE command "the device
+* MUST complete all pending I/O messages for the specified stream ID".
+* Thus, we consider the absence of I/O messages in the queue as an
+* indication that the substream has been released.
+*/
+   return atomic_read(&substream->msg_count) == 0;


Also here having it atomic doesn't really seem to help. This just means, 
that at some point of time it was == 0.



+}
+
+static int virtsnd_pcm_release(struct virtio_pcm_substream *substream)


kernel-doc missing


+{
+   struct virtio_snd *snd = substream->snd;
+   struct virtio_snd_msg *msg;
+   unsigned int js = msecs_to_jiffies(msg_timeout_ms);
+   int rc;
+
+   msg = virtsnd_pcm_ctl_msg_alloc(substream, VIRTIO_SND_R_PCM_RELEASE,
+   GFP_KERNEL);
+   if (IS_ERR(msg))
+   return PTR_ERR(msg);
+
+   rc = virtsnd_ctl_msg_send_sync(snd, msg);
+   if (rc)
+   return rc;
+
+   return wait_event_interruptible_timeout(substream->msg_empty,
+   virtsnd_pcm_released(substream),
+   js);
+}
+
+/**
+ * virtsnd_pcm_open() - Open the PCM substream.
+ * @substream: Kernel ALSA substream.
+ *
+ * Context: Any context.
+ * Return: 0 on success, -errno on failure.
+ */
+static int virtsnd_pcm_open(struct snd_pcm_substream *substream)
+{
+   struct virtio_pcm *pcm = snd_pcm_substream_chip(substream);
+   struct virtio_pcm_substream *ss = NULL;
+
+   if (pcm) {
+   switch (substream->stream) {
+   case SNDRV_PCM_STREAM_PLAYBACK:
+   case SNDRV_PCM_STREAM_CAPTURE: {
+   struct virtio_pcm_stream *stream =
+   &pcm->streams[substream->stream];
+
+   if (substream->number < stream->nsubstreams)


Can this condition ever be false?


+   ss = stream->substreams[substream->number];
+   break;
+   }
+   }
+   }
+
+   if (!ss)
+   return -EBADFD;
+
+   substream->runtime->hw = ss->hw;
+   substream->private_data = ss;
+
+   return 0;
+}
+
+/**
+ * virtsnd_pcm_close() - Close the PCM substream.
+ * @substream: Kernel ALSA substream.
+ *
+ * Context: Any context.
+ * Return: 0.
+ */
+static int virtsnd_pcm_close(struct snd_pcm_substream *substream)
+{
+   return 0;
+}
+
+/**
+ * virtsnd_pcm_hw_params() - Set the parameters of the PCM substream.
+ * @substream: Kernel ALSA substream.
+ * @hw_params: Hardware parameters (can be NULL).
+ *
+ * The function can be called both from the upper level (in this case,
+ * @hw_params is not NULL) or from the driver itself (in this case, @hw_params
+ * is NULL, and the parameter values are taken from the runtime structure).
+ *
+ * In all cases, the function:
+ *   1. checks the state of the virtqueue and, if necessary, tries to fix it,
+ *   2. sets the parameters on the device side,
+ *   3. allocates a hardware buffer and I/O messages.
+ *
+ * Context: Any context that permits to sleep.
+ * Return: 0 on success, -errno on failure.
+ */
+static int virtsnd_pcm_hw_params(struct snd_pcm_substream *substream,
+struct snd_pcm_hw_params *hw_params)
+{
+   struct snd_pcm_runtime *runtime = substream->runtime;
+   struct virtio_pcm_substream *ss = snd_pcm_substream_chip(substream);
+   struct virtio_device *vdev = ss->snd->vdev;
+   struct virtio_snd_msg *msg;
+   struct virtio_snd_pcm_set_params *request;
+   snd_pcm_format_t format;
+   unsigned int channels;
+   unsigned int rate;
+   unsigned int buffer_bytes;
+   unsigned int period_bytes;
+   unsigned int periods;
+   unsigned int i;
+   int vformat = -1;
+   int vrate = -1;
+   int rc;
+
+   /*
+* If we got here after ops->trigger() 

Re: [PATCH v2 5/9] ALSA: virtio: handling control and I/O messages for the PCM device

2021-01-25 Thread Guennadi Liakhovetski



On Sun, 24 Jan 2021, Anton Yakovlev wrote:


The driver implements a message-based transport for I/O substream
operations. Before the start of the substream, the hardware buffer is
sliced into I/O messages, the number of which is equal to the current
number of periods. The size of each message is equal to the current
size of one period.

I/O messages are organized in an ordered queue. The completion of the
I/O message indicates an elapsed period (the only exception is the end
of the stream for the capture substream). Upon completion, the message
is automatically re-added to the end of the queue.

Signed-off-by: Anton Yakovlev 
---
sound/virtio/Makefile |   3 +-
sound/virtio/virtio_card.c|  10 ++
sound/virtio/virtio_card.h|   9 +
sound/virtio/virtio_pcm.c |   3 +
sound/virtio/virtio_pcm.h |  31 
sound/virtio/virtio_pcm_msg.c | 325 ++
6 files changed, 380 insertions(+), 1 deletion(-)
create mode 100644 sound/virtio/virtio_pcm_msg.c

diff --git a/sound/virtio/Makefile b/sound/virtio/Makefile
index 69162a545a41..626af3cc3ed7 100644
--- a/sound/virtio/Makefile
+++ b/sound/virtio/Makefile
@@ -5,5 +5,6 @@ obj-$(CONFIG_SND_VIRTIO) += virtio_snd.o
virtio_snd-objs := \
virtio_card.o \
virtio_ctl_msg.o \
-   virtio_pcm.o
+   virtio_pcm.o \
+   virtio_pcm_msg.o

diff --git a/sound/virtio/virtio_card.c b/sound/virtio/virtio_card.c
index 39fe13b43dd1..11d025ee77c2 100644
--- a/sound/virtio/virtio_card.c
+++ b/sound/virtio/virtio_card.c
@@ -143,6 +143,12 @@ static int virtsnd_find_vqs(struct virtio_snd *snd)
callbacks[VIRTIO_SND_VQ_CONTROL] = virtsnd_ctl_notify_cb;
callbacks[VIRTIO_SND_VQ_EVENT] = virtsnd_event_notify_cb;

+   virtio_cread(vdev, struct virtio_snd_config, streams, &n);
+   if (n) {
+   callbacks[VIRTIO_SND_VQ_TX] = virtsnd_pcm_tx_notify_cb;
+   callbacks[VIRTIO_SND_VQ_RX] = virtsnd_pcm_rx_notify_cb;
+   }
+
rc = virtio_find_vqs(vdev, VIRTIO_SND_VQ_MAX, vqs, callbacks, names,
 NULL);
if (rc) {
@@ -177,6 +183,10 @@ static int virtsnd_find_vqs(struct virtio_snd *snd)
 * virtsnd_enable_event_vq() - Enable the event virtqueue.
 * @snd: VirtIO sound device.
 *
+ * The tx queue is enabled only if the device supports playback stream(s).
+ *
+ * The rx queue is enabled only if the device supports capture stream(s).
+ *
 * Context: Any context.
 */
static void virtsnd_enable_event_vq(struct virtio_snd *snd)
diff --git a/sound/virtio/virtio_card.h b/sound/virtio/virtio_card.h
index be6651a6aaf8..b11c09984882 100644
--- a/sound/virtio/virtio_card.h
+++ b/sound/virtio/virtio_card.h
@@ -89,4 +89,13 @@ virtsnd_rx_queue(struct virtio_snd *snd)
return &snd->queues[VIRTIO_SND_VQ_RX];
}

+static inline struct virtio_snd_queue *
+virtsnd_pcm_queue(struct virtio_pcm_substream *substream)
+{
+   if (substream->direction == SNDRV_PCM_STREAM_PLAYBACK)
+   return virtsnd_tx_queue(substream->snd);
+   else
+   return virtsnd_rx_queue(substream->snd);
+}
+
#endif /* VIRTIO_SND_CARD_H */
diff --git a/sound/virtio/virtio_pcm.c b/sound/virtio/virtio_pcm.c
index 036990b7b78a..1ab50dcc88c8 100644
--- a/sound/virtio/virtio_pcm.c
+++ b/sound/virtio/virtio_pcm.c
@@ -376,6 +376,7 @@ int virtsnd_pcm_parse_cfg(struct virtio_snd *snd)

substream->snd = snd;
substream->sid = i;
+   init_waitqueue_head(&substream->msg_empty);

rc = virtsnd_pcm_build_hw(substream, &info[i]);
if (rc)
@@ -530,6 +531,8 @@ void virtsnd_pcm_event(struct virtio_snd *snd, struct 
virtio_snd_event *event)
break;
}
case VIRTIO_SND_EVT_PCM_XRUN: {
+   if (atomic_read(&substream->xfer_enabled))


Why does .xfer_enabled have to be atomic? It only takes two values - 0 and 
1, I don't see any incrementing, or test-and-set type operations or 
anything similar. Also I don't see .xfer_enabled being set to 1 anywhere 
in this patch, presumably that happens in one of later patches.



+   atomic_set(&substream->xfer_xrun, 1);


Ditto.


break;
}
}
diff --git a/sound/virtio/virtio_pcm.h b/sound/virtio/virtio_pcm.h
index 73fb4d9dc524..d011b7e1d18d 100644
--- a/sound/virtio/virtio_pcm.h
+++ b/sound/virtio/virtio_pcm.h
@@ -24,6 +24,7 @@
#include 

struct virtio_pcm;
+struct virtio_pcm_msg;

/**
 * struct virtio_pcm_substream - VirtIO PCM substream.
@@ -34,6 +35,16 @@ struct virtio_pcm;
 * @features: Stream VirtIO feature bit map (1 << VIRTIO_SND_PCM_F_XXX).
 * @substream: Kernel ALSA substream.
 * @hw: Kernel ALSA substream hardware descriptor.
+ * @frame_bytes: Current frame size in bytes.
+ * @period_size: Current period size in frames.
+ * @buffer_size: Current buffer size in frames.
+ * @hw_ptr: Substream hardware pointer value in frames [0 ... buffer_size).
+ * @xfer_enabled: Data transfer

Re: [PATCH v2 1/2] media: dt-bindings: Convert video-interfaces.txt properties to schemas

2020-12-16 Thread Guennadi Liakhovetski
On Wed, 16 Dec 2020, Rob Herring wrote:

> On Wed, Dec 16, 2020 at 11:18:03AM +0100, Guennadi Liakhovetski wrote:
> > Hi Rob,
> >
> > Sorry for the delay! I didn't realise my ack was required for this patch.
> > I won't object against the licence change, but please don't add me as a
> > maintainer of
>
> Okay, so that's an Ack?

A conditional one, yes. You'll have to send a new version of this your
patch without me among maintainers, to that version you can add

Acked-by: Guennadi Liakhovetski 

Thanks
Guennadi

> > On Thu, 10 Dec 2020, Rob Herring wrote:
> >
> > [snip]
> >
> > > diff --git 
> > > a/Documentation/devicetree/bindings/media/video-interfaces.yaml 
> > > b/Documentation/devicetree/bindings/media/video-interfaces.yaml
> > > new file mode 100644
> > > index ..7415a4df1576
> > > --- /dev/null
> > > +++ b/Documentation/devicetree/bindings/media/video-interfaces.yaml
> > > @@ -0,0 +1,344 @@
> > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > > +%YAML 1.2
> > > +---
> > > +$id: http://devicetree.org/schemas/media/video-interfaces.yaml#
> > > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > > +
> > > +title: Common bindings for video receiver and transmitter interface 
> > > endpoints
> > > +
> > > +maintainers:
> > > +  - Guennadi Liakhovetski 
> >
> > I did commit the original version of
> > Documentation/devicetree/bindings/media/video-interfaces.txt but that was
> > more than 8 years ago, I haven't worked in media / V4L for several years
> > now, so, I don't think I can meaningfully maintain that file now.
>
> Okay, I'll drop you.
>
> Anyone else want to sign up? Laurent?
>
> Rob
>


Re: [PATCH v2 1/2] media: dt-bindings: Convert video-interfaces.txt properties to schemas

2020-12-16 Thread Guennadi Liakhovetski
Hi Rob,

Sorry for the delay! I didn't realise my ack was required for this patch.
I won't object against the licence change, but please don't add me as a
maintainer of

On Thu, 10 Dec 2020, Rob Herring wrote:

[snip]

> diff --git a/Documentation/devicetree/bindings/media/video-interfaces.yaml 
> b/Documentation/devicetree/bindings/media/video-interfaces.yaml
> new file mode 100644
> index ..7415a4df1576
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/media/video-interfaces.yaml
> @@ -0,0 +1,344 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/media/video-interfaces.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Common bindings for video receiver and transmitter interface endpoints
> +
> +maintainers:
> +  - Guennadi Liakhovetski 

I did commit the original version of
Documentation/devicetree/bindings/media/video-interfaces.txt but that was
more than 8 years ago, I haven't worked in media / V4L for several years
now, so, I don't think I can meaningfully maintain that file now.

Thanks
Guennadi


Re: [PATCH v7 0/8] rpmsg: Make RPMSG name service modular

2020-12-03 Thread Guennadi Liakhovetski
(adding vhost maintainers and the author of [1])

Hi,

I'm working on an Audio DSP virtualisation solution [2] and the next 
step in its upstreaming should be an RPMsg vhost implementation, based 
on [3], which contains a simple addition to the current library-style 
vhost API. Later in [1] a different approach has been presented, 
converting the vhost framework to a proper bus-type and device driver. 
Therefore my questions:

1. if the latter approach is prefered, should we expect follow up 
versions of [1] and their upstreaming?
2. judging by the size and complexity of [1] would it maybe be 
preferable to first extract a minimum patch set just to add vhost 
rpmsg? Looking at the patch set it should be doable and not too 
difficult? Kishon, would it be something you could submit?
3. or would it be preferable to keep vhost in its present form, use 
[3] for rpmsg support and re-implement [1] based on a different 
vhost / vringh approach?

Thanks
Guennadi

[1] https://www.spinics.net/lists/kvm/msg219632.html
[2] 
https://mailman.alsa-project.org/pipermail/sound-open-firmware/2020-April/003766.html
[3] https://www.spinics.net/lists/linux-virtualization/msg43359.html

On Wed, Dec 02, 2020 at 01:39:54PM -0700, Mathieu Poirier wrote:
> Good day,
> 
> On Wed, Dec 02, 2020 at 12:05:55PM +0100, Guennadi Liakhovetski wrote:
> > Hi Mathieu,
> > 
> > I'd like to resume reviewing and begin upstreaming of the next steps of 
> > my Audio DSP Virtualisation work, based on this your patch set. How 
> 
> I'm all for it too.
> 
> > confident are we that it's going to be upstreamed in its present form? 
> > What's the plan to push it to "next?"
> > 
> 
> I thought we were pretty unanimous that something like what Kishon did was the
> way to go.  
> 
> > Thanks
> > Guennadi
> > 
> > On Mon, Nov 23, 2020 at 05:06:10PM +0100, Guennadi Liakhovetski wrote:
> > > Hi Mathieu,
> > > 
> > > Thanks for bringing all the stuff together and for polishing it!
> > > 
> > > For the entire series:
> > > 
> > > Tested-by: Guennadi Liakhovetski 
> > > Reviewed-by: Guennadi Liakhovetski 
> > > 
> > > Thanks
> > > Guennadi
> > > 
> > > On Fri, Nov 20, 2020 at 02:42:37PM -0700, Mathieu Poirier wrote:
> > > > This revision addresses comments received from the previous revision,
> > > > i.e V6.  Please see details below.
> > > > 
> > > > It starts by making the RPMSG protocol transport agnostic by
> > > > moving the headers it uses to generic types and using those in the
> > > > current implementation.  From there it re-uses the work that Arnaud
> > > > published[1] to make the name service modular.
> > > > 
> > > > Tested on stm32mp157 with the RPMSG client sample application.  Applies
> > > > cleanly on rpmsg-next.
> > > > 
> > > > Thanks,
> > > > Mathieu
> > > > 
> > > > [1]. 
> > > > https://patchwork.kernel.org/project/linux-remoteproc/list/?series=338335
> > > > 
> > > > ---
> > > > New for V7:
> > > > - Fixed error path in rpmsg_probe() as reported by Guennadi
> > > > 
> > > > Arnaud Pouliquen (4):
> > > >   rpmsg: virtio: Rename rpmsg_create_channel
> > > >   rpmsg: core: Add channel creation internal API
> > > >   rpmsg: virtio: Add rpmsg channel device ops
> > > >   rpmsg: Turn name service into a stand alone driver
> > > > 
> > > > Mathieu Poirier (4):
> > > >   rpmsg: Introduce __rpmsg{16|32|64} types
> > > >   rpmsg: virtio: Move from virtio to rpmsg byte conversion
> > > >   rpmsg: Move structure rpmsg_ns_msg to header file
> > > >   rpmsg: Make rpmsg_{register|unregister}_device() public
> > > > 
> > > >  drivers/rpmsg/Kconfig|   9 ++
> > > >  drivers/rpmsg/Makefile   |   1 +
> > > >  drivers/rpmsg/rpmsg_core.c   |  44 
> > > >  drivers/rpmsg/rpmsg_internal.h   |  14 ++-
> > > >  drivers/rpmsg/rpmsg_ns.c | 126 +
> > > >  drivers/rpmsg/virtio_rpmsg_bus.c | 186 +++
> > > >  include/linux/rpmsg.h|  63 ++-
> > > >  include/linux/rpmsg/byteorder.h  |  67 +++
> > > >  include/linux/rpmsg/ns.h |  45 
> > > >  include/uapi/linux/rpmsg_types.h |  11 ++
> > > >  10 files changed, 439 insertions(+), 127 deletions(-)
> > > >  create mode 100644 drivers/rpmsg/rpmsg_ns.c
> > > >  create mode 100644 include/linux/rpmsg/byteorder.h
> > > >  create mode 100644 include/linux/rpmsg/ns.h
> > > >  create mode 100644 include/uapi/linux/rpmsg_types.h
> > > > 
> > > > -- 
> > > > 2.25.1
> > > > 


Re: [PATCH v7 0/8] rpmsg: Make RPMSG name service modular

2020-12-02 Thread Guennadi Liakhovetski
Hi Mathieu,

I'd like to resume reviewing and begin upstreaming of the next steps of 
my Audio DSP Virtualisation work, based on this your patch set. How 
confident are we that it's going to be upstreamed in its present form? 
What's the plan to push it to "next?"

Thanks
Guennadi

On Mon, Nov 23, 2020 at 05:06:10PM +0100, Guennadi Liakhovetski wrote:
> Hi Mathieu,
> 
> Thanks for bringing all the stuff together and for polishing it!
> 
> For the entire series:
> 
> Tested-by: Guennadi Liakhovetski 
> Reviewed-by: Guennadi Liakhovetski 
> 
> Thanks
> Guennadi
> 
> On Fri, Nov 20, 2020 at 02:42:37PM -0700, Mathieu Poirier wrote:
> > This revision addresses comments received from the previous revision,
> > i.e V6.  Please see details below.
> > 
> > It starts by making the RPMSG protocol transport agnostic by
> > moving the headers it uses to generic types and using those in the
> > current implementation.  From there it re-uses the work that Arnaud
> > published[1] to make the name service modular.
> > 
> > Tested on stm32mp157 with the RPMSG client sample application.  Applies
> > cleanly on rpmsg-next.
> > 
> > Thanks,
> > Mathieu
> > 
> > [1]. 
> > https://patchwork.kernel.org/project/linux-remoteproc/list/?series=338335
> > 
> > ---
> > New for V7:
> > - Fixed error path in rpmsg_probe() as reported by Guennadi
> > 
> > Arnaud Pouliquen (4):
> >   rpmsg: virtio: Rename rpmsg_create_channel
> >   rpmsg: core: Add channel creation internal API
> >   rpmsg: virtio: Add rpmsg channel device ops
> >   rpmsg: Turn name service into a stand alone driver
> > 
> > Mathieu Poirier (4):
> >   rpmsg: Introduce __rpmsg{16|32|64} types
> >   rpmsg: virtio: Move from virtio to rpmsg byte conversion
> >   rpmsg: Move structure rpmsg_ns_msg to header file
> >   rpmsg: Make rpmsg_{register|unregister}_device() public
> > 
> >  drivers/rpmsg/Kconfig|   9 ++
> >  drivers/rpmsg/Makefile   |   1 +
> >  drivers/rpmsg/rpmsg_core.c   |  44 
> >  drivers/rpmsg/rpmsg_internal.h   |  14 ++-
> >  drivers/rpmsg/rpmsg_ns.c | 126 +
> >  drivers/rpmsg/virtio_rpmsg_bus.c | 186 +++
> >  include/linux/rpmsg.h|  63 ++-
> >  include/linux/rpmsg/byteorder.h  |  67 +++
> >  include/linux/rpmsg/ns.h |  45 
> >  include/uapi/linux/rpmsg_types.h |  11 ++
> >  10 files changed, 439 insertions(+), 127 deletions(-)
> >  create mode 100644 drivers/rpmsg/rpmsg_ns.c
> >  create mode 100644 include/linux/rpmsg/byteorder.h
> >  create mode 100644 include/linux/rpmsg/ns.h
> >  create mode 100644 include/uapi/linux/rpmsg_types.h
> > 
> > -- 
> > 2.25.1
> > 


Re: [PATCH v7 0/8] rpmsg: Make RPMSG name service modular

2020-11-23 Thread Guennadi Liakhovetski
Hi Mathieu,

Thanks for bringing all the stuff together and for polishing it!

For the entire series:

Tested-by: Guennadi Liakhovetski 
Reviewed-by: Guennadi Liakhovetski 

Thanks
Guennadi

On Fri, Nov 20, 2020 at 02:42:37PM -0700, Mathieu Poirier wrote:
> This revision addresses comments received from the previous revision,
> i.e V6.  Please see details below.
> 
> It starts by making the RPMSG protocol transport agnostic by
> moving the headers it uses to generic types and using those in the
> current implementation.  From there it re-uses the work that Arnaud
> published[1] to make the name service modular.
> 
> Tested on stm32mp157 with the RPMSG client sample application.  Applies
> cleanly on rpmsg-next.
> 
> Thanks,
> Mathieu
> 
> [1]. https://patchwork.kernel.org/project/linux-remoteproc/list/?series=338335
> 
> ---
> New for V7:
> - Fixed error path in rpmsg_probe() as reported by Guennadi
> 
> Arnaud Pouliquen (4):
>   rpmsg: virtio: Rename rpmsg_create_channel
>   rpmsg: core: Add channel creation internal API
>   rpmsg: virtio: Add rpmsg channel device ops
>   rpmsg: Turn name service into a stand alone driver
> 
> Mathieu Poirier (4):
>   rpmsg: Introduce __rpmsg{16|32|64} types
>   rpmsg: virtio: Move from virtio to rpmsg byte conversion
>   rpmsg: Move structure rpmsg_ns_msg to header file
>   rpmsg: Make rpmsg_{register|unregister}_device() public
> 
>  drivers/rpmsg/Kconfig|   9 ++
>  drivers/rpmsg/Makefile   |   1 +
>  drivers/rpmsg/rpmsg_core.c   |  44 
>  drivers/rpmsg/rpmsg_internal.h   |  14 ++-
>  drivers/rpmsg/rpmsg_ns.c | 126 +
>  drivers/rpmsg/virtio_rpmsg_bus.c | 186 +++
>  include/linux/rpmsg.h|  63 ++-
>  include/linux/rpmsg/byteorder.h  |  67 +++
>  include/linux/rpmsg/ns.h |  45 
>  include/uapi/linux/rpmsg_types.h |  11 ++
>  10 files changed, 439 insertions(+), 127 deletions(-)
>  create mode 100644 drivers/rpmsg/rpmsg_ns.c
>  create mode 100644 include/linux/rpmsg/byteorder.h
>  create mode 100644 include/linux/rpmsg/ns.h
>  create mode 100644 include/uapi/linux/rpmsg_types.h
> 
> -- 
> 2.25.1
> 


Re: [PATCH v6 8/8] rpmsg: Turn name service into a stand alone driver

2020-11-19 Thread Guennadi Liakhovetski
Hi Mathieu,

I haven't tested it yet, but I've compared it to the previous version 
and all the changed except the one, mentioned by Arnaud, seem to be 
there! So, let's just fix this one and should be good to go!

Thanks
Guennadi

On Thu, Nov 19, 2020 at 03:52:50PM +0100, Arnaud POULIQUEN wrote:

[snip]

> As Guennadi mentionned in a previous mail
> a kfree(vch) is missing on error
> 
> @@ -949,10 +949,11 @@ static int rpmsg_probe(struct virtio_device *vdev)
>   dev_info(&vdev->dev, "rpmsg host is online\n");
> 
>   return 0;
> 
>  free_coherent:
> + kfree(vch);
>   dma_free_coherent(vdev->dev.parent, total_buf_space,
> bufs_va, vrp->bufs_dma);
>  vqs_del:
> 
> Otherwise i tested this series successfully.
> 
> Thanks,
> Arnaud


Re: [PATCH v5 8/8] rpmsg: Turn name service into a stand alone driver

2020-11-17 Thread Guennadi Liakhovetski
On Tue, Nov 17, 2020 at 05:06:47PM -0700, Mathieu Poirier wrote:

[snip]

> I confirm that all this is working as expected - I will send a new revision of
> this set tomorrow afternoon.  
> 
> Guennadi, can I add a Co-developed-by and Signed-off-by with your name on the
> patch?

You can add the "Co-developed-by" tag, sure, if you like. As for the SOB: I'm 
not sure if this is a proper use of it? AFAIK SOB is used when that person 
"transmitted" the patch, e.g. if they developed and submitted it to a list, 
or if they received it from someone and forwarded it upstream (maintainer 
case). I'm not sure about this case, but well, feel free, don't think we'd 
be violating anything since I did send versions of code, similar to parts of 
that, some with my SOF, so, should be fine.

Thanks
Guennadi


Re: [PATCH v5 8/8] rpmsg: Turn name service into a stand alone driver

2020-11-17 Thread Guennadi Liakhovetski
On Tue, Nov 17, 2020 at 06:30:54PM +0100, Arnaud POULIQUEN wrote:

[snip]

> It's not a good day for me today... it seems I read your explanation too 
> quickly
> this morning, which is, however, very clear.
> My apologies

Oh, I did the same to one of your earlier emails one of these days - 
I missed a paragraph at the end and then "re-discovered" it in a 
later email, so, I can do that too! :-D

Cheers
Guennadi


Re: [PATCH v5 8/8] rpmsg: Turn name service into a stand alone driver

2020-11-17 Thread Guennadi Liakhovetski
On Tue, Nov 17, 2020 at 05:44:05PM +0100, Arnaud POULIQUEN wrote:
> 
> 
> On 11/17/20 5:03 PM, Guennadi Liakhovetski wrote:
> > On Tue, Nov 17, 2020 at 12:42:30PM +0100, Arnaud POULIQUEN wrote:
> > 
> > [snip]
> > 
> >> diff --git a/drivers/rpmsg/rpmsg_ns.c b/drivers/rpmsg/rpmsg_ns.c
> >> index 5bda7cb44618..80c2cc23bada 100644
> >> --- a/drivers/rpmsg/rpmsg_ns.c
> >> +++ b/drivers/rpmsg/rpmsg_ns.c
> >> @@ -55,6 +55,39 @@ static int rpmsg_ns_cb(struct rpmsg_device *rpdev, void
> >> *data, int len,
> >>return 0;
> >>  }
> >>
> >> +/**
> >> + * rpmsg_ns_register_device() - register name service device based on 
> >> rpdev
> >> + * @rpdev: prepared rpdev to be used for creating endpoints
> >> + *
> >> + * This function wraps rpmsg_register_device() preparing the rpdev for 
> >> use as
> >> + * basis for the rpmsg name service device.
> >> + */
> >> +int rpmsg_ns_register_device(struct rpmsg_device *rpdev)
> >> +{
> >> +#ifdef MODULES
> >> +  int ret;
> >> +  struct module *rpmsg_ns;
> >> +
> >> +  mutex_lock(&module_mutex);
> >> +  rpmsg_ns = find_module(KBUILD_MODNAME);
> >> +  mutex_unlock(&module_mutex);
> >> +
> >> +  if (!rpmsg_ns) {
> >> +  ret = request_module(KBUILD_MODNAME);
> > 
> > Is this code requesting the module in which it is located?.. I must be 
> > missing 
> > something...
> 
> Right this is stupid...Thanks to highlight this!
> 
> That being said, your remark is very interesting: we need to load the module 
> to
> access to this function. This means that calling this function ensures that 
> the
> module is loaded. In this case no need to add the piece of code to find
> module... here is the call stack associated (associated patch is available 
> below):

Yes, as I wrote 10 hours ago:

> Now, as for how to actually load the
> module, I'd really propose to move rpmsg_ns_register_device() into the .c
> file and then the problem will be resolved automatically: as a symbol
> dependence the module will be loaded whenever another module, calling
> rpmsg_ns_register_device() is loaded.

Thanks
Guennadi

> (rpmsg_ns_probe+0x5c/0xe0 [rpmsg_ns])
> [   11.858748] [] (rpmsg_ns_probe [rpmsg_ns]) from []
> (rpmsg_dev_probe+0x14c/0x1b0 [rpmsg_core])
> [   11.869047] [] (rpmsg_dev_probe [rpmsg_core]) from []
> (really_probe+0x208/0x4f0)
> [   11.878117] [] (really_probe) from []
> (driver_probe_device+0x78/0x16c)
> [   11.886404] [] (driver_probe_device) from []
> (bus_for_each_drv+0x84/0xd0)
> [   11.894887] [] (bus_for_each_drv) from []
> (__device_attach+0xf0/0x188)
> [   11.903142] [] (__device_attach) from []
> (bus_probe_device+0x84/0x8c)
> [   11.911314] [] (bus_probe_device) from []
> (device_add+0x3b0/0x7b0)
> [   11.919227] [] (device_add) from []
> (rpmsg_register_device+0x54/0x88 [rpmsg_core])
> [   11.928541] [] (rpmsg_register_device [rpmsg_core]) from
> [] (rpmsg_probe+0x298/0x3c8 [virtio_rpmsg_bus])
> [   11.939748] [] (rpmsg_probe [virtio_rpmsg_bus]) from []
> (virtio_dev_probe+0x1f4/0x2c4)
> [   11.949377] [] (virtio_dev_probe) from []
> (really_probe+0x208/0x4f0)
> [   11.957454] [] (really_probe) from []
> (driver_probe_device+0x78/0x16c)
> [   11.965710] [] (driver_probe_device) from []
> (device_driver_attach+0x58/0x60)
> [   11.974574] [] (device_driver_attach) from []
> (__driver_attach+0xb4/0x154)
> [   11.983177] [] (__driver_attach) from []
> (bus_for_each_dev+0x78/0xc0)
> [   11.991344] [] (bus_for_each_dev) from []
> (bus_add_driver+0x170/0x20c)
> [   11.999600] [] (bus_add_driver) from []
> (driver_register+0x74/0x108)
> [   12.007693] [] (driver_register) from []
> (rpmsg_init+0x10/0x1000 [virtio_rpmsg_bus])
> [   12.017168] [] (rpmsg_init [virtio_rpmsg_bus]) from []
> (do_one_initcall+0x58/0x2bc)
> [
> 
> This would make the patch very simple. I tested following patch on my 
> platform,
> applying it, i do not reproduce the initial issue.
> 
> 
> diff --git a/drivers/rpmsg/Kconfig b/drivers/rpmsg/Kconfig
> index c3fc75e6514b..1394114782d2 100644
> --- a/drivers/rpmsg/Kconfig
> +++ b/drivers/rpmsg/Kconfig
> @@ -71,5 +71,6 @@ config RPMSG_VIRTIO
>   depends on HAS_DMA
>   select RPMSG
>   select VIRTIO
> + select RPMSG_NS
> 
>  endmenu
> diff --git a/drivers/rpmsg/rpmsg_ns.c b/drivers/rpmsg/rpmsg_ns.c
> index 5bda7cb44618..5867281188de 100644
> --- a/drivers/rpmsg/rpmsg_ns.c
> +++ b/drivers/rpmsg/rpmsg_ns.c
> @@ -55,6 +55,24 @@ static int rpmsg_ns_cb(struct rpmsg_device *rpdev, 

Re: [PATCH v5 8/8] rpmsg: Turn name service into a stand alone driver

2020-11-17 Thread Guennadi Liakhovetski
On Tue, Nov 17, 2020 at 12:42:30PM +0100, Arnaud POULIQUEN wrote:

[snip]

> diff --git a/drivers/rpmsg/rpmsg_ns.c b/drivers/rpmsg/rpmsg_ns.c
> index 5bda7cb44618..80c2cc23bada 100644
> --- a/drivers/rpmsg/rpmsg_ns.c
> +++ b/drivers/rpmsg/rpmsg_ns.c
> @@ -55,6 +55,39 @@ static int rpmsg_ns_cb(struct rpmsg_device *rpdev, void
> *data, int len,
>   return 0;
>  }
> 
> +/**
> + * rpmsg_ns_register_device() - register name service device based on rpdev
> + * @rpdev: prepared rpdev to be used for creating endpoints
> + *
> + * This function wraps rpmsg_register_device() preparing the rpdev for use as
> + * basis for the rpmsg name service device.
> + */
> +int rpmsg_ns_register_device(struct rpmsg_device *rpdev)
> +{
> +#ifdef MODULES
> + int ret;
> + struct module *rpmsg_ns;
> +
> + mutex_lock(&module_mutex);
> + rpmsg_ns = find_module(KBUILD_MODNAME);
> + mutex_unlock(&module_mutex);
> +
> + if (!rpmsg_ns) {
> + ret = request_module(KBUILD_MODNAME);

Is this code requesting the module in which it is located?.. I must be missing 
something...

Thanks
Guennadi


Re: [PATCH v5 8/8] rpmsg: Turn name service into a stand alone driver

2020-11-16 Thread Guennadi Liakhovetski
Hi Mathieu,

On Mon, Nov 16, 2020 at 03:40:03PM -0700, Mathieu Poirier wrote:
> On Mon, Nov 16, 2020 at 04:51:52PM +0100, Arnaud POULIQUEN wrote:

[snip]

> > Having said that, does this guarantee the probe, a good question!
> > Maybe you or Mathieu have the answer, not me...
> 
> I did a lot of probing, went deep in the bowels of the user mode helper
> subsystem and looked at sys_load_module().  Especially at do_init_module() 
> where
> function do_one_initcall()[1] is called on mod->init, which happens to be
> rpmsg_ns_init() where the name space driver is registered.  I am confident we
> can rely on this mechanism.

Thanks for investigating and confirming that! So, we can be confident, that 
if the module is already loaded at the time when the NS device is registered, 
the probing happens synchronously. Now, as for how to actually load the 
module, I'd really propose to move rpmsg_ns_register_device() into the .c 
file and then the problem will be resolved automatically: as a symbol 
dependence the module will be loaded whenever another module, calling 
rpmsg_ns_register_device() is loaded.

Thanks
Guennadi


Re: [PATCH v5 8/8] rpmsg: Turn name service into a stand alone driver

2020-11-16 Thread Guennadi Liakhovetski
On Mon, Nov 16, 2020 at 04:51:52PM +0100, Arnaud POULIQUEN wrote:
> Hi Guennadi,
> 
> On 11/16/20 4:10 PM, Guennadi Liakhovetski wrote:
> > Hi Arnaud,
> > 
> > On Mon, Nov 16, 2020 at 03:43:35PM +0100, Arnaud POULIQUEN wrote:
> >> Hi Guennadi, Mathieu,
> > 
> > [snip]
> > 
> >> I tried the find_module API, it's quite simple and seems to work well. 
> >> just need
> >> to be protected by #ifdef MODULE
> >>
> >> I also added a select RMPS_NS in the RPMSG_VIRTIO for compatibility with 
> >> the legacy.
> >>
> >> look to me that this patch is a simple fix that should work also for the 
> >> vhost...
> >> that said, the question is can we use this API here?
> >>
> >> I attached the patch at the end of the mail.
> > 
> > Thanks for the patch. Yes, this would guarantee, that the NS module is 
> > loaded. But 
> > does it also guarantee, that the NS probing completes faster than an NS 
> > announcement 
> > arrives? We have a race here:
> > 
> > rpmsg_ns_register_device() -\
> >  |  |
> > virtio_device_ready()   |
> >  |  |
> > remote sends NS announcement  rpmsg_register_device()
> >  |  |
> >  |rpmsg_ns_probe()
> >  |  |
> >  |rpmsg_create_ept()
> > rpmsg_ns_cb()
> > 
> > In practice we *should* be fine - maybe the whole probing (the right 
> > branch) happens 
> > synchronously on the same core as where rpmsg_ns_register_device() was 
> > called, or 
> > even if not, the probing runs locally and the NS announcement either talks 
> > to a 
> > remote core or a VM. So, it *should* be safe, but unless we can make 
> > guarantee, that 
> > the probing is synchronous, I wouldn't rely on this. So, without a 
> > completion this 
> > still seems incomplete to me.
> 
> Thanks for this description!
> I tested on a dual core, and I expected what you are describing above but in
> fact I observed following:
> 
>  rpmsg_ns_register_device()
>   |
>  rpmsg_register_device()
>   |
>  rpmsg_ns_probe()
>   |
>  rpmsg_create_ept()
>   |
>  virtio_device_ready()
>   |
>  remote sends NS announcement
>  rpmsg_ns_cb()
> 
> Here is the associated call stack generated in rpmsg_ns_probe using "warn_on"
> 
> [   11.498678] CPU: 1 PID: 348 Comm: systemd-udevd Not tainted 5.10.0-rc2 #54
> [   11.504106] Hardware name: STM32 (Device Tree Support)
> [   11.509271] [] (unwind_backtrace) from []
> (show_stack+0x10/0x14)
> [   11.516992] [] (show_stack) from [] 
> (dump_stack+0xb8/0xcc)
> [   11.524204] [] (dump_stack) from [] (__warn+0xd8/0xf0)
> [   11.531066] [] (__warn) from [] 
> (warn_slowpath_fmt+0x64/0xc4)
> [   11.538547] [] (warn_slowpath_fmt) from []
> (rpmsg_ns_probe+0x5c/0xe0 [rpmsg_ns])
> [   11.547681] [] (rpmsg_ns_probe [rpmsg_ns]) from []
> (rpmsg_dev_probe+0x14c/0x1b0 [rpmsg_core])
> [   11.557933] [] (rpmsg_dev_probe [rpmsg_core]) from []
> (really_probe+0x208/0x4f0)
> [   11.567050] [] (really_probe) from []
> (driver_probe_device+0x78/0x16c)
> [   11.575305] [] (driver_probe_device) from []
> (bus_for_each_drv+0x84/0xd0)
> [   11.583822] [] (bus_for_each_drv) from []
> (__device_attach+0xf0/0x188)
> [   11.592075] [] (__device_attach) from []
> (bus_probe_device+0x84/0x8c)
> [   11.600248] [] (bus_probe_device) from []
> (device_add+0x3b0/0x7b0)
> [   11.608165] [] (device_add) from []
> (rpmsg_register_device+0x54/0x88 [rpmsg_core])
> [   11.617486] [] (rpmsg_register_device [rpmsg_core]) from
> [] (rpmsg_probe+0x2c4/0x3f4 [virtio_rpmsg_bus])
> [   11.628696] [] (rpmsg_probe [virtio_rpmsg_bus]) from []
> (virtio_dev_probe+0x1f4/0x2c4)

Right, yes, that's also what I expected to happen, but I wasn't sure whether 
we can *rely* on this. It does indeed look like we can (by only looking at 
your trace, without scrutinising the code). So, if everybody is happy with 
this "empiric proof" we can use either this or the one-module approach 
without a completion, I'd be fine either way.

Thanks
Guennadi

> [   11.638352] [] (virtio_dev_probe) from []
> (really_probe+0x208/0x4f0)
> [   11.646406] [] (really_probe) from []
> (driver_probe_device+0x78/0x16c)
> [   11.654658] [] (driver_probe_device) from []
> (device_driver_attach+0x58/0x60)
> [   11.663522] [] (device_driver_attach) from []
> (__

Re: [PATCH v5 8/8] rpmsg: Turn name service into a stand alone driver

2020-11-16 Thread Guennadi Liakhovetski
Hi Arnaud,

On Mon, Nov 16, 2020 at 03:43:35PM +0100, Arnaud POULIQUEN wrote:
> Hi Guennadi, Mathieu,

[snip]

> I tried the find_module API, it's quite simple and seems to work well. just 
> need
> to be protected by #ifdef MODULE
> 
> I also added a select RMPS_NS in the RPMSG_VIRTIO for compatibility with the 
> legacy.
> 
> look to me that this patch is a simple fix that should work also for the 
> vhost...
> that said, the question is can we use this API here?
> 
> I attached the patch at the end of the mail.

Thanks for the patch. Yes, this would guarantee, that the NS module is loaded. 
But 
does it also guarantee, that the NS probing completes faster than an NS 
announcement 
arrives? We have a race here:

rpmsg_ns_register_device() -\
 |  |
virtio_device_ready()   |
 |  |
remote sends NS announcement  rpmsg_register_device()
 |  |
 |rpmsg_ns_probe()
 |  |
 |rpmsg_create_ept()
rpmsg_ns_cb()

In practice we *should* be fine - maybe the whole probing (the right branch) 
happens 
synchronously on the same core as where rpmsg_ns_register_device() was called, 
or 
even if not, the probing runs locally and the NS announcement either talks to a 
remote core or a VM. So, it *should* be safe, but unless we can make guarantee, 
that 
the probing is synchronous, I wouldn't rely on this. So, without a completion 
this 
still seems incomplete to me.

Thanks
Guennadi

> >> Why can it not be called in rpmsg_ns_probe()? The only purpose of this 
> >> completion 
> >> is to make sure that rpmsg_create_ept() for the NS endpoint has completed 
> >> before 
> >> we begin communicating with the remote / host, e.g. by calling 
> >> virtio_device_ready() in case of the VirtIO backend, right?
> > 
> > How the module driver are probed during device registration is not cristal 
> > clear
> > for me here...
> > Your approach looks to me a good compromize, I definitively need to apply 
> > and
> > test you patch to well understood the associated scheduling...
> 
> I looked in code, trying to understand behavior on device registration.
> 
> my understanding is: if driver is already registered (basic built-in or module
> previously loaded) the driver is probed on device registration. No 
> asynchronous
> probing through a work queue or other.
> 
> So it seems, (but i'm not enough expert to be 100% sure) that ensuring that 
> the
> rmpsg_ns module is loaded (and so driver registered) before the device 
> register
> is enough, no completion mechanism is needed here.
> 
> Regards,
> Arnaud
> 
> > 
> > Thanks,
> > Arnaud
> > 
> >>
> >> Thanks
> >> Guennadi
> >>
> >>> Thanks,
> >>> Arnaud
> >>>
> 
> [...]
> 
> From 2629298ef1b7eea7a3a7df245abba03914c09e6b Mon Sep 17 00:00:00 2001
> From: Arnaud Pouliquen 
> Date: Mon, 16 Nov 2020 15:07:14 +0100
> Subject: [PATCH] rpmsg: specify dependency between virtio rpmsg and virtio_ns
> 
> The rpmsg_ns service has to be registered before the first
> message reception. When used as module, this imply and
> dependency of the rpmsg virtio on the rpmsg_ns module.
> this patch solve the dependency issue.
> 
> Signed-off-by: Arnaud Pouliquen 
> ---
>  drivers/rpmsg/Kconfig|  1 +
>  drivers/rpmsg/rpmsg_ns.c |  2 +-
>  drivers/rpmsg/virtio_rpmsg_bus.c | 22 ++
>  3 files changed, 24 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/rpmsg/Kconfig b/drivers/rpmsg/Kconfig
> index c3fc75e6514b..1394114782d2 100644
> --- a/drivers/rpmsg/Kconfig
> +++ b/drivers/rpmsg/Kconfig
> @@ -71,5 +71,6 @@ config RPMSG_VIRTIO
>   depends on HAS_DMA
>   select RPMSG
>   select VIRTIO
> + select RPMSG_NS
> 
>  endmenu
> diff --git a/drivers/rpmsg/rpmsg_ns.c b/drivers/rpmsg/rpmsg_ns.c
> index 5bda7cb44618..f19f3cbd2526 100644
> --- a/drivers/rpmsg/rpmsg_ns.c
> +++ b/drivers/rpmsg/rpmsg_ns.c
> @@ -104,5 +104,5 @@ module_exit(rpmsg_ns_exit);
> 
>  MODULE_DESCRIPTION("Name service announcement rpmsg Driver");
>  MODULE_AUTHOR("Arnaud Pouliquen ");
> -MODULE_ALIAS("rpmsg_ns");
> +MODULE_ALIAS("rpmsg:rpmsg_ns");
>  MODULE_LICENSE("GPL v2");
> diff --git a/drivers/rpmsg/virtio_rpmsg_bus.c 
> b/drivers/rpmsg/virtio_rpmsg_bus.c
> index 338f16c6563d..f032e6c3f9a9 100644
> --- a/drivers/rpmsg/virtio_rpmsg_bus.c
> +++ b/drivers/rpmsg/virtio_rpmsg_bus.c
> @@ -1001,6 +1001,28 @@ static int __init rpmsg_init(void)
>  {
>   int ret;
> 
> +#ifdef MODULE
> + static const char name[] = "rpmsg_ns";
> + struct module *ns;
> +
> + /*
> +  * Make sur that the rpmsg ns module is loaded in case of module.
> +  * This ensures that the rpmsg_ns driver is probed immediately when the
> +  * associated device is registered during the rpmsg virtio probe.
> +  */
> + mutex_lock(&module_mutex);
> +   

Re: [PATCH v5 8/8] rpmsg: Turn name service into a stand alone driver

2020-11-12 Thread Guennadi Liakhovetski
Hi Arnaud,

On Thu, Nov 12, 2020 at 11:17:54AM +0100, Arnaud POULIQUEN wrote:
> Hi Guennadi,
> 
> On 11/11/20 3:49 PM, Guennadi Liakhovetski wrote:
> > Hi Arnaud,

[snip]

> > From: Guennadi Liakhovetski 
> > Subject: [PATCH] fixup! rpmsg: Turn name service into a stand alone driver
> > 
> > Link ns.c with core.c together to guarantee immediate probing.
> > 
> > Signed-off-by: Guennadi Liakhovetski 
> > ---
> >  drivers/rpmsg/Makefile|  2 +-
> >  drivers/rpmsg/{rpmsg_core.c => core.c}| 13 +++--
> >  drivers/rpmsg/{rpmsg_ns.c => ns.c}| 49 ++-
> >  drivers/rpmsg/virtio_rpmsg_bus.c  |  5 +-
> >  include/linux/rpmsg.h |  4 +-
> >  .../{rpmsg_byteorder.h => rpmsg/byteorder.h}  |  0
> >  include/linux/{rpmsg_ns.h => rpmsg/ns.h}  | 16 +++---
> >  7 files changed, 61 insertions(+), 28 deletions(-)
> >  rename drivers/rpmsg/{rpmsg_core.c => core.c} (99%)
> >  rename drivers/rpmsg/{rpmsg_ns.c => ns.c} (76%)
> >  rename include/linux/{rpmsg_byteorder.h => rpmsg/byteorder.h} (100%)
> >  rename include/linux/{rpmsg_ns.h => rpmsg/ns.h} (82%)
> > 
> > diff --git a/drivers/rpmsg/Makefile b/drivers/rpmsg/Makefile
> > index 8d452656f0ee..5aa79e167372 100644
> > --- a/drivers/rpmsg/Makefile
> > +++ b/drivers/rpmsg/Makefile
> > @@ -1,7 +1,7 @@
> >  # SPDX-License-Identifier: GPL-2.0
> > +rpmsg_core-objs:= core.o ns.o
> >  obj-$(CONFIG_RPMSG)+= rpmsg_core.o
> >  obj-$(CONFIG_RPMSG_CHAR)   += rpmsg_char.o
> > -obj-$(CONFIG_RPMSG_NS) += rpmsg_ns.o
> >  obj-$(CONFIG_RPMSG_MTK_SCP)+= mtk_rpmsg.o
> >  qcom_glink-objs:= qcom_glink_native.o qcom_glink_ssr.o
> >  obj-$(CONFIG_RPMSG_QCOM_GLINK) += qcom_glink.o
> > diff --git a/drivers/rpmsg/rpmsg_core.c b/drivers/rpmsg/core.c
> > similarity index 99%
> > rename from drivers/rpmsg/rpmsg_core.c
> > rename to drivers/rpmsg/core.c
> > index 6381c1e00741..0c622cced804 100644
> > --- a/drivers/rpmsg/rpmsg_core.c
> > +++ b/drivers/rpmsg/core.c
> > @@ -14,6 +14,7 @@
> >  #include 
> >  #include 
> >  #include 
> > +#include 
> >  #include 
> >  #include 
> >  #include 
> > @@ -625,21 +626,27 @@ void unregister_rpmsg_driver(struct rpmsg_driver 
> > *rpdrv)
> >  }
> >  EXPORT_SYMBOL(unregister_rpmsg_driver);
> >  
> > -
> >  static int __init rpmsg_init(void)
> >  {
> > int ret;
> >  
> > ret = bus_register(&rpmsg_bus);
> > -   if (ret)
> > +   if (ret) {
> > pr_err("failed to register rpmsg bus: %d\n", ret);
> > +   return ret;
> > +   }
> > +
> > +   ret = rpmsg_ns_init();
> > +   if (ret)
> > +   bus_unregister(&rpmsg_bus);
> >  
> > return ret;
> >  }
> >  postcore_initcall(rpmsg_init);
> >  
> > -static void __exit rpmsg_fini(void)
> > +static void rpmsg_fini(void)
> >  {
> > +   rpmsg_ns_exit();
> > bus_unregister(&rpmsg_bus);
> >  }
> >  module_exit(rpmsg_fini);
> 
> The drawback of this solution is that it makes the anoucement service ns
> mandatory, but it is optional because it depends on the RPMsg backend bus.
> RPMsg NS should be generic but optional.
> What about calling this in rpmsg_virtio?

This just registers a driver. If the backend doesn't register a suitable 
device by calling rpmsg_ns_register_device(); nothing happens. But if 
you're concerned about wasted memory, we can make it conditional on a 
configuration option.

> > diff --git a/drivers/rpmsg/rpmsg_ns.c b/drivers/rpmsg/ns.c
> > similarity index 76%
> > rename from drivers/rpmsg/rpmsg_ns.c
> > rename to drivers/rpmsg/ns.c
> > index 8e26824ca328..86c011bfb62f 100644
> > --- a/drivers/rpmsg/rpmsg_ns.c
> > +++ b/drivers/rpmsg/ns.c
> > @@ -2,15 +2,47 @@
> >  /*
> >   * Copyright (C) STMicroelectronics 2020 - All Rights Reserved
> >   */
> > +#include 
> >  #include 
> > +#include 
> >  #include 
> >  #include 
> > -#include 
> >  #include 
> > -#include 
> > +#include 
> > +#include 
> >  
> >  #include "rpmsg_internal.h"
> >  
> > +int rpmsg_ns_register_device(struct rpmsg_device *rpdev)
> > +{
> > +   int ret;
> > +
> > +   strcpy(rpdev->id.name, "rpmsg_ns");
> > +   rpdev->driver_override = "rpmsg_ns";
> > +   rpdev->src

Re: [PATCH v5 8/8] rpmsg: Turn name service into a stand alone driver

2020-11-11 Thread Guennadi Liakhovetski
Hi Arnaud,

On Tue, Nov 10, 2020 at 07:18:45PM +0100, Arnaud POULIQUEN wrote:
> Hi Mathieu, Guennadi,
> 
> On 11/9/20 6:55 PM, Mathieu Poirier wrote:
> > On Mon, Nov 09, 2020 at 11:20:24AM +0100, Guennadi Liakhovetski wrote:
> >> Hi Arnaud,
> >>
> >> On Mon, Nov 09, 2020 at 09:48:37AM +0100, Arnaud POULIQUEN wrote:
> >>> Hi Guennadi, Mathieu,
> >>>
> >>> On 11/6/20 6:53 PM, Mathieu Poirier wrote:
> >>>> On Fri, Nov 06, 2020 at 03:00:28PM +0100, Guennadi Liakhovetski wrote:
> >>>>> On Fri, Nov 06, 2020 at 02:15:45PM +0100, Guennadi Liakhovetski wrote:
> >>>>>> Hi Mathieu, Arnaud,
> >>>>>>
> >>>>>> On Thu, Nov 05, 2020 at 03:50:28PM -0700, Mathieu Poirier wrote:
> >>>>>>> From: Arnaud Pouliquen 
> >>>>>>>
> >>>>>>> Make the RPMSG name service announcement a stand alone driver so that 
> >>>>>>> it
> >>>>>>> can be reused by other subsystems.  It is also the first step in 
> >>>>>>> making the
> >>>>>>> functionatlity transport independent, i.e that is not tied to virtIO.
> >>>>>>
> >>>>>> Sorry, I just realised that my testing was incomplete. I haven't 
> >>>>>> tested 
> >>>>>> automatic module loading and indeed it doesn't work. If rpmsg_ns is 
> >>>>>> loaded 
> >>>>>> it probes and it's working, but if it isn't loaded and instead the 
> >>>>>> rpmsg 
> >>>>>> bus driver is probed (e.g. virtio_rpmsg_bus), calling 
> >>>>>> rpmsg_ns_register_device() to create a new rpmsg_ns device doesn't 
> >>>>>> cause 
> >>>>>> rpmsg_ns to be loaded.
> >>>>>
> >>>>> A simple fix for that is using MODULE_ALIAS("rpmsg:rpmsg_ns"); in 
> >>>>> rpmsg_ns.c 
> >>>>> but that alone doesn't fix the problem completely - the module does 
> >>>>> load then 
> >>>>> but not quickly enough, the NS announcement from the host / remote 
> >>>>> arrives 
> >>>>> before rpmsg_ns has properly registered. I think the best solution 
> >>>>> would be 
> >>>>> to link rpmsg_ns.c together with rpmsg_core.c. You'll probably want to 
> >>>>> keep 
> >>>>> the module name, so you could rename them to just core.c and ns.c.
> >>>>
> >>>> I'm pretty sure it is because virtio_device_ready() in rpmsg_probe() is 
> >>>> called
> >>>> before the kernel has finished loading the name space driver.  There has 
> >>>> to be
> >>>> a way to prevent that from happening - I will investigate further.
> >>>
> >>> Right, no dependency is set so the rpmsg_ns driver is never probed...
> >>> And  name service announcement messages are dropped if the service is not 
> >>> present.
> >>
> >> The mentioned change
> >>
> >> -MODULE_ALIAS("rpmsg_ns");
> >> +MODULE_ALIAS("rpmsg:rpmsg_ns");
> > 
> > Yes, I'm good with that part.
> > 
> >>
> >> is actually a compulsory fix, without it the driver doesn't even get 
> >> loaded when 
> >> a device id registered, using rpmsg_ns_register_device(). So this has to 
> >> be done 
> >> as a minimum *if* we keep RPNsg NS as a separate kernel module. However, 
> >> that 
> >> still doesn't fix the problem relyably because of timing. I've merged both 
> >> the 
> >> RPMsg core and NS into a single module, which fixed the issue for me. I'm 
> >> appending a patch to this email, but since it's a "fixup" please, feel 
> >> free to 
> >> roll it into the original work. But thinking about it, even linking 
> >> modules 
> >> together doesn't guarantee the order. I think rpmsg_ns_register_device() 
> >> should 
> >> actually actively wait for NS device probing to finish - successfully or 
> >> not. 
> >> I can add a complete() / wait_for_completion() pair to the process if you 
> >> like.
> >>
> > 
> > Working with a completion is the kind of thing I had in mind.  But I would 
> > still
> > like to keep the drivers separate and that's the par

Re: [PATCH v5 8/8] rpmsg: Turn name service into a stand alone driver

2020-11-09 Thread Guennadi Liakhovetski
Hi Arnaud,

On Mon, Nov 09, 2020 at 09:48:37AM +0100, Arnaud POULIQUEN wrote:
> Hi Guennadi, Mathieu,
> 
> On 11/6/20 6:53 PM, Mathieu Poirier wrote:
> > On Fri, Nov 06, 2020 at 03:00:28PM +0100, Guennadi Liakhovetski wrote:
> >> On Fri, Nov 06, 2020 at 02:15:45PM +0100, Guennadi Liakhovetski wrote:
> >>> Hi Mathieu, Arnaud,
> >>>
> >>> On Thu, Nov 05, 2020 at 03:50:28PM -0700, Mathieu Poirier wrote:
> >>>> From: Arnaud Pouliquen 
> >>>>
> >>>> Make the RPMSG name service announcement a stand alone driver so that it
> >>>> can be reused by other subsystems.  It is also the first step in making 
> >>>> the
> >>>> functionatlity transport independent, i.e that is not tied to virtIO.
> >>>
> >>> Sorry, I just realised that my testing was incomplete. I haven't tested 
> >>> automatic module loading and indeed it doesn't work. If rpmsg_ns is 
> >>> loaded 
> >>> it probes and it's working, but if it isn't loaded and instead the rpmsg 
> >>> bus driver is probed (e.g. virtio_rpmsg_bus), calling 
> >>> rpmsg_ns_register_device() to create a new rpmsg_ns device doesn't cause 
> >>> rpmsg_ns to be loaded.
> >>
> >> A simple fix for that is using MODULE_ALIAS("rpmsg:rpmsg_ns"); in 
> >> rpmsg_ns.c 
> >> but that alone doesn't fix the problem completely - the module does load 
> >> then 
> >> but not quickly enough, the NS announcement from the host / remote arrives 
> >> before rpmsg_ns has properly registered. I think the best solution would 
> >> be 
> >> to link rpmsg_ns.c together with rpmsg_core.c. You'll probably want to 
> >> keep 
> >> the module name, so you could rename them to just core.c and ns.c.
> > 
> > I'm pretty sure it is because virtio_device_ready() in rpmsg_probe() is 
> > called
> > before the kernel has finished loading the name space driver.  There has to 
> > be
> > a way to prevent that from happening - I will investigate further.
> 
> Right, no dependency is set so the rpmsg_ns driver is never probed...
> And  name service announcement messages are dropped if the service is not 
> present.

The mentioned change

-MODULE_ALIAS("rpmsg_ns");
+MODULE_ALIAS("rpmsg:rpmsg_ns");

is actually a compulsory fix, without it the driver doesn't even get loaded 
when 
a device id registered, using rpmsg_ns_register_device(). So this has to be 
done 
as a minimum *if* we keep RPNsg NS as a separate kernel module. However, that 
still doesn't fix the problem relyably because of timing. I've merged both the 
RPMsg core and NS into a single module, which fixed the issue for me. I'm 
appending a patch to this email, but since it's a "fixup" please, feel free to 
roll it into the original work. But thinking about it, even linking modules 
together doesn't guarantee the order. I think rpmsg_ns_register_device() should 
actually actively wait for NS device probing to finish - successfully or not. 
I can add a complete() / wait_for_completion() pair to the process if you like.

Thanks
Guennadi

> if rpmsg_virtio_bus is built-in
> -> using "select RPMSG_NS" in RPMSG_VIRTIO kconfig should ensure that 
> rpmsg_ns is also built-in 
> if rpmsg_virtio_bus is build as module rpmsg_ns.ko should be loaded first.
> -> MODULE_SOFTDEP could be used in virtio_rpmsg_bus.c
> 
> Thanks,
> Arnaud

From: Guennadi Liakhovetski 
Subject: [PATCH] fixup! rpmsg: Turn name service into a stand alone driver

Link ns.c with core.c together to guarantee immediate probing.

Signed-off-by: Guennadi Liakhovetski 
---
 drivers/rpmsg/Makefile   |  2 +-
 drivers/rpmsg/{rpmsg_core.c => core.c}   | 13 ++---
 drivers/rpmsg/{rpmsg_ns.c => ns.c}   | 13 +++--
 include/linux/{rpmsg_ns.h => rpmsg/ns.h} |  6 +-
 4 files changed, 19 insertions(+), 15 deletions(-)
 rename drivers/rpmsg/{rpmsg_core.c => core.c} (99%)
 rename drivers/rpmsg/{rpmsg_ns.c => ns.c} (87%)
 rename include/linux/{rpmsg_ns.h => rpmsg/ns.h} (95%)

diff --git a/drivers/rpmsg/Makefile b/drivers/rpmsg/Makefile
index 8d452656f0ee..5aa79e167372 100644
--- a/drivers/rpmsg/Makefile
+++ b/drivers/rpmsg/Makefile
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
+rpmsg_core-objs:= core.o ns.o
 obj-$(CONFIG_RPMSG)+= rpmsg_core.o
 obj-$(CONFIG_RPMSG_CHAR)   += rpmsg_char.o
-obj-$(CONFIG_RPMSG_NS) += rpmsg_ns.o
 obj-$(CONFIG_RPMSG_MTK_SCP)+= mtk_rpmsg.o
 qcom_glink-objs:= qcom_glink_native.o qcom_glink_ssr.o
 obj-$(CONFIG_RPM

Re: [PATCH v5 8/8] rpmsg: Turn name service into a stand alone driver

2020-11-06 Thread Guennadi Liakhovetski
On Fri, Nov 06, 2020 at 02:15:45PM +0100, Guennadi Liakhovetski wrote:
> Hi Mathieu, Arnaud,
> 
> On Thu, Nov 05, 2020 at 03:50:28PM -0700, Mathieu Poirier wrote:
> > From: Arnaud Pouliquen 
> > 
> > Make the RPMSG name service announcement a stand alone driver so that it
> > can be reused by other subsystems.  It is also the first step in making the
> > functionatlity transport independent, i.e that is not tied to virtIO.
> 
> Sorry, I just realised that my testing was incomplete. I haven't tested 
> automatic module loading and indeed it doesn't work. If rpmsg_ns is loaded 
> it probes and it's working, but if it isn't loaded and instead the rpmsg 
> bus driver is probed (e.g. virtio_rpmsg_bus), calling 
> rpmsg_ns_register_device() to create a new rpmsg_ns device doesn't cause 
> rpmsg_ns to be loaded.

A simple fix for that is using MODULE_ALIAS("rpmsg:rpmsg_ns"); in rpmsg_ns.c 
but that alone doesn't fix the problem completely - the module does load then 
but not quickly enough, the NS announcement from the host / remote arrives 
before rpmsg_ns has properly registered. I think the best solution would be 
to link rpmsg_ns.c together with rpmsg_core.c. You'll probably want to keep 
the module name, so you could rename them to just core.c and ns.c.

Thanks
Guennadi


Re: [PATCH v5 8/8] rpmsg: Turn name service into a stand alone driver

2020-11-06 Thread Guennadi Liakhovetski
Hi Mathieu, Arnaud,

On Thu, Nov 05, 2020 at 03:50:28PM -0700, Mathieu Poirier wrote:
> From: Arnaud Pouliquen 
> 
> Make the RPMSG name service announcement a stand alone driver so that it
> can be reused by other subsystems.  It is also the first step in making the
> functionatlity transport independent, i.e that is not tied to virtIO.

Sorry, I just realised that my testing was incomplete. I haven't tested 
automatic module loading and indeed it doesn't work. If rpmsg_ns is loaded 
it probes and it's working, but if it isn't loaded and instead the rpmsg 
bus driver is probed (e.g. virtio_rpmsg_bus), calling 
rpmsg_ns_register_device() to create a new rpmsg_ns device doesn't cause 
rpmsg_ns to be loaded.

Thanks
Guennadi

> Co-developed-by: Mathieu Poirier 
> Signed-off-by: Mathieu Poirier 
> Signed-off-by: Arnaud Pouliquen 
> ---
>  drivers/rpmsg/Kconfig|   8 +++
>  drivers/rpmsg/Makefile   |   1 +
>  drivers/rpmsg/rpmsg_ns.c | 108 +++
>  drivers/rpmsg/virtio_rpmsg_bus.c |  86 ++--
>  include/linux/rpmsg/ns.h |  18 ++
>  5 files changed, 154 insertions(+), 67 deletions(-)
>  create mode 100644 drivers/rpmsg/rpmsg_ns.c
> 
> diff --git a/drivers/rpmsg/Kconfig b/drivers/rpmsg/Kconfig
> index f96716893c2a..c3fc75e6514b 100644
> --- a/drivers/rpmsg/Kconfig
> +++ b/drivers/rpmsg/Kconfig
> @@ -15,6 +15,14 @@ config RPMSG_CHAR
> in /dev. They make it possible for user-space programs to send and
> receive rpmsg packets.
>  
> +config RPMSG_NS
> + tristate "RPMSG name service announcement"
> + depends on RPMSG
> + help
> +   Say Y here to enable the support of the name service announcement
> +   channel that probes the associated RPMsg device on remote endpoint
> +   service announcement.
> +
>  config RPMSG_MTK_SCP
>   tristate "MediaTek SCP"
>   depends on MTK_SCP
> diff --git a/drivers/rpmsg/Makefile b/drivers/rpmsg/Makefile
> index ffe932ef6050..8d452656f0ee 100644
> --- a/drivers/rpmsg/Makefile
> +++ b/drivers/rpmsg/Makefile
> @@ -1,6 +1,7 @@
>  # SPDX-License-Identifier: GPL-2.0
>  obj-$(CONFIG_RPMSG)  += rpmsg_core.o
>  obj-$(CONFIG_RPMSG_CHAR) += rpmsg_char.o
> +obj-$(CONFIG_RPMSG_NS)   += rpmsg_ns.o
>  obj-$(CONFIG_RPMSG_MTK_SCP)  += mtk_rpmsg.o
>  qcom_glink-objs  := qcom_glink_native.o qcom_glink_ssr.o
>  obj-$(CONFIG_RPMSG_QCOM_GLINK) += qcom_glink.o
> diff --git a/drivers/rpmsg/rpmsg_ns.c b/drivers/rpmsg/rpmsg_ns.c
> new file mode 100644
> index ..5bda7cb44618
> --- /dev/null
> +++ b/drivers/rpmsg/rpmsg_ns.c
> @@ -0,0 +1,108 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) STMicroelectronics 2020 - All Rights Reserved
> + */
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include "rpmsg_internal.h"
> +
> +/* invoked when a name service announcement arrives */
> +static int rpmsg_ns_cb(struct rpmsg_device *rpdev, void *data, int len,
> +void *priv, u32 src)
> +{
> + struct rpmsg_ns_msg *msg = data;
> + struct rpmsg_device *newch;
> + struct rpmsg_channel_info chinfo;
> + struct device *dev = rpdev->dev.parent;
> + int ret;
> +
> +#if defined(CONFIG_DYNAMIC_DEBUG)
> + dynamic_hex_dump("NS announcement: ", DUMP_PREFIX_NONE, 16, 1,
> +  data, len, true);
> +#endif
> +
> + if (len != sizeof(*msg)) {
> + dev_err(dev, "malformed ns msg (%d)\n", len);
> + return -EINVAL;
> + }
> +
> + /* don't trust the remote processor for null terminating the name */
> + msg->name[RPMSG_NAME_SIZE - 1] = '\0';
> +
> + strncpy(chinfo.name, msg->name, sizeof(chinfo.name));
> + chinfo.src = RPMSG_ADDR_ANY;
> + chinfo.dst = rpmsg32_to_cpu(rpdev, msg->addr);
> +
> + dev_info(dev, "%sing channel %s addr 0x%x\n",
> +  rpmsg32_to_cpu(rpdev, msg->flags) & RPMSG_NS_DESTROY ?
> +  "destroy" : "creat", msg->name, chinfo.dst);
> +
> + if (rpmsg32_to_cpu(rpdev, msg->flags) & RPMSG_NS_DESTROY) {
> + ret = rpmsg_release_channel(rpdev, &chinfo);
> + if (ret)
> + dev_err(dev, "rpmsg_destroy_channel failed: %d\n", ret);
> + } else {
> + newch = rpmsg_create_channel(rpdev, &chinfo);
> + if (!newch)
> + dev_err(dev, "rpmsg_create_channel failed\n");
> + }
> +
> + return 0;
> +}
> +
> +static int rpmsg_ns_probe(struct rpmsg_device *rpdev)
> +{
> + struct rpmsg_endpoint *ns_ept;
> + struct rpmsg_channel_info ns_chinfo = {
> + .src = RPMSG_NS_ADDR,
> + .dst = RPMSG_NS_ADDR,
> + .name = "name_service",
> + };
> +
> + /*
> +  * Create the NS announcement service endpoint associated to the RPMsg
> +  * device. The endpoint will be automatically destroyed when the RPMsg
> +  * device will be deleted.

Re: [PATCH v4 8/8] rpmsg: Turn name service into a stand alone driver

2020-11-04 Thread Guennadi Liakhovetski
On Wed, Nov 04, 2020 at 10:34:24AM -0700, Mathieu Poirier wrote:
> On Wed, Nov 04, 2020 at 03:01:44PM +0100, Guennadi Liakhovetski wrote:
> > Hi Mathieu, Arnaud,
> > 
> > I've tried the patch set with my VirtIO / vhost audio implementation, 
> > in general it worked quite well, 
> 
> Very good - it would be nice if you could add your "Tested-by:" tags.

Sure, I guess it would be better if I reply with both "Tested-by" and 
"Reviewed-by" to your next version?

Thanks
Guennadi

> > On Tue, Oct 27, 2020 at 11:52:18AM -0600, Mathieu Poirier wrote:
> > > From: Arnaud Pouliquen 
> > > 
> > > Make the RPMSG name service announcement a stand alone driver so that it
> > > can be reused by other subsystems.  It is also the first step in making 
> > > the
> > > functionatlity transport independent, i.e that is not tied to virtIO.
> > > 
> > > Co-developed-by: Mathieu Poirier 
> > > Signed-off-by: Arnaud Pouliquen 
> > > ---
> > 
> > [snip]
> > 
> > > diff --git a/include/linux/rpmsg_ns.h b/include/linux/rpmsg_ns.h
> > > index bb479f430080..42786bb759b5 100644
> > > --- a/include/linux/rpmsg_ns.h
> > > +++ b/include/linux/rpmsg_ns.h
> > > @@ -39,4 +39,21 @@ enum rpmsg_ns_flags {
> > >  /* Address 53 is reserved for advertising remote services */
> > >  #define RPMSG_NS_ADDR(53)
> > >  
> > > +/**
> > > + * rpmsg_ns_register_device() - register name service device based on 
> > > rpdev
> > > + * @rpdev: prepared rpdev to be used for creating endpoints
> > > + *
> > > + * This function wraps rpmsg_register_device() preparing the rpdev for 
> > > use as
> > > + * basis for the rpmsg name service device.
> > > + */
> > > +static inline int rpmsg_ns_register_device(struct rpmsg_device *rpdev)
> > > +{
> > > +   strcpy(rpdev->id.name, "rpmsg_ns");
> > 
> > you need to
> > 
> > #include 
> 
> Of course yes - I'll simply add the header file.  I plan on having another
> revision addressing your comments out by the end of the week or early next 
> week.
> 
> Thanks,
> Mathieu
> 
> > 
> > in this file for rpdev definition. Or you could leave this function in 
> > rpmsg_ns.c, then it's enough to forward-declare struct rpdev here.
> > 
> > Thanks
> > Guennadi
> > 
> > > +   rpdev->driver_override = "rpmsg_ns";
> > > +   rpdev->src = RPMSG_NS_ADDR;
> > > +   rpdev->dst = RPMSG_NS_ADDR;
> > > +
> > > +   return rpmsg_register_device(rpdev);
> > > +}
> > > +
> > >  #endif
> > > -- 
> > > 2.25.1
> > > 


Re: [PATCH v4 3/8] rpmsg: Move structure rpmsg_ns_msg to header file

2020-11-04 Thread Guennadi Liakhovetski
A nitpick to this one:

On Tue, Oct 27, 2020 at 11:52:13AM -0600, Mathieu Poirier wrote:
> Move structure rpmsg_ns_msg to its own header file so that
> it can be used by other entities.
> 
> Signed-off-by: Mathieu Poirier 
> Reviewed-by: Arnaud Pouliquen 
> ---

[snip]

> diff --git a/include/linux/rpmsg_ns.h b/include/linux/rpmsg_ns.h
> new file mode 100644
> index ..bb479f430080
> --- /dev/null
> +++ b/include/linux/rpmsg_ns.h
> @@ -0,0 +1,42 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +
> +#ifndef _LINUX_RPMSG_NS_H
> +#define _LINUX_RPMSG_NS_H
> +
> +#include 
> +#include 
> +#include 

would be good to sort these alphabetically.

Thanks
Guennadi


Re: [PATCH v4 8/8] rpmsg: Turn name service into a stand alone driver

2020-11-04 Thread Guennadi Liakhovetski
Hi Mathieu, Arnaud,

I've tried the patch set with my VirtIO / vhost audio implementation, 
in general it worked quite well, but I did need one chamge, which 
should be improved in this patch:

On Tue, Oct 27, 2020 at 11:52:18AM -0600, Mathieu Poirier wrote:
> From: Arnaud Pouliquen 
> 
> Make the RPMSG name service announcement a stand alone driver so that it
> can be reused by other subsystems.  It is also the first step in making the
> functionatlity transport independent, i.e that is not tied to virtIO.
> 
> Co-developed-by: Mathieu Poirier 
> Signed-off-by: Arnaud Pouliquen 
> ---

[snip]

> diff --git a/include/linux/rpmsg_ns.h b/include/linux/rpmsg_ns.h
> index bb479f430080..42786bb759b5 100644
> --- a/include/linux/rpmsg_ns.h
> +++ b/include/linux/rpmsg_ns.h
> @@ -39,4 +39,21 @@ enum rpmsg_ns_flags {
>  /* Address 53 is reserved for advertising remote services */
>  #define RPMSG_NS_ADDR(53)
>  
> +/**
> + * rpmsg_ns_register_device() - register name service device based on rpdev
> + * @rpdev: prepared rpdev to be used for creating endpoints
> + *
> + * This function wraps rpmsg_register_device() preparing the rpdev for use as
> + * basis for the rpmsg name service device.
> + */
> +static inline int rpmsg_ns_register_device(struct rpmsg_device *rpdev)
> +{
> +   strcpy(rpdev->id.name, "rpmsg_ns");

you need to

#include 

in this file for rpdev definition. Or you could leave this function in 
rpmsg_ns.c, then it's enough to forward-declare struct rpdev here.

Thanks
Guennadi

> +   rpdev->driver_override = "rpmsg_ns";
> +   rpdev->src = RPMSG_NS_ADDR;
> +   rpdev->dst = RPMSG_NS_ADDR;
> +
> +   return rpmsg_register_device(rpdev);
> +}
> +
>  #endif
> -- 
> 2.25.1
> 


Re: [PATCH v4 3/8] rpmsg: Move structure rpmsg_ns_msg to header file

2020-11-03 Thread Guennadi Liakhovetski
Hi Mathieu,

On Tue, Oct 27, 2020 at 11:52:13AM -0600, Mathieu Poirier wrote:
> Move structure rpmsg_ns_msg to its own header file so that
> it can be used by other entities.
> 
> Signed-off-by: Mathieu Poirier 
> Reviewed-by: Arnaud Pouliquen 
> ---
>  drivers/rpmsg/virtio_rpmsg_bus.c | 32 +---
>  include/linux/rpmsg_ns.h | 42 

Sorry for a delayed comment, it just occurred to me: there is a 
include/linux/rpmsg directory already, so, perhaps it would be 
better to place the new headers there as include/linux/rpmsg/ns.h 
and include/linux/rpmsg/byteorder.h?

Thanks
Guennadi


Re: [PATCH v2 0/9] rpmsg: Make RPMSG name service modular

2020-10-14 Thread Guennadi Liakhovetski
On Tue, Oct 13, 2020 at 05:25:10PM -0600, Mathieu Poirier wrote:
> Good afternoon,
> 
> This set starts by making the RPMSG protocol transport agnostic by
> moving the headers it uses to generic types and using those in the
> current implementation.  From there it re-uses the work that Arnaud
> published[1] to make the name service modular. 
> 
> Tested on stm32mp157 with the RPMSG client sample application.  Applies
> cleanly on v5.9.

Reviewed-by: Guennadi Liakhovetski 

Thanks
Guennadi

> 
> Thanks,
> Mathieu
> 
> [1]. https://patchwork.kernel.org/project/linux-remoteproc/list/?series=338335
> 
> --
> New for V2:
> - Created new RPMSG types (Guennadi).
> - Re-worked byte conversion functions(Guennadi).
> - Added a single ->is_little_endian() operation (Arnaud).
> - Fixed byte conversion before making name service modular.
> 
> Arnaud Pouliquen (4):
>   rpmsg: virtio: Rename rpmsg_create_channel
>   rpmsg: core: Add channel creation internal API
>   rpmsg: virtio: Add rpmsg channel device ops
>   rpmsg: Turn name service into a stand alone driver
> 
> Mathieu Poirier (5):
>   rpmsg: Move rpmsg_endpoint_ops to rpmsg.h
>   rpmsg: Introduce __rpmsg{16|32|64} types
>   rpmsg: virtio: Move from virtio to rpmsg byte conversion
>   rpmsg: Move rpmsg_hr and rpmsg_ns_msg to header file
>   rpmsg: Make rpmsg_{register|unregister}_device() public
> 
>  drivers/rpmsg/Kconfig|   8 ++
>  drivers/rpmsg/Makefile   |   1 +
>  drivers/rpmsg/rpmsg_core.c   |  44 +++
>  drivers/rpmsg/rpmsg_internal.h   |  27 +---
>  drivers/rpmsg/rpmsg_ns.c | 110 +
>  drivers/rpmsg/virtio_rpmsg_bus.c | 206 ++-
>  include/linux/rpmsg.h|  93 --
>  include/linux/rpmsg_byteorder.h  |  67 ++
>  include/linux/rpmsg_ns.h |  79 
>  include/uapi/linux/rpmsg.h   |   3 +
>  include/uapi/linux/rpmsg_types.h |  11 ++
>  11 files changed, 481 insertions(+), 168 deletions(-)
>  create mode 100644 drivers/rpmsg/rpmsg_ns.c
>  create mode 100644 include/linux/rpmsg_byteorder.h
>  create mode 100644 include/linux/rpmsg_ns.h
>  create mode 100644 include/uapi/linux/rpmsg_types.h
> 
> -- 
> 2.25.1
> 


Re: [PATCH 10/10] rpmsg: ns: Make Name service module transport agnostic

2020-09-30 Thread Guennadi Liakhovetski
On Mon, Sep 21, 2020 at 06:10:00PM -0600, Mathieu Poirier wrote:
> Make name service module transport agnostic by using the rpmsg
> device specific byte conversion routine.
> 
> Signed-off-by: Mathieu Poirier 
> ---
>  drivers/rpmsg/rpmsg_ns.c | 10 --
>  include/linux/rpmsg_ns.h |  4 ++--
>  2 files changed, 6 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/rpmsg/rpmsg_ns.c b/drivers/rpmsg/rpmsg_ns.c
> index b3318bf84433..1df3aaadfe10 100644
> --- a/drivers/rpmsg/rpmsg_ns.c
> +++ b/drivers/rpmsg/rpmsg_ns.c
> @@ -18,9 +18,7 @@ static int rpmsg_ns_cb(struct rpmsg_device *rpdev, void 
> *data, int len,
>   struct rpmsg_ns_msg *msg = data;
>   struct rpmsg_device *newch;
>   struct rpmsg_channel_info chinfo;
> - struct virtio_rpmsg_channel *vch = to_virtio_rpmsg_channel(rpdev);
> - struct virtproc_info *vrp = vch->vrp;
> - struct device *dev = &vrp->vdev->dev;
> + struct device *dev = &rpdev->dev;
>   int ret;
>  
>  #if defined(CONFIG_DYNAMIC_DEBUG)
> @@ -38,13 +36,13 @@ static int rpmsg_ns_cb(struct rpmsg_device *rpdev, void 
> *data, int len,
>  
>   strncpy(chinfo.name, msg->name, sizeof(chinfo.name));
>   chinfo.src = RPMSG_ADDR_ANY;
> - chinfo.dst = virtio32_to_cpu(vrp->vdev, msg->addr);
> + chinfo.dst = rpmsg32_to_cpu(rpdev, msg->addr);
>  
>   dev_info(dev, "%sing channel %s addr 0x%x\n",
> -  virtio32_to_cpu(vrp->vdev, msg->flags) & RPMSG_NS_DESTROY ?
> +  rpmsg32_to_cpu(rpdev, msg->flags) & RPMSG_NS_DESTROY ?
>"destroy" : "creat", msg->name, chinfo.dst);
>  
> - if (virtio32_to_cpu(vrp->vdev, msg->flags) & RPMSG_NS_DESTROY) {
> + if (rpmsg32_to_cpu(rpdev, msg->flags) & RPMSG_NS_DESTROY) {
>   ret = rpmsg_release_channel(rpdev, &chinfo);
>   if (ret)
>   dev_err(dev, "rpmsg_destroy_channel failed: %d\n", ret);
> diff --git a/include/linux/rpmsg_ns.h b/include/linux/rpmsg_ns.h
> index aabc6c3c0d6d..9f3030b2145b 100644
> --- a/include/linux/rpmsg_ns.h
> +++ b/include/linux/rpmsg_ns.h
> @@ -41,8 +41,8 @@ struct rpmsg_hdr {
>   */
>  struct rpmsg_ns_msg {
>   char name[RPMSG_NAME_SIZE];
> - __virtio32 addr;
> - __virtio32 flags;
> + u32 addr;
> + u32 flags;

These aren't (necessarily) native endianness, right? Don't they deserve a 
separate type? __rpmsg32?

Thanks
Guennadi

>  } __packed;
>  
>  /**
> -- 
> 2.25.1
> 


Re: [PATCH 08/10] rpmsg: core: Add RPMSG byte conversion operations

2020-09-30 Thread Guennadi Liakhovetski
On Mon, Sep 21, 2020 at 06:09:58PM -0600, Mathieu Poirier wrote:
> Add RPMSG device specific byte conversion operations as a first
> step to separate the RPMSG name space service from the virtIO
> transport layer.
> 
> Signed-off-by: Mathieu Poirier 
> ---
>  drivers/rpmsg/rpmsg_core.c | 51 ++
>  drivers/rpmsg/rpmsg_internal.h | 12 
>  2 files changed, 63 insertions(+)
> 
> diff --git a/drivers/rpmsg/rpmsg_core.c b/drivers/rpmsg/rpmsg_core.c
> index 50a835eaf1ba..66ad5b5f1e87 100644
> --- a/drivers/rpmsg/rpmsg_core.c
> +++ b/drivers/rpmsg/rpmsg_core.c
> @@ -20,6 +20,57 @@
>  
>  #include "rpmsg_internal.h"
>  
> +/**
> + * rpmsg{16|32}_to_cpu()
> + * cpu_to_rpmsg[16|32}() - rpmsg device specific byte conversion functions to
> + *  perform byte conversion between rpmsg device and the
> + *  transport layer it is operating on.
> + */
> +
> +u16 rpmsg16_to_cpu(struct rpmsg_device *rpdev, u16 val)

All the endianness conversions are great as long as they compile to 
NOPs where no conversion is needed. Can we come up with a solution 
to keep it that way?

Thanks
Guennadi

> +{
> + if (WARN_ON(!rpdev))
> + return -EINVAL;
> + if (!rpdev->ops || !rpdev->ops->transport16_to_cpu)
> + return -EPERM;
> +
> + return rpdev->ops->transport16_to_cpu(rpdev, val);
> +}
> +EXPORT_SYMBOL(rpmsg16_to_cpu);
> +
> +u16 cpu_to_rpmsg16(struct rpmsg_device *rpdev, u16 val)
> +{
> + if (WARN_ON(!rpdev))
> + return -EINVAL;
> + if (!rpdev->ops || !rpdev->ops->cpu_to_transport16)
> + return -EPERM;
> +
> + return rpdev->ops->cpu_to_transport16(rpdev, val);
> +}
> +EXPORT_SYMBOL(cpu_to_rpmsg16);
> +
> +u32 rpmsg32_to_cpu(struct rpmsg_device *rpdev, u32 val)
> +{
> + if (WARN_ON(!rpdev))
> + return -EINVAL;
> + if (!rpdev->ops || !rpdev->ops->transport32_to_cpu)
> + return -EPERM;
> +
> + return rpdev->ops->transport32_to_cpu(rpdev, val);
> +}
> +EXPORT_SYMBOL(rpmsg32_to_cpu);
> +
> +u32 cpu_to_rpmsg32(struct rpmsg_device *rpdev, u32 val)
> +{
> + if (WARN_ON(!rpdev))
> + return -EINVAL;
> + if (!rpdev->ops || !rpdev->ops->cpu_to_transport32)
> + return -EPERM;
> +
> + return rpdev->ops->cpu_to_transport32(rpdev, val);
> +}
> +EXPORT_SYMBOL(cpu_to_rpmsg32);
> +
>  /**
>   * rpmsg_create_channel() - create a new rpmsg channel
>   * using its name and address info.
> diff --git a/drivers/rpmsg/rpmsg_internal.h b/drivers/rpmsg/rpmsg_internal.h
> index 2e65386f191e..2f0ad1a52698 100644
> --- a/drivers/rpmsg/rpmsg_internal.h
> +++ b/drivers/rpmsg/rpmsg_internal.h
> @@ -81,6 +81,8 @@ struct virtio_rpmsg_channel {
>  
>  /**
>   * struct rpmsg_device_ops - indirection table for the rpmsg_device 
> operations
> + * @transport{16|32}_to_cpu: byte conversion from rpmsg device to transport 
> layer
> + * @cpu_to_transport{16|32}: byte conversion from transport layer to rpmsg 
> device
>   * @create_channel:  create backend-specific channel, optional
>   * @release_channel: release backend-specific channel, optional
>   * @create_ept:  create backend-specific endpoint, required
> @@ -92,6 +94,10 @@ struct virtio_rpmsg_channel {
>   * advertise new channels implicitly by creating the endpoints.
>   */
>  struct rpmsg_device_ops {
> + u16 (*transport16_to_cpu)(struct rpmsg_device *rpdev, u16 val);
> + u16 (*cpu_to_transport16)(struct rpmsg_device *rpdev, u16 val);
> + u32 (*transport32_to_cpu)(struct rpmsg_device *rpdev, u32 val);
> + u32 (*cpu_to_transport32)(struct rpmsg_device *rpdev, u32 val);
>   struct rpmsg_device *(*create_channel)(struct rpmsg_device *rpdev,
>struct rpmsg_channel_info *chinfo);
>   int (*release_channel)(struct rpmsg_device *rpdev,
> @@ -148,6 +154,12 @@ rpmsg_create_channel(struct rpmsg_device *rpdev,
>struct rpmsg_channel_info *chinfo);
>  int rpmsg_release_channel(struct rpmsg_device *rpdev,
> struct rpmsg_channel_info *chinfo);
> +
> +u16 rpmsg16_to_cpu(struct rpmsg_device *rpdev, u16 val);
> +u16 cpu_to_rpmsg16(struct rpmsg_device *rpdev, u16 val);
> +u32 rpmsg32_to_cpu(struct rpmsg_device *rpdev, u32 val);
> +u32 cpu_to_rpmsg32(struct rpmsg_device *rpdev, u32 val);
> +
>  /**
>   * rpmsg_chrdev_register_device() - register chrdev device based on rpdev
>   * @rpdev:   prepared rpdev to be used for creating endpoints
> -- 
> 2.25.1
> 


Re: [PATCH 06/10] rpmsg: Turn name service into a stand alone driver

2020-09-30 Thread Guennadi Liakhovetski
On Mon, Sep 21, 2020 at 06:09:56PM -0600, Mathieu Poirier wrote:
> From: Arnaud Pouliquen 
> 
> Make the RPMSG name service announcement a stand alone driver so that it
> can be reused by other subsystems.  It is also the first step in making the
> functionatlity transport independent, i.e that is not tied to virtIO.
> 
> Signed-off-by: Arnaud Pouliquen 
> Signed-off-by: Mathieu Poirier 
> ---
>  drivers/rpmsg/Kconfig  |   8 +++
>  drivers/rpmsg/Makefile |   1 +
>  drivers/rpmsg/rpmsg_internal.h |  18 ++
>  drivers/rpmsg/rpmsg_ns.c   | 110 +
>  4 files changed, 137 insertions(+)
>  create mode 100644 drivers/rpmsg/rpmsg_ns.c
> 
> diff --git a/drivers/rpmsg/Kconfig b/drivers/rpmsg/Kconfig
> index f96716893c2a..c3fc75e6514b 100644
> --- a/drivers/rpmsg/Kconfig
> +++ b/drivers/rpmsg/Kconfig
> @@ -15,6 +15,14 @@ config RPMSG_CHAR
> in /dev. They make it possible for user-space programs to send and
> receive rpmsg packets.
>  
> +config RPMSG_NS
> + tristate "RPMSG name service announcement"
> + depends on RPMSG
> + help
> +   Say Y here to enable the support of the name service announcement
> +   channel that probes the associated RPMsg device on remote endpoint
> +   service announcement.
> +
>  config RPMSG_MTK_SCP
>   tristate "MediaTek SCP"
>   depends on MTK_SCP
> diff --git a/drivers/rpmsg/Makefile b/drivers/rpmsg/Makefile
> index ffe932ef6050..8d452656f0ee 100644
> --- a/drivers/rpmsg/Makefile
> +++ b/drivers/rpmsg/Makefile
> @@ -1,6 +1,7 @@
>  # SPDX-License-Identifier: GPL-2.0
>  obj-$(CONFIG_RPMSG)  += rpmsg_core.o
>  obj-$(CONFIG_RPMSG_CHAR) += rpmsg_char.o
> +obj-$(CONFIG_RPMSG_NS)   += rpmsg_ns.o
>  obj-$(CONFIG_RPMSG_MTK_SCP)  += mtk_rpmsg.o
>  qcom_glink-objs  := qcom_glink_native.o qcom_glink_ssr.o
>  obj-$(CONFIG_RPMSG_QCOM_GLINK) += qcom_glink.o
> diff --git a/drivers/rpmsg/rpmsg_internal.h b/drivers/rpmsg/rpmsg_internal.h
> index 3ea9cec26fc0..04e6cb287e18 100644
> --- a/drivers/rpmsg/rpmsg_internal.h
> +++ b/drivers/rpmsg/rpmsg_internal.h
> @@ -15,6 +15,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -164,4 +165,21 @@ static inline int rpmsg_chrdev_register_device(struct 
> rpmsg_device *rpdev)
>   return rpmsg_register_device(rpdev);
>  }
>  
> +/**
> + * rpmsg_ns_register_device() - register name service device based on rpdev
> + * @rpdev: prepared rpdev to be used for creating endpoints
> + *
> + * This function wraps rpmsg_register_device() preparing the rpdev for use as
> + * basis for the rpmsg name service device.
> + */
> +static inline int rpmsg_ns_register_device(struct rpmsg_device *rpdev)
> +{
> + strcpy(rpdev->id.name, "rpmsg_ns");
> + rpdev->driver_override = "rpmsg_ns";
> + rpdev->src = RPMSG_NS_ADDR;
> + rpdev->dst = RPMSG_NS_ADDR;
> +
> + return rpmsg_register_device(rpdev);
> +}
> +
>  #endif
> diff --git a/drivers/rpmsg/rpmsg_ns.c b/drivers/rpmsg/rpmsg_ns.c
> new file mode 100644
> index ..b3318bf84433
> --- /dev/null
> +++ b/drivers/rpmsg/rpmsg_ns.c
> @@ -0,0 +1,110 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) STMicroelectronics 2020 - All Rights Reserved
> + */
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include "rpmsg_internal.h"
> +
> +/* Invoked when a name service announcement arrives */
> +static int rpmsg_ns_cb(struct rpmsg_device *rpdev, void *data, int len,
> +void *priv, u32 src)
> +{
> + struct rpmsg_ns_msg *msg = data;
> + struct rpmsg_device *newch;
> + struct rpmsg_channel_info chinfo;
> + struct virtio_rpmsg_channel *vch = to_virtio_rpmsg_channel(rpdev);

Let's not do this, non-VirtIO RPMsg drivers shouldn't need this struct.

> + struct virtproc_info *vrp = vch->vrp;
> + struct device *dev = &vrp->vdev->dev;
> + int ret;
> +
> +#if defined(CONFIG_DYNAMIC_DEBUG)
> + dynamic_hex_dump("NS announcement: ", DUMP_PREFIX_NONE, 16, 1,
> +  data, len, true);
> +#endif
> +
> + if (len != sizeof(*msg)) {
> + dev_err(dev, "malformed ns msg (%d)\n", len);
> + return -EINVAL;
> + }
> +
> + /* Don't trust the remote processor for null terminating the name */
> + msg->name[RPMSG_NAME_SIZE - 1] = '\0';
> +
> + strncpy(chinfo.name, msg->name, sizeof(chinfo.name));
> + chinfo.src = RPMSG_ADDR_ANY;
> + chinfo.dst = virtio32_to_cpu(vrp->vdev, msg->addr);
> +
> + dev_info(dev, "%sing channel %s addr 0x%x\n",
> +  virtio32_to_cpu(vrp->vdev, msg->flags) & RPMSG_NS_DESTROY ?
> +  "destroy" : "creat", msg->name, chinfo.dst);
> +
> + if (virtio32_to_cpu(vrp->vdev, msg->flags) & RPMSG_NS_DESTROY) {
> + ret = rpmsg_release_channel(rpdev, &chinfo);
> + if (ret)
> + dev_err(dev, "rpms

Re: [PATCH 05/10] rpmsg: virtio: Move virtio RPMSG structures to private header

2020-09-30 Thread Guennadi Liakhovetski
On Mon, Sep 21, 2020 at 06:09:55PM -0600, Mathieu Poirier wrote:
> Move structure virtiproc_info and virtio_rpmsg_channel to rpmsg_internal.h
> so that they can be used by rpmsg_ns.c
> 
> Signed-off-by: Mathieu Poirier 
> ---
>  drivers/rpmsg/rpmsg_internal.h   | 62 
>  drivers/rpmsg/virtio_rpmsg_bus.c | 57 -
>  2 files changed, 62 insertions(+), 57 deletions(-)
> 
> diff --git a/drivers/rpmsg/rpmsg_internal.h b/drivers/rpmsg/rpmsg_internal.h
> index 587f723757d4..3ea9cec26fc0 100644
> --- a/drivers/rpmsg/rpmsg_internal.h
> +++ b/drivers/rpmsg/rpmsg_internal.h
> @@ -12,12 +12,74 @@
>  #ifndef __RPMSG_INTERNAL_H__
>  #define __RPMSG_INTERNAL_H__
>  
> +#include 
> +#include 
>  #include 
> +#include 
> +#include 

I think it would be better to not add any VirtIO dependencies here even 
temporarily.

> +#include 
>  #include 
>  
>  #define to_rpmsg_device(d) container_of(d, struct rpmsg_device, dev)
>  #define to_rpmsg_driver(d) container_of(d, struct rpmsg_driver, drv)
>  
> +/**
> + * struct virtproc_info - virtual remote processor state

This struct shouldn't be here, let's first prepare the NS callback by 
removing any VirtIO dependencies and only then move it to the generic 
driver.

Thanks
Guennadi

> + * @vdev:the virtio device
> + * @rvq: rx virtqueue
> + * @svq: tx virtqueue
> + * @rbufs:   kernel address of rx buffers
> + * @sbufs:   kernel address of tx buffers
> + * @num_bufs:total number of buffers for rx and tx
> + * @buf_size:   size of one rx or tx buffer
> + * @last_sbuf:   index of last tx buffer used
> + * @bufs_dma:dma base addr of the buffers
> + * @tx_lock: protects svq, sbufs and sleepers, to allow concurrent senders.
> + *   sending a message might require waking up a dozing remote
> + *   processor, which involves sleeping, hence the mutex.
> + * @endpoints:   idr of local endpoints, allows fast retrieval
> + * @endpoints_lock: lock of the endpoints set
> + * @sendq:   wait queue of sending contexts waiting for a tx buffers
> + * @sleepers:number of senders that are waiting for a tx buffer
> + * @ns_ept:  the bus's name service endpoint
> + *
> + * This structure stores the rpmsg state of a given virtio remote processor
> + * device (there might be several virtio proc devices for each physical
> + * remote processor).
> + */
> +struct virtproc_info {
> + struct virtio_device *vdev;
> + struct virtqueue *rvq, *svq;
> + void *rbufs, *sbufs;
> + unsigned int num_bufs;
> + unsigned int buf_size;
> + int last_sbuf;
> + dma_addr_t bufs_dma;
> + struct mutex tx_lock;
> + struct idr endpoints;
> + struct mutex endpoints_lock;
> + wait_queue_head_t sendq;
> + atomic_t sleepers;
> + struct rpmsg_endpoint *ns_ept;
> +};
> +
> +/**
> + * struct virtio_rpmsg_channel - rpmsg channel descriptor
> + * @rpdev: the rpmsg channel device
> + * @vrp: the virtio remote processor device this channel belongs to
> + *
> + * This structure stores the channel that links the rpmsg device to the 
> virtio
> + * remote processor device.
> + */
> +struct virtio_rpmsg_channel {
> + struct rpmsg_device rpdev;
> +
> + struct virtproc_info *vrp;
> +};
> +
> +#define to_virtio_rpmsg_channel(_rpdev) \
> + container_of(_rpdev, struct virtio_rpmsg_channel, rpdev)
> +
>  /**
>   * struct rpmsg_device_ops - indirection table for the rpmsg_device 
> operations
>   * @create_channel:  create backend-specific channel, optional
> diff --git a/drivers/rpmsg/virtio_rpmsg_bus.c 
> b/drivers/rpmsg/virtio_rpmsg_bus.c
> index eaf3b2c012c8..0635d86d490f 100644
> --- a/drivers/rpmsg/virtio_rpmsg_bus.c
> +++ b/drivers/rpmsg/virtio_rpmsg_bus.c
> @@ -32,63 +32,6 @@
>  
>  #include "rpmsg_internal.h"
>  
> -/**
> - * struct virtproc_info - virtual remote processor state
> - * @vdev:the virtio device
> - * @rvq: rx virtqueue
> - * @svq: tx virtqueue
> - * @rbufs:   kernel address of rx buffers
> - * @sbufs:   kernel address of tx buffers
> - * @num_bufs:total number of buffers for rx and tx
> - * @buf_size:   size of one rx or tx buffer
> - * @last_sbuf:   index of last tx buffer used
> - * @bufs_dma:dma base addr of the buffers
> - * @tx_lock: protects svq, sbufs and sleepers, to allow concurrent senders.
> - *   sending a message might require waking up a dozing remote
> - *   processor, which involves sleeping, hence the mutex.
> - * @endpoints:   idr of local endpoints, allows fast retrieval
> - * @endpoints_lock: lock of the endpoints set
> - * @sendq:   wait queue of sending contexts waiting for a tx buffers
> - * @sleepers:number of senders that are waiting for a tx buffer
> - * @ns_ept:  the bus's name service endpoint
> - *
> - * This structure stores the rpmsg state of a given virtio remote processor
> - * device (there might be several virtio proc devices for each physical
> - * remote pro

Re: [PATCH 04/10] rpmsg: Move common structures and defines to headers

2020-09-29 Thread Guennadi Liakhovetski
On Mon, Sep 21, 2020 at 06:09:54PM -0600, Mathieu Poirier wrote:
> From: Guennadi Liakhovetski 
> 
> virtio_rpmsg_bus.c keeps RPMsg protocol structure declarations and
> common defines like the ones, needed for name-space announcements,
> internal. Move them to common headers instead.
> 
> Signed-off-by: Guennadi Liakhovetski 
> [Renamed header file from linux/rpmsg/rpmsg_virtio.h to linux/rpmsg_ns.h]

No, this isn't only for the name-service, the message header is common 
for all RPMsg messages.

Thanks
Guennadi

> Signed-off-by: Mathieu Poirier 
> ---
>  drivers/rpmsg/virtio_rpmsg_bus.c | 78 +-
>  include/linux/rpmsg_ns.h | 83 
>  include/uapi/linux/rpmsg.h   |  3 ++
>  3 files changed, 88 insertions(+), 76 deletions(-)
>  create mode 100644 include/linux/rpmsg_ns.h
> 
> diff --git a/drivers/rpmsg/virtio_rpmsg_bus.c 
> b/drivers/rpmsg/virtio_rpmsg_bus.c
> index e87cf0b79542..eaf3b2c012c8 100644
> --- a/drivers/rpmsg/virtio_rpmsg_bus.c
> +++ b/drivers/rpmsg/virtio_rpmsg_bus.c
> @@ -19,6 +19,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -27,6 +28,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  
>  #include "rpmsg_internal.h"
>  
> @@ -70,58 +72,6 @@ struct virtproc_info {
>   struct rpmsg_endpoint *ns_ept;
>  };
>  
> -/* The feature bitmap for virtio rpmsg */
> -#define VIRTIO_RPMSG_F_NS0 /* RP supports name service notifications */
> -
> -/**
> - * struct rpmsg_hdr - common header for all rpmsg messages
> - * @src: source address
> - * @dst: destination address
> - * @reserved: reserved for future use
> - * @len: length of payload (in bytes)
> - * @flags: message flags
> - * @data: @len bytes of message payload data
> - *
> - * Every message sent(/received) on the rpmsg bus begins with this header.
> - */
> -struct rpmsg_hdr {
> - __virtio32 src;
> - __virtio32 dst;
> - __virtio32 reserved;
> - __virtio16 len;
> - __virtio16 flags;
> - u8 data[];
> -} __packed;
> -
> -/**
> - * struct rpmsg_ns_msg - dynamic name service announcement message
> - * @name: name of remote service that is published
> - * @addr: address of remote service that is published
> - * @flags: indicates whether service is created or destroyed
> - *
> - * This message is sent across to publish a new service, or announce
> - * about its removal. When we receive these messages, an appropriate
> - * rpmsg channel (i.e device) is created/destroyed. In turn, the ->probe()
> - * or ->remove() handler of the appropriate rpmsg driver will be invoked
> - * (if/as-soon-as one is registered).
> - */
> -struct rpmsg_ns_msg {
> - char name[RPMSG_NAME_SIZE];
> - __virtio32 addr;
> - __virtio32 flags;
> -} __packed;
> -
> -/**
> - * enum rpmsg_ns_flags - dynamic name service announcement flags
> - *
> - * @RPMSG_NS_CREATE: a new remote service was just created
> - * @RPMSG_NS_DESTROY: a known remote service was just destroyed
> - */
> -enum rpmsg_ns_flags {
> - RPMSG_NS_CREATE = 0,
> - RPMSG_NS_DESTROY= 1,
> -};
> -
>  /**
>   * struct virtio_rpmsg_channel - rpmsg channel descriptor
>   * @rpdev: the rpmsg channel device
> @@ -139,27 +89,6 @@ struct virtio_rpmsg_channel {
>  #define to_virtio_rpmsg_channel(_rpdev) \
>   container_of(_rpdev, struct virtio_rpmsg_channel, rpdev)
>  
> -/*
> - * We're allocating buffers of 512 bytes each for communications. The
> - * number of buffers will be computed from the number of buffers supported
> - * by the vring, upto a maximum of 512 buffers (256 in each direction).
> - *
> - * Each buffer will have 16 bytes for the msg header and 496 bytes for
> - * the payload.
> - *
> - * This will utilize a maximum total space of 256KB for the buffers.
> - *
> - * We might also want to add support for user-provided buffers in time.
> - * This will allow bigger buffer size flexibility, and can also be used
> - * to achieve zero-copy messaging.
> - *
> - * Note that these numbers are purely a decision of this driver - we
> - * can change this without changing anything in the firmware of the remote
> - * processor.
> - */
> -#define MAX_RPMSG_NUM_BUFS   (512)
> -#define MAX_RPMSG_BUF_SIZE   (512)
> -
>  /*
>   * Local addresses are dynamically allocated on-demand.
>   * We do not dynamically assign addresses from the low 1024 range,
> @@ -167,9 +96,6 @@ struct virtio_rpmsg_channel {
>   */
>  #define RPMSG_RESERVED_ADDRESSES (1024)
>  
> -/* Address 53 is reserved for advertising remote services */
> -#d

Re: [PATCH 02/10] rpmsg: core: Add channel creation internal API

2020-09-29 Thread Guennadi Liakhovetski
On Mon, Sep 21, 2020 at 06:09:52PM -0600, Mathieu Poirier wrote:
> From: Arnaud Pouliquen 
> 
> Add the channel creation API as a first step to be able to define the
> name service announcement as a rpmsg driver independent from the RPMsg
> virtio bus.
> 
> Signed-off-by: Arnaud Pouliquen 
> ---
>  drivers/rpmsg/rpmsg_core.c | 45 ++
>  drivers/rpmsg/rpmsg_internal.h | 12 +
>  2 files changed, 57 insertions(+)
> 
> diff --git a/drivers/rpmsg/rpmsg_core.c b/drivers/rpmsg/rpmsg_core.c
> index 91de940896e3..50a835eaf1ba 100644
> --- a/drivers/rpmsg/rpmsg_core.c
> +++ b/drivers/rpmsg/rpmsg_core.c
> @@ -20,6 +20,51 @@
>  
>  #include "rpmsg_internal.h"
>  
> +/**
> + * rpmsg_create_channel() - create a new rpmsg channel
> + * using its name and address info.
> + * @rpdev: rpmsg driver

device

> + * @chinfo: channel_info to bind
> + *
> + * Returns a pointer to the new rpmsg device on success, or NULL on error.
> + */
> +struct rpmsg_device *
> + rpmsg_create_channel(struct rpmsg_device *rpdev,

You might call this nitpicking, but we already have two indentation styles for 
functions:

return_type function(type1 arg1,
...)

(my personal preference, it also has sub-variants - depending on the aligning 
of the second line and any following lines, and one more moving "type1 arg1" 
to the second line)

return_type
function(...

and now you're also introducing the third style - with "function" indented... 
Maybe we don't need more of those, particularly since now with 100 chars per 
line in most cases the very first style can be used.

> +  struct rpmsg_channel_info *chinfo)
> +{
> + if (WARN_ON(!rpdev))
> + return NULL;
> + if (!rpdev->ops || !rpdev->ops->create_channel) {
> + dev_err(&rpdev->dev, "no create_channel ops found\n");
> + return NULL;
> + }
> +
> + return rpdev->ops->create_channel(rpdev, chinfo);
> +}
> +EXPORT_SYMBOL(rpmsg_create_channel);
> +
> +/**
> + * rpmsg_release_channel() - release a rpmsg channel
> + * using its name and address info.
> + * @rpdev: rpmsg driver

device

> + * @chinfo: channel_info to bind
> + *
> + * Returns 0 on success or an appropriate error value.
> + */
> +int rpmsg_release_channel(struct rpmsg_device *rpdev,
> +   struct rpmsg_channel_info *chinfo)
> +{
> + if (WARN_ON(!rpdev))
> + return -EINVAL;
> + if (!rpdev->ops || !rpdev->ops->release_channel) {
> + dev_err(&rpdev->dev, "no release_channel ops found\n");
> + return -EPERM;

ENOSYS or EOPNOTSUPP? I'm never sure which one is appropriate for 
this kind of errors.

> + }
> +
> + return rpdev->ops->release_channel(rpdev, chinfo);
> +}
> +EXPORT_SYMBOL(rpmsg_release_channel);
> +
>  /**
>   * rpmsg_create_ept() - create a new rpmsg_endpoint
>   * @rpdev: rpmsg channel device
> diff --git a/drivers/rpmsg/rpmsg_internal.h b/drivers/rpmsg/rpmsg_internal.h
> index 3fc83cd50e98..587f723757d4 100644
> --- a/drivers/rpmsg/rpmsg_internal.h
> +++ b/drivers/rpmsg/rpmsg_internal.h
> @@ -20,6 +20,8 @@
>  
>  /**
>   * struct rpmsg_device_ops - indirection table for the rpmsg_device 
> operations
> + * @create_channel:  create backend-specific channel, optional
> + * @release_channel: release backend-specific channel, optional

Are they really optional? You return errors if they aren't available.

>   * @create_ept:  create backend-specific endpoint, required
>   * @announce_create: announce presence of new channel, optional
>   * @announce_destroy:announce destruction of channel, optional
> @@ -29,6 +31,11 @@
>   * advertise new channels implicitly by creating the endpoints.
>   */
>  struct rpmsg_device_ops {
> + struct rpmsg_device *(*create_channel)(struct rpmsg_device *rpdev,
> +  struct rpmsg_channel_info *chinfo);
> + int (*release_channel)(struct rpmsg_device *rpdev,
> +struct rpmsg_channel_info *chinfo);
> +
>   struct rpmsg_endpoint *(*create_ept)(struct rpmsg_device *rpdev,
>   rpmsg_rx_cb_t cb, void *priv,
>   struct rpmsg_channel_info chinfo);
> @@ -75,6 +82,11 @@ int rpmsg_unregister_device(struct device *parent,
>  struct device *rpmsg_find_device(struct device *parent,
>struct rpmsg_channel_info *chinfo);
>  
> +struct rpmsg_device *
> +rpmsg_create_channel(struct rpmsg_device *rpdev,
> +  struct rpmsg_channel_info *chinfo);
> +int rpmsg_release_channel(struct rpmsg_device *rpdev,
> +   struct rpmsg_channel_info *chinfo);
>  /**
>   * rpmsg_chrdev_register_device() - register chrdev device based on rpdev
>   * @rpdev:   prepared rpdev to be used for creating endpoints
> -- 
> 2.25.1
> 


Re: [PATCH 00/10] rpmsg: Make RPMSG name service modular

2020-09-29 Thread Guennadi Liakhovetski
Hi Mathieu,

On Mon, Sep 28, 2020 at 01:33:08PM -0600, Mathieu Poirier wrote:
> Hey Guennadi,
> 
> On Mon, Sep 28, 2020 at 11:49:42AM +0200, Guennadi Liakhovetski wrote:
> > (re-sending, mailing list delivery attempts last Friday failed)
> > 
> 
> I got your email on Friday but had to tend to other things.

Sure, no problem, you got it directly because you were on CC, but it didn't 
make it to the mailing lists - you can check archives, it isn't there :-/ 
But thanks to your reply now it's also on the lists.

> > Hi Mathieu,
> > 
> > On Thu, Sep 24, 2020 at 12:18:53PM -0600, Mathieu Poirier wrote:
> > > On Thu, Sep 24, 2020 at 08:53:56AM +0200, Guennadi Liakhovetski wrote:
> > 
> > [snip]
> > 
> > > > Yes, the current rpmsg-virtio code does create *one* rpmsg device when 
> > > > an NS announcement arrives.
> > > 
> > > Currently an rpmsg_device is created each time a NS announcement is 
> > > received.  
> > 
> > Are there really cases when an NS announcement is sent multiple times by a 
> > remote? But not for the same name-space, at least in virtio_rpmsg_bus.c 
> > there's a check for a duplicate announcement in rpmsg_create_channel().
> > 
> > > > Whereas with this patch set the first rpmsg 
> > > > device would be created to probe the NS service driver and the next one 
> > > > would still be created following the code borrowed from rpmsg-virtio 
> > > > when an NS announcement arrives. And I don't see how those two devices 
> > > > now make sense, sorry. I understand one device per channel, but two, of 
> > > > which one is for a certain endpoing only, whereas other endpoints don't 
> > > > create their devices, don't seem very logical to me.
> > > 
> > > In the current implementation the NS service channel is created 
> > > automatically
> > > when instantiating an rproc_vdev.
> > 
> > I think the terminology is slightly incorrect above. It isn't a channel, 
> > it's 
> > an endpoint. A channel is a synonym of a device in RPMsg (from rpmsg.txt):
> > 
> > "Every rpmsg device is a communication channel with a remote processor (thus
> > rpmsg devices are called channels)."
> > 
> > > An official rpmsg_device is not needed since
> > > it is implicit.
> > 
> > Agree.
> > 
> > > With this set (and as you noted above) an rpmsg_device to
> > > represent the NS service is registered, the same way other services such 
> > > as
> > > rpmsg_chrdev are.
> > 
> > Oh, I think I'm getting it now. I think now I understand where the 
> > disagreement lies. If I understand correctly in your model each remote 
> > processor can provide multiple *devices* / *channels*. E.g. a remote
> 
> That is correct
>  
> > processor can provide a character device, a network device etc. Each of 
> > those devices / channels would send a namespace announcement to the 
> > main processor, which then would create a respective device and probe 
> > the respective driver - all with the same remote processor over the same 
> > RPMsg bus. I understand this concept and in fact I find it logical.
> > 
> 
> Ok
> 
> > However, since I have no experience with real life RPMsg implementations 
> > I am basing my understanding of RPMsg on the little and scarce and 
> > non-conclusive documentation that I can find online. E.g. on
> > 
> > https://github.com/OpenAMP/open-amp/wiki/RPMsg-Messaging-Protocol
> > 
> > which says:
> > 
> > "Every remote core in RPMsg component is represented by RPMsg device that 
> > provides a communication channel between master and remote, hence RPMsg 
> > devices are also known as channels"
> > 
> > So, according to that definition you cannot have a remote processor, 
> > doing both a character and a network devices. However, in kernel's 
> > rpmsg.txt an *almost exact* copy of that sentence is the quote, that 
> > I've already provided above, with a subtle but important difference:
> > 
> > "Every rpmsg device is a communication channel with a remote processor 
> > (thus rpmsg devices are called channels)."
> 
> The documentation isn't easy to follow and personally got very confused when I
> started getting involved with the remoteproc/rpmsg subsystems.  I have the
> intention of doing a good revamp but there is never enough time. 
> 
> > 
> > It doesn't explicitly say, that there can be multiple devices per 
> &

Re: [PATCH 00/10] rpmsg: Make RPMSG name service modular

2020-09-23 Thread Guennadi Liakhovetski
Hi Mathieu,

Sorry for a delayed response, after I'd sent that my message I've 
subscribed to remoteproc and it seems during that transition some 
messages were only delivered from the list and not directly to me 
or something similar has happened.

On Tue, Sep 22, 2020 at 01:12:41PM -0600, Mathieu Poirier wrote:
> Good day Guennadi,
> 
> On Tue, 22 Sep 2020 at 02:09, Guennadi Liakhovetski
>  wrote:
> >
> > Hi Mathieu,
> >
> > Thanks for the patches. I'm trying to understand the concept of
> > this approach and I'm probably failing at that. It seems to me
> > that this patch set is making the NS announcement service to a
> > separate RPMsg device and I don't understand the reasoning for
> > doing this. As far as I understand namespace announcements
> > belong to RPMsg devices / channels, they create a dedicated
> > endpoint on them with a fixed pre-defined address. But they
> > don't form a separate RPMsg device. I think the current
> > virtio_rpmsg_bus.c has that correctly: for each rpmsg device /
> > channel multiple endpoints can be created, where the NS
> > service is one of them. It's just an endpoing of an rpmsg
> > device, not a complete separate device. Have I misunderstood
> > anything?
> 
> This patchset does not introduce any new features - the end result in
> terms of functionality is exactly the same.  It is also a carbon copy
> of the work introduced by Arnaud (hence reusing his patches), with the
> exception that the code is presented in a slightly different order to
> allow for a complete dissociation of RPMSG name service from the
> virtIO transport mechanic.
> 
> To make that happen rpmsg device specific byte conversion operations
> had to be introduced in struct rpmsg_device_ops and the explicit
> creation of an rpmsg_device associated with the name service (that
> wasn't needed when name service was welded to virtIO).  But
> associating a rpmsg_device to the name service doesn't change anything
> - RPMSG devices are created the same way when name service messages
> are received from the host or the remote processor.

Yes, the current rpmsg-virtio code does create *one* rpmsg device when 
an NS announcement arrives. Whereas with this patch set the first rpmsg 
device would be created to probe the NS service driver and the next one 
would still be created following the code borrowed from rpmsg-virtio 
when an NS announcement arrives. And I don't see how those two devices 
now make sense, sorry. I understand one device per channel, but two, of 
which one is for a certain endpoing only, whereas other endpoints don't 
create their devices, don't seem very logical to me.

Thanks
Guennadi

> To prove my theory I ran the rpmsg_client_sample.c and it just worked,
> no changes to client code needed.
> 
> Let's keep talking, it's the only way we'll get through this.
> 
> Mathieu
> 
> >
> > Thanks
> > Guennadi
> >
> > On Mon, Sep 21, 2020 at 06:09:50PM -0600, Mathieu Poirier wrote:
> > > Hi all,
> > >
> > > After looking at Guennadi[1] and Arnaud's patchsets[2] it became
> > > clear that we need to go back to a generic rpmsg_ns_msg structure
> > > if we wanted to make progress.  To do that some of the work from
> > > Arnaud had to be modified in a way that common name service
> > > functionality was transport agnostic.
> > >
> > > This patchset is based on Arnaud's work but also include a patch
> > > from Guennadi and some input from me.  It should serve as a
> > > foundation for the next revision of [1].
> > >
> > > Applies on rpmsg-next (4e3dda0bc603) and tested on stm32mp157. I
> > > did not test the modularisation.
> > >
> > > Comments and feedback would be greatly appreciated.
> > >
> > > Thanks,
> > > Mathieu
> > >
> > > [1]. 
> > > https://patchwork.kernel.org/project/linux-remoteproc/list/?series=346593
> > > [2]. 
> > > https://patchwork.kernel.org/project/linux-remoteproc/list/?series=338335
> > >
> > > Arnaud Pouliquen (5):
> > >   rpmsg: virtio: rename rpmsg_create_channel
> > >   rpmsg: core: Add channel creation internal API
> > >   rpmsg: virtio: Add rpmsg channel device ops
> > >   rpmsg: Turn name service into a stand alone driver
> > >   rpmsg: virtio: use rpmsg ns device for the ns announcement
> > >
> > > Guennadi Liakhovetski (1):
> > >   rpmsg: Move common structures and defines to headers
> > >
> > > Mathieu Poirier (4):
> > >   rpmsg: virtio: Move virtio 

Re: [PATCH 00/10] rpmsg: Make RPMSG name service modular

2020-09-22 Thread Guennadi Liakhovetski
Hi Mathieu,

Thanks for the patches. I'm trying to understand the concept of 
this approach and I'm probably failing at that. It seems to me 
that this patch set is making the NS announcement service to a 
separate RPMsg device and I don't understand the reasoning for 
doing this. As far as I understand namespace announcements 
belong to RPMsg devices / channels, they create a dedicated 
endpoint on them with a fixed pre-defined address. But they 
don't form a separate RPMsg device. I think the current 
virtio_rpmsg_bus.c has that correctly: for each rpmsg device / 
channel multiple endpoints can be created, where the NS 
service is one of them. It's just an endpoing of an rpmsg 
device, not a complete separate device. Have I misunderstood 
anything?

Thanks
Guennadi

On Mon, Sep 21, 2020 at 06:09:50PM -0600, Mathieu Poirier wrote:
> Hi all,
> 
> After looking at Guennadi[1] and Arnaud's patchsets[2] it became
> clear that we need to go back to a generic rpmsg_ns_msg structure
> if we wanted to make progress.  To do that some of the work from
> Arnaud had to be modified in a way that common name service
> functionality was transport agnostic.
> 
> This patchset is based on Arnaud's work but also include a patch
> from Guennadi and some input from me.  It should serve as a
> foundation for the next revision of [1].
> 
> Applies on rpmsg-next (4e3dda0bc603) and tested on stm32mp157. I
> did not test the modularisation.   
> 
> Comments and feedback would be greatly appreciated.
> 
> Thanks,
> Mathieu 
> 
> [1]. https://patchwork.kernel.org/project/linux-remoteproc/list/?series=346593
> [2]. https://patchwork.kernel.org/project/linux-remoteproc/list/?series=338335
> 
> Arnaud Pouliquen (5):
>   rpmsg: virtio: rename rpmsg_create_channel
>   rpmsg: core: Add channel creation internal API
>   rpmsg: virtio: Add rpmsg channel device ops
>   rpmsg: Turn name service into a stand alone driver
>   rpmsg: virtio: use rpmsg ns device for the ns announcement
> 
> Guennadi Liakhovetski (1):
>   rpmsg: Move common structures and defines to headers
> 
> Mathieu Poirier (4):
>   rpmsg: virtio: Move virtio RPMSG structures to private header
>   rpmsg: core: Add RPMSG byte conversion operations
>   rpmsg: virtio: Make endianness conversion virtIO specific
>   rpmsg: ns: Make Name service module transport agnostic
> 
>  drivers/rpmsg/Kconfig|   9 +
>  drivers/rpmsg/Makefile   |   1 +
>  drivers/rpmsg/rpmsg_core.c   |  96 +++
>  drivers/rpmsg/rpmsg_internal.h   | 102 +++
>  drivers/rpmsg/rpmsg_ns.c | 108 
>  drivers/rpmsg/virtio_rpmsg_bus.c | 284 +--
>  include/linux/rpmsg_ns.h |  83 +
>  include/uapi/linux/rpmsg.h   |   3 +
>  8 files changed, 487 insertions(+), 199 deletions(-)
>  create mode 100644 drivers/rpmsg/rpmsg_ns.c
>  create mode 100644 include/linux/rpmsg_ns.h
> 
> -- 
> 2.25.1
> 


Re: [PATCH 01/10] rpmsg: virtio: rename rpmsg_create_channel

2020-09-22 Thread Guennadi Liakhovetski
On Mon, Sep 21, 2020 at 06:09:51PM -0600, Mathieu Poirier wrote:
> From: Arnaud Pouliquen 
> 
> Rename the internal function as it is internal, and as
> the name will be used in rpmsg_core.
> 
> Signed-off-by: Arnaud Pouliquen 
> ---
>  drivers/rpmsg/virtio_rpmsg_bus.c | 7 ---
>  1 file changed, 4 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/rpmsg/virtio_rpmsg_bus.c 
> b/drivers/rpmsg/virtio_rpmsg_bus.c
> index 7d7ed4e5cce7..e8d55c8b9cbf 100644
> --- a/drivers/rpmsg/virtio_rpmsg_bus.c
> +++ b/drivers/rpmsg/virtio_rpmsg_bus.c
> @@ -395,8 +395,9 @@ static void virtio_rpmsg_release_device(struct device 
> *dev)
>   * this function will be used to create both static and dynamic
>   * channels.
>   */
> -static struct rpmsg_device *rpmsg_create_channel(struct virtproc_info *vrp,
> -  struct rpmsg_channel_info 
> *chinfo)
> +static struct rpmsg_device *
> +__rpmsg_create_channel(struct virtproc_info *vrp,
> +struct rpmsg_channel_info *chinfo)

Nitpick: we now have 100 characters, so there's no *need* any more to split 
that 
line, now it's more a matter of consistent style and personal preference. Most 
functions in that file have function type and name on the same line, but a few 
also make the split like here... So, we can choose our poison here I guess.

Thanks
Guennadi

>  {
>   struct virtio_rpmsg_channel *vch;
>   struct rpmsg_device *rpdev;
> @@ -869,7 +870,7 @@ static int rpmsg_ns_cb(struct rpmsg_device *rpdev, void 
> *data, int len,
>   if (ret)
>   dev_err(dev, "rpmsg_destroy_channel failed: %d\n", ret);
>   } else {
> - newch = rpmsg_create_channel(vrp, &chinfo);
> + newch = __rpmsg_create_channel(vrp, &chinfo);
>   if (!newch)
>   dev_err(dev, "rpmsg_create_channel failed\n");
>   }
> -- 
> 2.25.1
> 


Re: linux-next: build failure after merge of the vhost tree

2020-08-04 Thread Guennadi Liakhovetski
Michael, looks like something went wrong with your merge? My patch 
https://lore.kernel.org/r/20200722150927.15587-3-guennadi.liakhovet...@linux.intel.com
 
has the header, your merged commit 
https://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost.git/commit/?h=vhost&id=bba6f4f52c31af1ce4ebcc063afa08eb063b3d2c
doesn't have it?

Thanks
Guennadi

On Tue, Aug 04, 2020 at 07:47:58AM +0200, Guennadi Liakhovetski wrote:
> Hi Stephen,
> 
> On Tue, Aug 04, 2020 at 03:11:17PM +1000, Stephen Rothwell wrote:
> > Hi all,
> > 
> > After merging the vhost tree, today's linux-next build (arm
> > multi_v7_defconfig) failed like this:
> > 
> > drivers/rpmsg/virtio_rpmsg_bus.c:28:10: fatal error: linux/virtio_rpmsg.h: 
> > No such file or directory
> >28 | #include 
> >   |  ^~
> > 
> > Caused by commit
> > 
> >   bba6f4f52c31 ("rpmsg: move common structures and defines to headers")
> > 
> > I have used the vhost tree from next-20200803 for today.
> 
> Yes, I've seen that, that's a clang build for MIPS... I'll have a look.
> 
> Thanks
> Guennadi
> 
> > -- 
> > Cheers,
> > Stephen Rothwell


Re: linux-next: build failure after merge of the vhost tree

2020-08-03 Thread Guennadi Liakhovetski
Hi Stephen,

On Tue, Aug 04, 2020 at 03:11:17PM +1000, Stephen Rothwell wrote:
> Hi all,
> 
> After merging the vhost tree, today's linux-next build (arm
> multi_v7_defconfig) failed like this:
> 
> drivers/rpmsg/virtio_rpmsg_bus.c:28:10: fatal error: linux/virtio_rpmsg.h: No 
> such file or directory
>28 | #include 
>   |  ^~
> 
> Caused by commit
> 
>   bba6f4f52c31 ("rpmsg: move common structures and defines to headers")
> 
> I have used the vhost tree from next-20200803 for today.

Yes, I've seen that, that's a clang build for MIPS... I'll have a look.

Thanks
Guennadi

> -- 
> Cheers,
> Stephen Rothwell




Re: [PATCH v4 1/3] virtio: add dma-buf support for exported objects

2020-06-18 Thread Guennadi Liakhovetski
Hi David,

On Fri, Jun 19, 2020 at 10:57:37AM +0900, David Stevens wrote:
> On Thu, Jun 18, 2020 at 9:29 PM Guennadi Liakhovetski
>  wrote:
> >
> > Hi Michael,
> >
> > On Thu, Jun 04, 2020 at 03:05:23PM -0400, Michael S. Tsirkin wrote:
> > > On Tue, May 26, 2020 at 07:58:09PM +0900, David Stevens wrote:
> > > > This change adds a new flavor of dma-bufs that can be used by virtio
> > > > drivers to share exported objects. A virtio dma-buf can be queried by
> > > > virtio drivers to obtain the UUID which identifies the underlying
> > > > exported object.
> > > >
> > > > Signed-off-by: David Stevens 
> > >
> > > Is this just for graphics? If yes I'd rather we put it in the graphics
> > > driver. We can always move it later ...
> >
> > Wouldn't this be the API that audio virtualisation will have to use to share
> > buffers between the host and any guests?
> 
> The new flavor of dma-buf isn't directly related to sharing buffers
> between the host and the guest. The purpose of this API is to help
> share buffers between multiple virtio devices - e.g. share buffers
> created by a virito-gpu device with a virito-video device. In
> particular, the new flavor of dma-buf provides a mechanism to attach
> identifying metadata to a dma-buf object that is shared between
> different virtio drivers in a single guest. This identifying metadata
> can then be passed to the importing device and used to fetch some
> resource from the exporting device. But the new flavor of dma-buf is
> an abstraction within the guest kernel, independent of the host-guest
> boundary, and it's definitely not necessary if we're only talking
> about a single virtio subsystem.

Thanks for the explanation!

Regards
Guennadi

> > > > ---
> > > >  drivers/virtio/Makefile |  2 +-
> > > >  drivers/virtio/virtio.c |  6 +++
> > > >  drivers/virtio/virtio_dma_buf.c | 89 +
> > > >  include/linux/virtio.h  |  1 +
> > > >  include/linux/virtio_dma_buf.h  | 58 +
> > > >  5 files changed, 155 insertions(+), 1 deletion(-)
> > > >  create mode 100644 drivers/virtio/virtio_dma_buf.c
> > > >  create mode 100644 include/linux/virtio_dma_buf.h
> > > >
> > > > diff --git a/drivers/virtio/Makefile b/drivers/virtio/Makefile
> > > > index 29a1386ecc03..ecdae5b596de 100644
> > > > --- a/drivers/virtio/Makefile
> > > > +++ b/drivers/virtio/Makefile
> > > > @@ -1,5 +1,5 @@
> > > >  # SPDX-License-Identifier: GPL-2.0
> > > > -obj-$(CONFIG_VIRTIO) += virtio.o virtio_ring.o
> > > > +obj-$(CONFIG_VIRTIO) += virtio.o virtio_ring.o virtio_dma_buf.o
> > > >  obj-$(CONFIG_VIRTIO_MMIO) += virtio_mmio.o
> > > >  obj-$(CONFIG_VIRTIO_PCI) += virtio_pci.o
> > > >  virtio_pci-y := virtio_pci_modern.o virtio_pci_common.o
> > > > diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
> > > > index a977e32a88f2..5d46f0ded92d 100644
> > > > --- a/drivers/virtio/virtio.c
> > > > +++ b/drivers/virtio/virtio.c
> > > > @@ -357,6 +357,12 @@ int register_virtio_device(struct virtio_device 
> > > > *dev)
> > > >  }
> > > >  EXPORT_SYMBOL_GPL(register_virtio_device);
> > > >
> > > > +bool is_virtio_device(struct device *dev)
> > > > +{
> > > > +   return dev->bus == &virtio_bus;
> > > > +}
> > > > +EXPORT_SYMBOL_GPL(is_virtio_device);
> > > > +
> > > >  void unregister_virtio_device(struct virtio_device *dev)
> > > >  {
> > > > int index = dev->index; /* save for after device release */
> > > > diff --git a/drivers/virtio/virtio_dma_buf.c 
> > > > b/drivers/virtio/virtio_dma_buf.c
> > > > new file mode 100644
> > > > index ..23e3399b11ed
> > > > --- /dev/null
> > > > +++ b/drivers/virtio/virtio_dma_buf.c
> > > > @@ -0,0 +1,89 @@
> > > > +// SPDX-License-Identifier: GPL-2.0-or-later
> > > > +/*
> > > > + * dma-bufs for virtio exported objects
> > > > + *
> > > > + * Copyright (C) 2020 Google, Inc.
> > > > + */
> > > > +
> > > > +#include 
> > > > +
> > > > +/**
> > > > + * virtio_dma_buf_export - Creates a new dma-buf for a virtio exported 
> > > > object
> > > > + *
> > &g

Re: [PATCH v4 1/3] virtio: add dma-buf support for exported objects

2020-06-18 Thread Guennadi Liakhovetski
Hi Michael,

On Thu, Jun 04, 2020 at 03:05:23PM -0400, Michael S. Tsirkin wrote:
> On Tue, May 26, 2020 at 07:58:09PM +0900, David Stevens wrote:
> > This change adds a new flavor of dma-bufs that can be used by virtio
> > drivers to share exported objects. A virtio dma-buf can be queried by
> > virtio drivers to obtain the UUID which identifies the underlying
> > exported object.
> > 
> > Signed-off-by: David Stevens 
> 
> Is this just for graphics? If yes I'd rather we put it in the graphics
> driver. We can always move it later ...

Wouldn't this be the API that audio virtualisation will have to use to share 
buffers between the host and any guests?

Thanks
Guennadi

> > ---
> >  drivers/virtio/Makefile |  2 +-
> >  drivers/virtio/virtio.c |  6 +++
> >  drivers/virtio/virtio_dma_buf.c | 89 +
> >  include/linux/virtio.h  |  1 +
> >  include/linux/virtio_dma_buf.h  | 58 +
> >  5 files changed, 155 insertions(+), 1 deletion(-)
> >  create mode 100644 drivers/virtio/virtio_dma_buf.c
> >  create mode 100644 include/linux/virtio_dma_buf.h
> > 
> > diff --git a/drivers/virtio/Makefile b/drivers/virtio/Makefile
> > index 29a1386ecc03..ecdae5b596de 100644
> > --- a/drivers/virtio/Makefile
> > +++ b/drivers/virtio/Makefile
> > @@ -1,5 +1,5 @@
> >  # SPDX-License-Identifier: GPL-2.0
> > -obj-$(CONFIG_VIRTIO) += virtio.o virtio_ring.o
> > +obj-$(CONFIG_VIRTIO) += virtio.o virtio_ring.o virtio_dma_buf.o
> >  obj-$(CONFIG_VIRTIO_MMIO) += virtio_mmio.o
> >  obj-$(CONFIG_VIRTIO_PCI) += virtio_pci.o
> >  virtio_pci-y := virtio_pci_modern.o virtio_pci_common.o
> > diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
> > index a977e32a88f2..5d46f0ded92d 100644
> > --- a/drivers/virtio/virtio.c
> > +++ b/drivers/virtio/virtio.c
> > @@ -357,6 +357,12 @@ int register_virtio_device(struct virtio_device *dev)
> >  }
> >  EXPORT_SYMBOL_GPL(register_virtio_device);
> >  
> > +bool is_virtio_device(struct device *dev)
> > +{
> > +   return dev->bus == &virtio_bus;
> > +}
> > +EXPORT_SYMBOL_GPL(is_virtio_device);
> > +
> >  void unregister_virtio_device(struct virtio_device *dev)
> >  {
> > int index = dev->index; /* save for after device release */
> > diff --git a/drivers/virtio/virtio_dma_buf.c 
> > b/drivers/virtio/virtio_dma_buf.c
> > new file mode 100644
> > index ..23e3399b11ed
> > --- /dev/null
> > +++ b/drivers/virtio/virtio_dma_buf.c
> > @@ -0,0 +1,89 @@
> > +// SPDX-License-Identifier: GPL-2.0-or-later
> > +/*
> > + * dma-bufs for virtio exported objects
> > + *
> > + * Copyright (C) 2020 Google, Inc.
> > + */
> > +
> > +#include 
> > +
> > +/**
> > + * virtio_dma_buf_export - Creates a new dma-buf for a virtio exported 
> > object
> > + *
> > + * This wraps dma_buf_export() to allow virtio drivers to create a dma-buf
> > + * for an virtio exported object that can be queried by other virtio 
> > drivers
> > + * for the object's UUID.
> > + */
> > +struct dma_buf *virtio_dma_buf_export(
> > +   const struct virtio_dma_buf_export_info *virtio_exp_info)
> > +{
> > +   struct dma_buf_export_info exp_info;
> > +
> > +   if (!virtio_exp_info->ops
> > +   || virtio_exp_info->ops->ops.attach != &virtio_dma_buf_attach
> > +   || !virtio_exp_info->ops->get_uuid) {
> > +   return ERR_PTR(-EINVAL);
> > +   }
> > +
> > +   exp_info.exp_name = virtio_exp_info->exp_name;
> > +   exp_info.owner = virtio_exp_info->owner;
> > +   exp_info.ops = &virtio_exp_info->ops->ops;
> > +   exp_info.size = virtio_exp_info->size;
> > +   exp_info.flags = virtio_exp_info->flags;
> > +   exp_info.resv = virtio_exp_info->resv;
> > +   exp_info.priv = virtio_exp_info->priv;
> > +   BUILD_BUG_ON(sizeof(struct virtio_dma_buf_export_info)
> > +!= sizeof(struct dma_buf_export_info));
> 
> This is the only part that gives me pause. Why do we need this hack?
> What's wrong with just using dma_buf_export_info directly,
> and if you want the virtio ops, just using container_off?
> 
> 
> 
> > +
> > +   return dma_buf_export(&exp_info);
> > +}
> > +EXPORT_SYMBOL(virtio_dma_buf_export);
> > +
> > +/**
> > + * virtio_dma_buf_attach - mandatory attach callback for virtio dma-bufs
> > + */
> > +int virtio_dma_buf_attach(struct dma_buf *dma_buf,
> > + struct dma_buf_attachment *attach)
> > +{
> > +   int ret;
> > +   const struct virtio_dma_buf_ops *ops = container_of(
> > +   dma_buf->ops, const struct virtio_dma_buf_ops, ops);
> > +
> > +   if (ops->device_attach) {
> > +   ret = ops->device_attach(dma_buf, attach);
> > +   if (ret)
> > +   return ret;
> > +   }
> > +   return 0;
> > +}
> > +EXPORT_SYMBOL(virtio_dma_buf_attach);
> > +
> > +/**
> > + * is_virtio_dma_buf - returns true if the given dma-buf is a virtio 
> > dma-buf
> > + * @dma_buf: buffer to query
> > + */
> > +bool is_virtio_dma_buf(struct dma_buf *dma_buf)
> > +{
> > +   return dma_buf

Re: [alsa-devel] [RFC PATCH 0/5] ASoC: SOF: Intel: SoundWire initial integration

2019-08-22 Thread Guennadi Liakhovetski
Hi Pierre,

In patch 4/5 I forgot to mention superfluous braces around dev_err() 
in sdw_config_stream() and sdw_free_stream(). Otherwise for the series:

Reviewed-by: Guennadi Liakhovetski 

Thanks
Guennadi

On Wed, Aug 21, 2019 at 03:17:15PM -0500, Pierre-Louis Bossart wrote:
> This RFC is the companion of the other RFC 'soundwire: intel: simplify
> DAI/PDI handling​'. Our purpose at this point is to gather feedback on
> the interfaces between the Intel SOF parts and the SoundWire code.
> 
> The suggested solution is a simple init/release inserted at
> probe/remove and resume/suspend, as well as two callbacks for the SOF
> driver to generate IPC configurations with the firmware. That level of
> separation completely hides the details of the SoundWire DAIs and will
> allow for 'transparent' multi-cpu DAI support, which will be handled
> in the machine driver and the soundwire DAIs.
> 
> This solution was tested on IceLake and CometLake, and captures the
> feedback from SOF contributors on an initial integration that was
> deemed too complicated (and rightly so).
> 
> Pierre-Louis Bossart (5):
>   ASoC: SOF: IPC: dai-intel: move ALH declarations in header file
>   ASoC: SOF: Intel: hda: add helper to initialize SoundWire IP
>   ASoC: SOF: Intel: hda: add SoundWire IP support
>   ASoC: SOF: Intel: hda: add SoundWire stream config/free callbacks
>   ASoC: SOF: Intel: add support for SoundWire suspend/resume
> 
>  include/sound/sof/dai-intel.h |  18 ++--
>  sound/soc/sof/intel/hda-dsp.c |  11 +++
>  sound/soc/sof/intel/hda.c | 157 ++
>  sound/soc/sof/intel/hda.h |  11 +++
>  4 files changed, 188 insertions(+), 9 deletions(-)
> 
> 
> base-commit: 3b3aaa017e8072b1bfddda92be296b3463d870be
> -- 
> 2.20.1
> 
> ___
> Alsa-devel mailing list
> alsa-de...@alsa-project.org
> https://mailman.alsa-project.org/mailman/listinfo/alsa-devel


Re: [RFC PATCH 4/5] ASoC: SOF: Intel: hda: add SoundWire stream config/free callbacks

2019-08-22 Thread Guennadi Liakhovetski
On Thu, Aug 22, 2019 at 08:53:06AM -0500, Pierre-Louis Bossart wrote:
> Thanks for the review Guennadi
> 
> > > +static int sdw_config_stream(void *arg, void *s, void *dai,
> > > +  void *params, int link_id, int alh_stream_id)
> > 
> > I realise, that these function prototypes aren't being introduced by these
> > patches, but just wondering whether such overly generic prototype is really
> > a good idea here, whether some of those "void *" pointers could be given
> > real types. The first one could be "struct device *" etc.
> 
> In this case the 'arg' parameter is actually a private 'struct snd_sof_dev',
> as shown below [1]. We probably want to keep this relatively opaque, this is
> a context that doesn't need to be exposed to the SoundWire code.

Right, that's why I proposed struct device and not struct snd_sof_dev, to not 
make it SOF-specific, then sdev could be obtained from dev_get_drvdata(). But 
yes, that's unrelated to this series.

Thanks
Guennadi


Re: [RFC PATCH 4/5] ASoC: SOF: Intel: hda: add SoundWire stream config/free callbacks

2019-08-22 Thread Guennadi Liakhovetski
On Thu, Aug 22, 2019 at 09:18:35AM +0200, Guennadi Liakhovetski wrote:

[snip]

> >  static int hda_sdw_init(struct snd_sof_dev *sdev)
> >  {
> > acpi_handle handle;
> > @@ -67,6 +131,8 @@ static int hda_sdw_init(struct snd_sof_dev *sdev)
> > res.mmio_base = sdev->bar[HDA_DSP_BAR];
> > res.irq = sdev->ipc_irq;
> > res.parent = sdev->dev;
> > +   res.ops = &sdw_callback;
> > +   res.arg = sdev;
> >  
> > sdw = sdw_intel_init(handle, &res);
> > if (!sdw) {
> 
> Hm, looks like this function is using spaces for indentation... Let me check 
> if this is coming from an earlier patch

Ouch, it's mutt or whatever editor it's using... Sorry for the noise.

Thanks
Guennadi


Re: [RFC PATCH 4/5] ASoC: SOF: Intel: hda: add SoundWire stream config/free callbacks

2019-08-22 Thread Guennadi Liakhovetski
Hi Pierre,

A couple of comments below

On Wed, Aug 21, 2019 at 03:17:19PM -0500, Pierre-Louis Bossart wrote:
> These callbacks are invoked when a matching hw_params/hw_free() DAI
> operation takes place, and will result in IPC operations with the SOF
> firmware.
> 
> Signed-off-by: Pierre-Louis Bossart 
> ---
>  sound/soc/sof/intel/hda.c | 66 +++
>  1 file changed, 66 insertions(+)
> 
> diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c
> index e754058e3679..1e84ea9e6fce 100644
> --- a/sound/soc/sof/intel/hda.c
> +++ b/sound/soc/sof/intel/hda.c
> @@ -53,6 +53,70 @@ static void hda_sdw_int_enable(struct snd_sof_dev *sdev, 
> bool enable)
>   0);
>  }
>  
> +static int sdw_config_stream(void *arg, void *s, void *dai,
> +  void *params, int link_id, int alh_stream_id)

I realise, that these function prototypes aren't being introduced by these 
patches, but just wondering whether such overly generic prototype is really 
a good idea here, whether some of those "void *" pointers could be given 
real types. The first one could be "struct device *" etc.

> +{
> + struct snd_sof_dev *sdev = arg;
> + struct snd_soc_dai *d = dai;
> + struct sof_ipc_dai_config config;
> + struct sof_ipc_reply reply;
> + int ret;
> + u32 size = sizeof(config);
> +
> + memset(&config, 0, size);
> + config.hdr.size = size;
> + config.hdr.cmd = SOF_IPC_GLB_DAI_MSG | SOF_IPC_DAI_CONFIG;
> + config.type = SOF_DAI_INTEL_ALH;
> + config.dai_index = (link_id << 8) | (d->id);
> + config.alh.stream_id = alh_stream_id;

Entirely up to you, in such cases I usually do something like

+   struct sof_ipc_dai_config config = {
+   .type = SOF_DAI_INTEL_ALH,
+   .hre = {
+   .size = sizeof(config),
+   .cmd = SOF_IPC_GLB_DAI_MSG | SOF_IPC_DAI_CONFIG,
+   ...

which then also avoids a memset(). But that's mostly a matter of personal 
preference, since this is on stack, the compiler would probably internally 
anyway translate the above initialisation to a memset() with all the 
following assignments.

> +
> + /* send message to DSP */
> + ret = sof_ipc_tx_message(sdev->ipc,
> +  config.hdr.cmd, &config, size, &reply,
> +  sizeof(reply));
> + if (ret < 0) {
> + dev_err(sdev->dev,
> + "error: failed to set DAI hw_params for link %d dai->id 
> %d ALH %d\n",

Are readers really expected to understand what "dai->id" means? Wouldn't 
"DAI ID" be friendlier, although I understand you - who might not know 
what "x->y" stands for?.. ;-)

> + link_id, d->id, alh_stream_id);
> + }
> +
> + return ret;
> +}
> +
> +static int sdw_free_stream(void *arg, void *s, void *dai, int link_id)
> +{
> + struct snd_sof_dev *sdev = arg;
> + struct snd_soc_dai *d = dai;
> + struct sof_ipc_dai_config config;
> + struct sof_ipc_reply reply;
> + int ret;
> + u32 size = sizeof(config);
> +
> + memset(&config, 0, size);
> + config.hdr.size = size;
> + config.hdr.cmd = SOF_IPC_GLB_DAI_MSG | SOF_IPC_DAI_CONFIG;
> + config.type = SOF_DAI_INTEL_ALH;
> + config.dai_index = (link_id << 8) | d->id;
> + config.alh.stream_id = 0x; /* invalid value on purpose */

ditto

> +
> + /* send message to DSP */
> + ret = sof_ipc_tx_message(sdev->ipc,
> +  config.hdr.cmd, &config, size, &reply,
> +  sizeof(reply));
> + if (ret < 0) {
> + dev_err(sdev->dev,
> + "error: failed to free stream for link %d dai->id %d\n",
> + link_id, d->id);

ditto

> + }
> +
> + return ret;
> +}
> +
> +static const struct sdw_intel_ops sdw_callback = {
> + .config_stream = sdw_config_stream,
> + .free_stream = sdw_free_stream,
> +};
> +
>  static int hda_sdw_init(struct snd_sof_dev *sdev)
>  {
>   acpi_handle handle;
> @@ -67,6 +131,8 @@ static int hda_sdw_init(struct snd_sof_dev *sdev)
>   res.mmio_base = sdev->bar[HDA_DSP_BAR];
>   res.irq = sdev->ipc_irq;
>   res.parent = sdev->dev;
> + res.ops = &sdw_callback;
> + res.arg = sdev;
>  
>   sdw = sdw_intel_init(handle, &res);
>   if (!sdw) {

Hm, looks like this function is using spaces for indentation... Let me check 
if this is coming from an earlier patch

Thanks
Guennadi

> -- 
> 2.20.1
> 


Re: [alsa-devel] [RFC PATCH 17/40] soundwire: bus: use runtime_pm_get_sync/pm when enabled

2019-07-26 Thread Guennadi Liakhovetski
On Fri, Jul 26, 2019 at 01:08:57PM -0500, Pierre-Louis Bossart wrote:
> This thread became unreadable with interleaved top-posting, allow me restate
> the options and ask PM folks what they think
> 
> On 7/25/19 6:40 PM, Pierre-Louis Bossart wrote:
> > Not all platforms support runtime_pm for now, let's use runtime_pm
> > only when enabled.
> > 
> > Suggested-by: Srinivas Kandagatla 
> > Signed-off-by: Pierre-Louis Bossart 
> > ---
> >   drivers/soundwire/bus.c | 25 -
> >   1 file changed, 16 insertions(+), 9 deletions(-)
> > 
> > diff --git a/drivers/soundwire/bus.c b/drivers/soundwire/bus.c
> > index 5ad4109dc72f..0a45dc5713df 100644
> > --- a/drivers/soundwire/bus.c
> > +++ b/drivers/soundwire/bus.c
> > @@ -332,12 +332,16 @@ int sdw_nread(struct sdw_slave *slave, u32 addr, 
> > size_t count, u8 *val)
> > if (ret < 0)
> > return ret;
> > -   ret = pm_runtime_get_sync(slave->bus->dev);
> > -   if (ret < 0)
> > -   return ret;
> > +   if (pm_runtime_enabled(slave->bus->dev)) {
> > +   ret = pm_runtime_get_sync(slave->bus->dev);
> > +   if (ret < 0)
> > +   return ret;
> > +   }
> > ret = sdw_transfer(slave->bus, &msg);
> > -   pm_runtime_put(slave->bus->dev);
> > +
> > +   if (pm_runtime_enabled(slave->bus->dev))
> > +   pm_runtime_put(slave->bus->dev);
> 
> This is option1: we explicitly test if pm_runtime is enabled before calling
> _get_sync() and _put()
> 
> option2 (suggested by Jan Kotas): catch the -EACCESS error code
> 
>   ret = pm_runtime_get_sync(slave->bus->dev);
> - if (ret < 0)
> + if (ret < 0 && ret != -EACCES)
>   return ret;
> 
> option3: ignore the return value as done in quite a few drivers
> 
> Are there any other options? I am personally surprised this is not handled
> in the pm_runtime core, not sure why users need to test for this?

option 4: fix this in runtime PM :-) This seems like the best option to me,
but probably not the easiest one. Otherwise I'd go with (2), I think, since
that's also the official purpose of the -EACCESS return code:

https://lists.linuxfoundation.org/pipermail/linux-pm/2011-June/031930.html

Thanks
Guennadi


Re: [alsa-devel] [RFC PATCH 38/40] soundwire: cadence_master: make clock stop exit configurable on init

2019-07-26 Thread Guennadi Liakhovetski
On Thu, Jul 25, 2019 at 06:40:30PM -0500, Pierre-Louis Bossart wrote:
> The use of clock stop is not a requirement, the IP can e.g. be
> completely power gated and not detect any wakes while in s2idle/deep
> sleep.
> 
> Signed-off-by: Pierre-Louis Bossart 
> ---
>  drivers/soundwire/cadence_master.c | 15 ---
>  drivers/soundwire/cadence_master.h |  2 +-
>  drivers/soundwire/intel.c  |  2 +-
>  3 files changed, 10 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/soundwire/cadence_master.c 
> b/drivers/soundwire/cadence_master.c
> index 53278aa2436f..4ab6f70d7705 100644
> --- a/drivers/soundwire/cadence_master.c
> +++ b/drivers/soundwire/cadence_master.c
> @@ -1010,7 +1010,7 @@ static u32 cdns_set_default_frame_shape(int n_rows, int 
> n_cols)
>   * sdw_cdns_init() - Cadence initialization
>   * @cdns: Cadence instance
>   */
> -int sdw_cdns_init(struct sdw_cdns *cdns)
> +int sdw_cdns_init(struct sdw_cdns *cdns, bool clock_stop_exit)
>  {
>   struct sdw_bus *bus = &cdns->bus;
>   struct sdw_master_prop *prop = &bus->prop;
> @@ -1018,12 +1018,13 @@ int sdw_cdns_init(struct sdw_cdns *cdns)
>   int divider;
>   int ret;
>  
> - /* Exit clock stop */
> - ret = cdns_clear_bit(cdns, CDNS_MCP_CONTROL,
> -  CDNS_MCP_CONTROL_CLK_STOP_CLR);
> - if (ret < 0) {
> - dev_err(cdns->dev, "Couldn't exit from clock stop\n");
> - return ret;
> + if (clock_stop_exit) {
> + ret = cdns_clear_bit(cdns, CDNS_MCP_CONTROL,
> +  CDNS_MCP_CONTROL_CLK_STOP_CLR);
> + if (ret < 0) {
> + dev_err(cdns->dev, "Couldn't exit from clock stop\n");
> + return ret;
> + }
>   }
>  
>   /* Set clock divider */
> diff --git a/drivers/soundwire/cadence_master.h 
> b/drivers/soundwire/cadence_master.h
> index 1a0ba36dd78f..091b771b570d 100644
> --- a/drivers/soundwire/cadence_master.h
> +++ b/drivers/soundwire/cadence_master.h
> @@ -158,7 +158,7 @@ extern struct sdw_master_ops sdw_cdns_master_ops;
>  irqreturn_t sdw_cdns_irq(int irq, void *dev_id);
>  irqreturn_t sdw_cdns_thread(int irq, void *dev_id);
>  
> -int sdw_cdns_init(struct sdw_cdns *cdns);
> +int sdw_cdns_init(struct sdw_cdns *cdns, bool clock_stop_exit);
>  int sdw_cdns_pdi_init(struct sdw_cdns *cdns,
> struct sdw_cdns_stream_config config);
>  int sdw_cdns_exit_reset(struct sdw_cdns *cdns);
> diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c
> index 1192d5775484..db7bf2912767 100644
> --- a/drivers/soundwire/intel.c
> +++ b/drivers/soundwire/intel.c
> @@ -1043,7 +1043,7 @@ static int intel_init(struct sdw_intel *sdw)
>   intel_link_power_up(sdw);
>   intel_shim_init(sdw);
>  
> - return sdw_cdns_init(&sdw->cdns);
> + return sdw_cdns_init(&sdw->cdns, false);

This is the only caller of this function so far, so, it looks like
the second argument ATM is always "false." I assume you foresee other
uses with "true" in the future, otherwise maybe just fix it to false
in the function?

Thanks
Guennadi

>  }
>  
>  /*
> -- 
> 2.20.1
> 
> ___
> Alsa-devel mailing list
> alsa-de...@alsa-project.org
> https://mailman.alsa-project.org/mailman/listinfo/alsa-devel


Re: [alsa-devel] [RFC PATCH 36/40] soundwire: intel: disable interrupts on suspend

2019-07-26 Thread Guennadi Liakhovetski
On Thu, Jul 25, 2019 at 06:40:28PM -0500, Pierre-Louis Bossart wrote:
> Signed-off-by: Pierre-Louis Bossart 
> ---
>  drivers/soundwire/cadence_master.c | 42 +-
>  drivers/soundwire/cadence_master.h |  2 +-
>  drivers/soundwire/intel.c  |  6 +++--
>  3 files changed, 29 insertions(+), 21 deletions(-)
> 
> diff --git a/drivers/soundwire/cadence_master.c 
> b/drivers/soundwire/cadence_master.c
> index f486fe15fb46..fa7230b0f200 100644
> --- a/drivers/soundwire/cadence_master.c
> +++ b/drivers/soundwire/cadence_master.c
> @@ -814,33 +814,39 @@ EXPORT_SYMBOL(sdw_cdns_exit_reset);
>   * sdw_cdns_enable_interrupt() - Enable SDW interrupts and update config
>   * @cdns: Cadence instance
>   */
> -int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns)
> +int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns, bool state)
>  {
>   u32 mask;
>  
> - cdns_writel(cdns, CDNS_MCP_SLAVE_INTMASK0,
> - CDNS_MCP_SLAVE_INTMASK0_MASK);
> - cdns_writel(cdns, CDNS_MCP_SLAVE_INTMASK1,
> - CDNS_MCP_SLAVE_INTMASK1_MASK);
> + if (state) {
> + cdns_writel(cdns, CDNS_MCP_SLAVE_INTMASK0,
> + CDNS_MCP_SLAVE_INTMASK0_MASK);
> + cdns_writel(cdns, CDNS_MCP_SLAVE_INTMASK1,
> + CDNS_MCP_SLAVE_INTMASK1_MASK);
>  
> - /* enable detection of slave state changes */
> - mask = CDNS_MCP_INT_SLAVE_RSVD | CDNS_MCP_INT_SLAVE_ALERT |
> - CDNS_MCP_INT_SLAVE_ATTACH | CDNS_MCP_INT_SLAVE_NATTACH;
> + /* enable detection of slave state changes */
> + mask = CDNS_MCP_INT_SLAVE_RSVD | CDNS_MCP_INT_SLAVE_ALERT |
> + CDNS_MCP_INT_SLAVE_ATTACH | CDNS_MCP_INT_SLAVE_NATTACH;
>  
> - /* enable detection of bus issues */
> - mask |= CDNS_MCP_INT_CTRL_CLASH | CDNS_MCP_INT_DATA_CLASH |
> - CDNS_MCP_INT_PARITY;
> + /* enable detection of bus issues */
> + mask |= CDNS_MCP_INT_CTRL_CLASH | CDNS_MCP_INT_DATA_CLASH |
> + CDNS_MCP_INT_PARITY;
>  
> - /* no detection of port interrupts for now */
> + /* no detection of port interrupts for now */
>  
> - /* enable detection of RX fifo level */
> - mask |= CDNS_MCP_INT_RX_WL;
> + /* enable detection of RX fifo level */
> + mask |= CDNS_MCP_INT_RX_WL;
>  
> - /* now enable all of the above */
> - mask |= CDNS_MCP_INT_IRQ;
> + /* now enable all of the above */
> + mask |= CDNS_MCP_INT_IRQ;
>  
> - if (interrupt_mask) /* parameter override */
> - mask = interrupt_mask;
> + if (interrupt_mask) /* parameter override */
> + mask = interrupt_mask;
> + } else {
> + cdns_writel(cdns, CDNS_MCP_SLAVE_INTMASK0, 0);
> + cdns_writel(cdns, CDNS_MCP_SLAVE_INTMASK1, 0);
> + mask = 0;
> + }

Looks like this should be two functions? Especially since "state" is always a 
constant
when it is called. If there is still a lot of common code below, maybe make it 
a helper
function.

Thanks
Guennadi

>  
>   cdns_writel(cdns, CDNS_MCP_INTMASK, mask);
>  
> diff --git a/drivers/soundwire/cadence_master.h 
> b/drivers/soundwire/cadence_master.h
> index 2b551f9226f3..1a0ba36dd78f 100644
> --- a/drivers/soundwire/cadence_master.h
> +++ b/drivers/soundwire/cadence_master.h
> @@ -162,7 +162,7 @@ int sdw_cdns_init(struct sdw_cdns *cdns);
>  int sdw_cdns_pdi_init(struct sdw_cdns *cdns,
> struct sdw_cdns_stream_config config);
>  int sdw_cdns_exit_reset(struct sdw_cdns *cdns);
> -int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns);
> +int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns, bool state);
>  
>  void sdw_cdns_debugfs_init(struct sdw_cdns *cdns, struct dentry *root);
>  
> diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c
> index 9ebe38e4d979..1192d5775484 100644
> --- a/drivers/soundwire/intel.c
> +++ b/drivers/soundwire/intel.c
> @@ -1110,7 +1110,7 @@ static int intel_probe(struct platform_device *pdev)
>   goto err_init;
>   }
>  
> - ret = sdw_cdns_enable_interrupt(&sdw->cdns);
> + ret = sdw_cdns_enable_interrupt(&sdw->cdns, true);
>  
>   ret = sdw_cdns_exit_reset(&sdw->cdns);
>  
> @@ -1169,6 +1169,8 @@ static int intel_suspend(struct device *dev)
>   return 0;
>   }
>  
> + sdw_cdns_enable_interrupt(&sdw->cdns, false);
> +
>   ret = intel_link_power_down(sdw);
>   if (ret) {
>   dev_err(dev, "Link power down failed: %d", ret);
> @@ -1199,7 +1201,7 @@ static int intel_resume(struct device *dev)
>   return ret;
>   }
>  
> - sdw_cdns_enable_interrupt(&sdw->cdns);
> + sdw_cdns_enable_interrupt(&sdw->cdns, true);
>  
>   ret = sdw_cdns_exit_reset(&sdw->cdns);
>  
> -- 
> 2.20.1
> 
> ___
> Alsa-devel mailing list
> alsa-de...

Re: [alsa-devel] [RFC PATCH 37/40] soundwire: cadence_master: add hw_reset capability in debugfs

2019-07-26 Thread Guennadi Liakhovetski
On Thu, Jul 25, 2019 at 06:40:29PM -0500, Pierre-Louis Bossart wrote:
> This is to kick devices into reset and see what software does
> 
> Signed-off-by: Pierre-Louis Bossart 
> ---
>  drivers/soundwire/cadence_master.c | 22 ++
>  1 file changed, 22 insertions(+)
> 
> diff --git a/drivers/soundwire/cadence_master.c 
> b/drivers/soundwire/cadence_master.c
> index fa7230b0f200..53278aa2436f 100644
> --- a/drivers/soundwire/cadence_master.c
> +++ b/drivers/soundwire/cadence_master.c
> @@ -331,6 +331,25 @@ static const struct file_operations cdns_reg_fops = {
>   .llseek = default_llseek,
>  };
>  
> +static int cdns_hw_reset(void *data, u64 value)
> +{
> + struct sdw_cdns *cdns = data;
> + int ret;
> +
> + if (value != 1)
> + return 0;
> +
> + dev_info(cdns->dev, "starting link hw_reset\n");
> +
> + ret = sdw_cdns_exit_reset(cdns);
> +
> + dev_info(cdns->dev, "link hw_reset done\n");

Both really should be dev_info()? Maybe at least one of them can be dev_dbg()?

Thanks
Guennadi

> +
> + return ret;
> +}
> +
> +DEFINE_DEBUGFS_ATTRIBUTE(cdns_hw_reset_fops, NULL, cdns_hw_reset, "%llu\n");
> +
>  /**
>   * sdw_cdns_debugfs_init() - Cadence debugfs init
>   * @cdns: Cadence instance
> @@ -339,6 +358,9 @@ static const struct file_operations cdns_reg_fops = {
>  void sdw_cdns_debugfs_init(struct sdw_cdns *cdns, struct dentry *root)
>  {
>   debugfs_create_file("cdns-registers", 0400, root, cdns, &cdns_reg_fops);
> +
> + debugfs_create_file_unsafe("cdns-hw-reset", 0200, root, cdns,
> +&cdns_hw_reset_fops);
>  }
>  EXPORT_SYMBOL_GPL(sdw_cdns_debugfs_init);
>  
> -- 
> 2.20.1
> 
> ___
> Alsa-devel mailing list
> alsa-de...@alsa-project.org
> https://mailman.alsa-project.org/mailman/listinfo/alsa-devel


Re: [alsa-devel] [RFC PATCH 35/40] soundwire: intel: export helper to exit reset

2019-07-26 Thread Guennadi Liakhovetski
On Thu, Jul 25, 2019 at 06:40:27PM -0500, Pierre-Louis Bossart wrote:
> Signed-off-by: Pierre-Louis Bossart 
> ---
>  drivers/soundwire/cadence_master.c | 9 +++--
>  drivers/soundwire/cadence_master.h | 1 +
>  drivers/soundwire/intel.c  | 4 
>  3 files changed, 12 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/soundwire/cadence_master.c 
> b/drivers/soundwire/cadence_master.c
> index 4a189e487830..f486fe15fb46 100644
> --- a/drivers/soundwire/cadence_master.c
> +++ b/drivers/soundwire/cadence_master.c
> @@ -780,7 +780,11 @@ EXPORT_SYMBOL(sdw_cdns_thread);
>   * init routines
>   */
>  
> -static int do_reset(struct sdw_cdns *cdns)
> +/**
> + * sdw_cdns_exit_reset() - Program reset parameters and start bus operations
> + * @cdns: Cadence instance
> + */
> +int sdw_cdns_exit_reset(struct sdw_cdns *cdns)
>  {
>   int ret;
>  
> @@ -804,6 +808,7 @@ static int do_reset(struct sdw_cdns *cdns)
>  
>   return ret;
>  }
> +EXPORT_SYMBOL(sdw_cdns_exit_reset);
>  
>  /**
>   * sdw_cdns_enable_interrupt() - Enable SDW interrupts and update config
> @@ -839,7 +844,7 @@ int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns)
>  
>   cdns_writel(cdns, CDNS_MCP_INTMASK, mask);
>  
> - return do_reset(cdns);
> + return 0;
>  }
>  EXPORT_SYMBOL(sdw_cdns_enable_interrupt);
>  
> diff --git a/drivers/soundwire/cadence_master.h 
> b/drivers/soundwire/cadence_master.h
> index de97bc22acb7..2b551f9226f3 100644
> --- a/drivers/soundwire/cadence_master.h
> +++ b/drivers/soundwire/cadence_master.h
> @@ -161,6 +161,7 @@ irqreturn_t sdw_cdns_thread(int irq, void *dev_id);
>  int sdw_cdns_init(struct sdw_cdns *cdns);
>  int sdw_cdns_pdi_init(struct sdw_cdns *cdns,
> struct sdw_cdns_stream_config config);
> +int sdw_cdns_exit_reset(struct sdw_cdns *cdns);
>  int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns);
>  
>  void sdw_cdns_debugfs_init(struct sdw_cdns *cdns, struct dentry *root);
> diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c
> index a976480d6f36..9ebe38e4d979 100644
> --- a/drivers/soundwire/intel.c
> +++ b/drivers/soundwire/intel.c
> @@ -1112,6 +1112,8 @@ static int intel_probe(struct platform_device *pdev)
>  
>   ret = sdw_cdns_enable_interrupt(&sdw->cdns);
>  
> + ret = sdw_cdns_exit_reset(&sdw->cdns);

This isn't something, that this patch changes, but if the return value above is
ignored, maybe no need to assign it at all?

Thanks
Guennadi

> +
>   /* Register DAIs */
>   ret = intel_register_dai(sdw);
>   if (ret) {
> @@ -1199,6 +1201,8 @@ static int intel_resume(struct device *dev)
>  
>   sdw_cdns_enable_interrupt(&sdw->cdns);
>  
> + ret = sdw_cdns_exit_reset(&sdw->cdns);
> +
>   return ret;
>  }
>  
> -- 
> 2.20.1
> 
> ___
> Alsa-devel mailing list
> alsa-de...@alsa-project.org
> https://mailman.alsa-project.org/mailman/listinfo/alsa-devel


Re: [alsa-devel] [RFC PATCH 27/40] soundwire: Add Intel resource management algorithm

2019-07-26 Thread Guennadi Liakhovetski
On Thu, Jul 25, 2019 at 06:40:19PM -0500, Pierre-Louis Bossart wrote:
> This algorithm computes bus parameters like clock frequency, frame
> shape and port transport parameters based on active stream(s) running
> on the bus.
> 
> This implementation is optimal for Intel platforms. Developers can
> also implement their own .compute_params() callback for specific
> resource management algorithm.
> 
> Credits: this patch is based on an earlier internal contribution by
> Vinod Koul, Sanyog Kale, Shreyas Nc and Hardik Shah. All hard-coded
> values were removed from the initial contribution to use BIOS
> information instead.
> 
> FIXME: remove checkpatch report
> WARNING: Reusing the krealloc arg is almost always a bug
> + group->rates = krealloc(group->rates,
> 
> Signed-off-by: Pierre-Louis Bossart 
> ---
>  drivers/soundwire/Makefile  |   2 +-
>  drivers/soundwire/algo_dynamic_allocation.c | 403 
>  drivers/soundwire/bus.c |   3 +
>  drivers/soundwire/bus.h |  46 ++-
>  drivers/soundwire/stream.c  |  20 +
>  include/linux/soundwire/sdw.h   |   5 +
>  6 files changed, 476 insertions(+), 3 deletions(-)
>  create mode 100644 drivers/soundwire/algo_dynamic_allocation.c
> 
> diff --git a/drivers/soundwire/Makefile b/drivers/soundwire/Makefile
> index 88990cac48a7..f59a9d4a28fd 100644
> --- a/drivers/soundwire/Makefile
> +++ b/drivers/soundwire/Makefile
> @@ -5,7 +5,7 @@
>  
>  #Bus Objs
>  soundwire-bus-objs := bus_type.o bus.o slave.o mipi_disco.o stream.o \
> - debugfs.o
> + debugfs.o algo_dynamic_allocation.o
>  
>  obj-$(CONFIG_SOUNDWIRE_BUS) += soundwire-bus.o
>  
> diff --git a/drivers/soundwire/algo_dynamic_allocation.c 
> b/drivers/soundwire/algo_dynamic_allocation.c
> new file mode 100644
> index ..89edb39162b8
> --- /dev/null
> +++ b/drivers/soundwire/algo_dynamic_allocation.c
> @@ -0,0 +1,403 @@
> +// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
> +// Copyright(c) 2015-18 Intel Corporation.
> +
> +/*
> + * Bandwidth management algorithm based on 2^n gears
> + *
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include "bus.h"
> +
> +#define SDW_STRM_RATE_GROUPING   1
> +
> +struct sdw_group_params {
> + unsigned int rate;
> + int full_bw;
> + int payload_bw;
> + int hwidth;
> +};
> +
> +struct sdw_group {
> + unsigned int count;
> + unsigned int max_size;
> + unsigned int *rates;
> +};
> +
> +struct sdw_transport_data {
> + int hstart;
> + int hstop;
> + int block_offset;
> + int sub_block_offset;
> +};
> +
> +static void sdw_compute_slave_ports(struct sdw_master_runtime *m_rt,
> + struct sdw_transport_data *t_data)
> +{
> + struct sdw_slave_runtime *s_rt = NULL;

Superfluous initialisation.

> + struct sdw_port_runtime *p_rt;
> + int port_bo, sample_int;
> + unsigned int rate, bps, ch = 0;

ditto for ch

> +
> + port_bo = t_data->block_offset;
> +
> + list_for_each_entry(s_rt, &m_rt->slave_rt_list, m_rt_node) {
> + rate = m_rt->stream->params.rate;
> + bps = m_rt->stream->params.bps;
> + sample_int = (m_rt->bus->params.curr_dr_freq / rate);
> +
> + list_for_each_entry(p_rt, &s_rt->port_list, port_node) {
> + ch = sdw_ch_mask_to_ch(p_rt->ch_mask);
> +
> + sdw_fill_xport_params(&p_rt->transport_params,
> +   p_rt->num, true,
> +   SDW_BLK_GRP_CNT_1,
> +   sample_int, port_bo, port_bo >> 8,
> +   t_data->hstart,
> +   t_data->hstop,

I think the above two lines could fit in one

> +   (SDW_BLK_GRP_CNT_1 * ch), 0x0);

superfluous parentheses

> +
> + sdw_fill_port_params(&p_rt->port_params,
> +  p_rt->num, bps,
> +  SDW_PORT_FLOW_MODE_ISOCH,
> +  SDW_PORT_DATA_MODE_NORMAL);
> +
> + port_bo += bps * ch;
> + }
> + }
> +}
> +
> +static void sdw_compute_master_ports(struct sdw_master_runtime *m_rt,
> +  struct sdw_group_params *params,
> +  int port_bo, int hstop)
> +{
> + struct sdw_transport_data t_data = {0};
> + struct sdw_port_runtime *p_rt;
> + struct sdw_bus *bus = m_rt->bus;
> + int sample_int, hstart = 0;

superfluous initialisation

> + unsigned int rate, bps, ch, no_ch;
> +
> + rate = m_rt->stream->params.rate;
> + bps = m_rt->stream->params.bps;
> + ch = m_rt->ch_count;
> + sample_int = (bus->params.c

Re: [alsa-devel] [RFC PATCH 23/40] soundwire: stream: fix disable sequence

2019-07-26 Thread Guennadi Liakhovetski
Unrelated to this specific patch, but I looked at _sdw_disable_stream()
and I see this there (again, maybe my version is outdated already):

struct sdw_master_runtime *m_rt = NULL;
struct sdw_bus *bus = NULL;

where both those initialisations are redundant. Moreover:

On Thu, Jul 25, 2019 at 06:40:15PM -0500, Pierre-Louis Bossart wrote:
> When we disable the stream and then call hw_free, two bank switches
> will be handled and as a result we re-enable the stream on hw_free.
> 
> Make sure the stream is disabled on both banks.
> 
> TODO: we need to completely revisit all this and make sure we have a
> mirroring mechanism between current and alternate banks.
> 
> Signed-off-by: Pierre-Louis Bossart 
> ---
>  drivers/soundwire/stream.c | 19 ++-
>  1 file changed, 18 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/soundwire/stream.c b/drivers/soundwire/stream.c
> index 53f5e790fcd7..75b9ad1fb1a6 100644
> --- a/drivers/soundwire/stream.c
> +++ b/drivers/soundwire/stream.c
> @@ -1637,7 +1637,24 @@ static int _sdw_disable_stream(struct 
> sdw_stream_runtime *stream)
>   }
>   }
>  
> - return do_bank_switch(stream);
> + ret = do_bank_switch(stream);
> + if (ret < 0) {
> + dev_err(bus->dev, "Bank switch failed: %d\n", ret);
> + return ret;
> + }
> +
> + /* make sure alternate bank (previous current) is also disabled */
> + list_for_each_entry(m_rt, &stream->master_list, stream_node) {
> + bus = m_rt->bus;

"bus" is only used below, so at least take that line under "if (ret < 0)"
or even just do "dev_err(m_rt->bus->dev,...)" everywhere in this function
and remove the variable altogether...

Thanks
Guennadi

> + /* Disable port(s) */
> + ret = sdw_enable_disable_ports(m_rt, false);
> + if (ret < 0) {
> + dev_err(bus->dev, "Disable port(s) failed: %d\n", ret);
> + return ret;
> + }
> + }
> +
> + return 0;
>  }
>  
>  /**
> -- 
> 2.20.1
> 
> ___
> Alsa-devel mailing list
> alsa-de...@alsa-project.org
> https://mailman.alsa-project.org/mailman/listinfo/alsa-devel


Re: [alsa-devel] [RFC PATCH 21/40] soundwire: export helpers to find row and column values

2019-07-26 Thread Guennadi Liakhovetski
On Thu, Jul 25, 2019 at 06:40:13PM -0500, Pierre-Louis Bossart wrote:
> Add a prefix for common tables and export 2 helpers to set the frame
> shapes based on row/col values.
> 
> Signed-off-by: Pierre-Louis Bossart 
> ---
>  drivers/soundwire/bus.h|  7 +--
>  drivers/soundwire/stream.c | 14 --
>  2 files changed, 13 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/soundwire/bus.h b/drivers/soundwire/bus.h
> index 06ac4adb0074..c57c9c23f6ca 100644
> --- a/drivers/soundwire/bus.h
> +++ b/drivers/soundwire/bus.h
> @@ -73,8 +73,11 @@ struct sdw_msg {
>  
>  #define SDW_DOUBLE_RATE_FACTOR   2
>  
> -extern int rows[SDW_FRAME_ROWS];
> -extern int cols[SDW_FRAME_COLS];
> +extern int sdw_rows[SDW_FRAME_ROWS];
> +extern int sdw_cols[SDW_FRAME_COLS];

So these arrays actually have to be exported? In the current (5.2) sources they
seem to only be used in stream.c, maybe make them static there?

> +
> +int sdw_find_row_index(int row);
> +int sdw_find_col_index(int col);
>  
>  /**
>   * sdw_port_runtime: Runtime port parameters for Master or Slave
> diff --git a/drivers/soundwire/stream.c b/drivers/soundwire/stream.c
> index a0476755a459..53f5e790fcd7 100644
> --- a/drivers/soundwire/stream.c
> +++ b/drivers/soundwire/stream.c
> @@ -21,37 +21,39 @@
>   * The rows are arranged as per the array index value programmed
>   * in register. The index 15 has dummy value 0 in order to fill hole.
>   */
> -int rows[SDW_FRAME_ROWS] = {48, 50, 60, 64, 75, 80, 125, 147,
> +int sdw_rows[SDW_FRAME_ROWS] = {48, 50, 60, 64, 75, 80, 125, 147,
>   96, 100, 120, 128, 150, 160, 250, 0,
>   192, 200, 240, 256, 72, 144, 90, 180};
>  
> -int cols[SDW_FRAME_COLS] = {2, 4, 6, 8, 10, 12, 14, 16};
> +int sdw_cols[SDW_FRAME_COLS] = {2, 4, 6, 8, 10, 12, 14, 16};
>  
> -static int sdw_find_col_index(int col)
> +int sdw_find_col_index(int col)
>  {
>   int i;
>  
>   for (i = 0; i < SDW_FRAME_COLS; i++) {
> - if (cols[i] == col)
> + if (sdw_cols[i] == col)
>   return i;
>   }
>  
>   pr_warn("Requested column not found, selecting lowest column no: 2\n");
>   return 0;
>  }
> +EXPORT_SYMBOL(sdw_find_col_index);
>  
> -static int sdw_find_row_index(int row)
> +int sdw_find_row_index(int row)
>  {
>   int i;
>  
>   for (i = 0; i < SDW_FRAME_ROWS; i++) {
> - if (rows[i] == row)
> + if (sdw_rows[i] == row)
>   return i;
>   }
>  
>   pr_warn("Requested row not found, selecting lowest row no: 48\n");
>   return 0;
>  }
> +EXPORT_SYMBOL(sdw_find_row_index);
>  
>  static int _sdw_program_slave_port_params(struct sdw_bus *bus,
> struct sdw_slave *slave,
> -- 
> 2.20.1
> 
> ___
> Alsa-devel mailing list
> alsa-de...@alsa-project.org
> https://mailman.alsa-project.org/mailman/listinfo/alsa-devel


Re: [alsa-devel] [RFC PATCH 17/40] soundwire: bus: use runtime_pm_get_sync/pm when enabled

2019-07-26 Thread Guennadi Liakhovetski
On Fri, Jul 26, 2019 at 08:33:35AM +, Jan Kotas wrote:
> 
> 
> > On 26 Jul 2019, at 10:22, Guennadi Liakhovetski 
> >  wrote:
> > 
> > EXTERNAL MAIL
> > 
> > 
> > Hi Jan,
> > 
> > On Fri, Jul 26, 2019 at 07:47:04AM +, Jan Kotas wrote:
> >> Hello,
> >> 
> >> I while back I proposed a patch for this, but it went nowhere.
> >> 
> >> https://urldefense.proofpoint.com/v2/url?u=https-3A__patchwork.kernel.org_patch_10887405_&d=DwIBAg&c=aUq983L2pue2FqKFoP6PGHMJQyoJ7kl3s3GZ-_haXqY&r=g7GAQENVXx_RQdyXHInPMg&m=i_0S359hFIVqNgv3fR5_MNzDOHP99trdXszZ-FMiQEE&s=ddktFZYlePh-bC7kXeoKWt4QomupzHATK4FLY4oSWKA&e=
> >>  
> >> Maybe something similar can be implemented?
> > 
> > Yes, I was thinking about checkint -EACCESS too, but then I noticed this 
> > code
> > in rpm_resume():
> > 
> > else if (dev->power.disable_depth == 1 && dev->power.is_suspended
> > && dev->power.runtime_status == RPM_ACTIVE)
> > retval = 1;
> > 
> > i.e. if RT-PM is disabled on the device (but only exactly once?..) and it's
> > active and the device is suspended for a system suspend, the function will
> > return 1. I don't understand the logic of this code, but it seems to me it
> > could break the -EACCESS check?
> > 
> 
> Hi,
> 
> In such case ret < 0 will not be true, which I think is fine,
> if I’m understanding you correctly.

Yes, if we just have to distinguish a single case "RT-PM is enabled and it 
failed."
Which is indeed the case here, it seems. However if we want to check whether 
RT-PM
is disabled after a call to, say, pm_runtime_get_sync(), then just checking
-EACCESS isn't always enough - there can be cases when RT-PM is disabled and the
return code is 1. But yes, just for checking for failures, like here, it should 
be
fine.

Thanks
Guennadi

> >> Jan
> >> 
> >>> On 26 Jul 2019, at 09:39, Guennadi Liakhovetski 
> >>>  wrote:
> >>> 
> >>> EXTERNAL MAIL
> >>> 
> >>> 
> >>> Hi Pierre,
> >>> 
> >>> I might be wrong but this doesn't seem right to me. (Supposedly) all RT-PM
> >>> functions check for "enabled" internally. The only thing that can happen 
> >>> is
> >>> that if RT-PM isn't enabled some of those functions will return an error.
> >>> So, in those cases where the return value of RT-PM functions isn't 
> >>> checked,
> >>> I don't think you need to do anything. Where it is checked maybe do
> >>> 
> >>> + if (ret < 0 && pm_runtime_enabled(slave->bus->dev))
> >>> 
> >>> Thanks
> >>> Guennadi
> >>> 
> >>> On Thu, Jul 25, 2019 at 06:40:09PM -0500, Pierre-Louis Bossart wrote:
> >>>> Not all platforms support runtime_pm for now, let's use runtime_pm
> >>>> only when enabled.
> >>>> 
> >>>> Suggested-by: Srinivas Kandagatla 
> >>>> Signed-off-by: Pierre-Louis Bossart 
> >>>> 
> >>>> ---
> >>>> drivers/soundwire/bus.c | 25 -
> >>>> 1 file changed, 16 insertions(+), 9 deletions(-)
> >>>> 
> >>>> diff --git a/drivers/soundwire/bus.c b/drivers/soundwire/bus.c
> >>>> index 5ad4109dc72f..0a45dc5713df 100644
> >>>> --- a/drivers/soundwire/bus.c
> >>>> +++ b/drivers/soundwire/bus.c
> >>>> @@ -332,12 +332,16 @@ int sdw_nread(struct sdw_slave *slave, u32 addr, 
> >>>> size_t count, u8 *val)
> >>>>  if (ret < 0)
> >>>>  return ret;
> >>>> 
> >>>> -ret = pm_runtime_get_sync(slave->bus->dev);
> >>>> -if (ret < 0)
> >>>> -return ret;
> >>>> +if (pm_runtime_enabled(slave->bus->dev)) {
> >>>> +ret = pm_runtime_get_sync(slave->bus->dev);
> >>>> +if (ret < 0)
> >>>> +return ret;
> >>>> +}
> >>>> 
> >>>>  ret = sdw_transfer(slave->bus, &msg);
> >>>> -pm_runtime_put(slave->bus->dev);
> >>>> +
> >>>> +if (pm_runtime_enabled(slave->bus->dev))
> >>>> +pm_runtime_put(slave->bus->dev);
> >>>> 
>

Re: [alsa-devel] [RFC PATCH 17/40] soundwire: bus: use runtime_pm_get_sync/pm when enabled

2019-07-26 Thread Guennadi Liakhovetski
Hi Jan,

On Fri, Jul 26, 2019 at 07:47:04AM +, Jan Kotas wrote:
> Hello,
> 
> I while back I proposed a patch for this, but it went nowhere.
> 
> https://patchwork.kernel.org/patch/10887405/
> Maybe something similar can be implemented?

Yes, I was thinking about checkint -EACCESS too, but then I noticed this code
in rpm_resume():

else if (dev->power.disable_depth == 1 && dev->power.is_suspended
&& dev->power.runtime_status == RPM_ACTIVE)
retval = 1;

i.e. if RT-PM is disabled on the device (but only exactly once?..) and it's
active and the device is suspended for a system suspend, the function will
return 1. I don't understand the logic of this code, but it seems to me it
could break the -EACCESS check?

Thanks
Guennadi

> Jan
> 
> > On 26 Jul 2019, at 09:39, Guennadi Liakhovetski 
> >  wrote:
> > 
> > EXTERNAL MAIL
> > 
> > 
> > Hi Pierre,
> > 
> > I might be wrong but this doesn't seem right to me. (Supposedly) all RT-PM
> > functions check for "enabled" internally. The only thing that can happen is
> > that if RT-PM isn't enabled some of those functions will return an error.
> > So, in those cases where the return value of RT-PM functions isn't checked,
> > I don't think you need to do anything. Where it is checked maybe do
> > 
> > +   if (ret < 0 && pm_runtime_enabled(slave->bus->dev))
> > 
> > Thanks
> > Guennadi
> > 
> > On Thu, Jul 25, 2019 at 06:40:09PM -0500, Pierre-Louis Bossart wrote:
> >> Not all platforms support runtime_pm for now, let's use runtime_pm
> >> only when enabled.
> >> 
> >> Suggested-by: Srinivas Kandagatla 
> >> Signed-off-by: Pierre-Louis Bossart 
> >> ---
> >> drivers/soundwire/bus.c | 25 -
> >> 1 file changed, 16 insertions(+), 9 deletions(-)
> >> 
> >> diff --git a/drivers/soundwire/bus.c b/drivers/soundwire/bus.c
> >> index 5ad4109dc72f..0a45dc5713df 100644
> >> --- a/drivers/soundwire/bus.c
> >> +++ b/drivers/soundwire/bus.c
> >> @@ -332,12 +332,16 @@ int sdw_nread(struct sdw_slave *slave, u32 addr, 
> >> size_t count, u8 *val)
> >>if (ret < 0)
> >>return ret;
> >> 
> >> -  ret = pm_runtime_get_sync(slave->bus->dev);
> >> -  if (ret < 0)
> >> -  return ret;
> >> +  if (pm_runtime_enabled(slave->bus->dev)) {
> >> +  ret = pm_runtime_get_sync(slave->bus->dev);
> >> +  if (ret < 0)
> >> +  return ret;
> >> +  }
> >> 
> >>ret = sdw_transfer(slave->bus, &msg);
> >> -  pm_runtime_put(slave->bus->dev);
> >> +
> >> +  if (pm_runtime_enabled(slave->bus->dev))
> >> +  pm_runtime_put(slave->bus->dev);
> >> 
> >>return ret;
> >> }
> >> @@ -359,13 +363,16 @@ int sdw_nwrite(struct sdw_slave *slave, u32 addr, 
> >> size_t count, u8 *val)
> >>   slave->dev_num, SDW_MSG_FLAG_WRITE, val);
> >>if (ret < 0)
> >>return ret;
> >> -
> >> -  ret = pm_runtime_get_sync(slave->bus->dev);
> >> -  if (ret < 0)
> >> -  return ret;
> >> +  if (pm_runtime_enabled(slave->bus->dev)) {
> >> +  ret = pm_runtime_get_sync(slave->bus->dev);
> >> +  if (ret < 0)
> >> +  return ret;
> >> +  }
> >> 
> >>ret = sdw_transfer(slave->bus, &msg);
> >> -  pm_runtime_put(slave->bus->dev);
> >> +
> >> +  if (pm_runtime_enabled(slave->bus->dev))
> >> +  pm_runtime_put(slave->bus->dev);
> >> 
> >>return ret;
> >> }
> >> -- 
> >> 2.20.1
> >> 
> >> ___
> >> Alsa-devel mailing list
> >> alsa-de...@alsa-project.org
> >> https://urldefense.proofpoint.com/v2/url?u=https-3A__mailman.alsa-2Dproject.org_mailman_listinfo_alsa-2Ddevel&d=DwIBAg&c=aUq983L2pue2FqKFoP6PGHMJQyoJ7kl3s3GZ-_haXqY&r=g7GAQENVXx_RQdyXHInPMg&m=vETGQLSPeGb7K_ZsXv4Tl3VFfdXzyummTDga97ozJcg&s=LiW4SToh5U0zhnkox54oRhJ1u3vFNbBB9nmzRDuCDjI&e=
> 
> ___
> Alsa-devel mailing list
> alsa-de...@alsa-project.org
> https://mailman.alsa-project.org/mailman/listinfo/alsa-devel


Re: [alsa-devel] [RFC PATCH 17/40] soundwire: bus: use runtime_pm_get_sync/pm when enabled

2019-07-26 Thread Guennadi Liakhovetski
Hi Pierre,

I might be wrong but this doesn't seem right to me. (Supposedly) all RT-PM
functions check for "enabled" internally. The only thing that can happen is
that if RT-PM isn't enabled some of those functions will return an error.
So, in those cases where the return value of RT-PM functions isn't checked,
I don't think you need to do anything. Where it is checked maybe do

+   if (ret < 0 && pm_runtime_enabled(slave->bus->dev))

Thanks
Guennadi

On Thu, Jul 25, 2019 at 06:40:09PM -0500, Pierre-Louis Bossart wrote:
> Not all platforms support runtime_pm for now, let's use runtime_pm
> only when enabled.
> 
> Suggested-by: Srinivas Kandagatla 
> Signed-off-by: Pierre-Louis Bossart 
> ---
>  drivers/soundwire/bus.c | 25 -
>  1 file changed, 16 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/soundwire/bus.c b/drivers/soundwire/bus.c
> index 5ad4109dc72f..0a45dc5713df 100644
> --- a/drivers/soundwire/bus.c
> +++ b/drivers/soundwire/bus.c
> @@ -332,12 +332,16 @@ int sdw_nread(struct sdw_slave *slave, u32 addr, size_t 
> count, u8 *val)
>   if (ret < 0)
>   return ret;
>  
> - ret = pm_runtime_get_sync(slave->bus->dev);
> - if (ret < 0)
> - return ret;
> + if (pm_runtime_enabled(slave->bus->dev)) {
> + ret = pm_runtime_get_sync(slave->bus->dev);
> + if (ret < 0)
> + return ret;
> + }
>  
>   ret = sdw_transfer(slave->bus, &msg);
> - pm_runtime_put(slave->bus->dev);
> +
> + if (pm_runtime_enabled(slave->bus->dev))
> + pm_runtime_put(slave->bus->dev);
>  
>   return ret;
>  }
> @@ -359,13 +363,16 @@ int sdw_nwrite(struct sdw_slave *slave, u32 addr, 
> size_t count, u8 *val)
>  slave->dev_num, SDW_MSG_FLAG_WRITE, val);
>   if (ret < 0)
>   return ret;
> -
> - ret = pm_runtime_get_sync(slave->bus->dev);
> - if (ret < 0)
> - return ret;
> + if (pm_runtime_enabled(slave->bus->dev)) {
> + ret = pm_runtime_get_sync(slave->bus->dev);
> + if (ret < 0)
> + return ret;
> + }
>  
>   ret = sdw_transfer(slave->bus, &msg);
> - pm_runtime_put(slave->bus->dev);
> +
> + if (pm_runtime_enabled(slave->bus->dev))
> + pm_runtime_put(slave->bus->dev);
>  
>   return ret;
>  }
> -- 
> 2.20.1
> 
> ___
> Alsa-devel mailing list
> alsa-de...@alsa-project.org
> https://mailman.alsa-project.org/mailman/listinfo/alsa-devel


Re: [alsa-devel] [RFC PATCH 16/40] soundwire: cadence_master: improve startup sequence with link hw_reset

2019-07-26 Thread Guennadi Liakhovetski
On Thu, Jul 25, 2019 at 06:40:08PM -0500, Pierre-Louis Bossart wrote:
> Enable interrupts first, then engage hardware bus reset with maximum
> duration to make sure the Slave(s) correctly detect the reset pattern
> and to ensure electrical conflicts can be resolved.
> 
> Without these changes the initialization is randomly corrupted by bus
> clashes, parity errors and Slave attachment does not generate any
> interrupt, despite the status showing them being attached.
> 
> Signed-off-by: Pierre-Louis Bossart 
> ---
>  drivers/soundwire/cadence_master.c | 35 +-
>  1 file changed, 30 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/soundwire/cadence_master.c 
> b/drivers/soundwire/cadence_master.c
> index 25d5c7267c15..442f78c00f09 100644
> --- a/drivers/soundwire/cadence_master.c
> +++ b/drivers/soundwire/cadence_master.c
> @@ -778,6 +778,31 @@ EXPORT_SYMBOL(sdw_cdns_thread);
>   * init routines
>   */
>  
> +static int do_reset(struct sdw_cdns *cdns)
> +{
> + int ret;
> +
> + /* program maximum length reset to be safe */
> + cdns_updatel(cdns, CDNS_MCP_CONTROL,
> +  CDNS_MCP_CONTROL_RST_DELAY,
> +  CDNS_MCP_CONTROL_RST_DELAY);
> +
> + /* use hardware generated reset */
> + cdns_updatel(cdns, CDNS_MCP_CONTROL,
> +  CDNS_MCP_CONTROL_HW_RST,
> +  CDNS_MCP_CONTROL_HW_RST);
> +
> + /* enable bus operations with clock and data */
> + cdns_updatel(cdns, CDNS_MCP_CONFIG,
> +  CDNS_MCP_CONFIG_OP,
> +  CDNS_MCP_CONFIG_OP_NORMAL);
> +
> + /* commit changes */
> + ret = cdns_update_config(cdns);
> +
> + return ret;

+   return cdns_update_config(cdns);

and remove the "ret" variable.

Thanks
Guennadi

> +}
> +
>  /**
>   * sdw_cdns_enable_interrupt() - Enable SDW interrupts and update config
>   * @cdns: Cadence instance
> @@ -809,7 +834,7 @@ int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns)
>  
>   cdns_writel(cdns, CDNS_MCP_INTMASK, mask);
>  
> - return 0;
> + return do_reset(cdns);
>  }
>  EXPORT_SYMBOL(sdw_cdns_enable_interrupt);
>  
> @@ -958,6 +983,10 @@ int sdw_cdns_init(struct sdw_cdns *cdns)
>   cdns_writel(cdns, CDNS_MCP_SSP_CTRL0, CDNS_DEFAULT_SSP_INTERVAL);
>   cdns_writel(cdns, CDNS_MCP_SSP_CTRL1, CDNS_DEFAULT_SSP_INTERVAL);
>  
> + /* flush command FIFOs */
> + cdns_updatel(cdns, CDNS_MCP_CONTROL, CDNS_MCP_CONTROL_CMD_RST,
> +  CDNS_MCP_CONTROL_CMD_RST);
> +
>   /* Set cmd accept mode */
>   cdns_updatel(cdns, CDNS_MCP_CONTROL, CDNS_MCP_CONTROL_CMD_ACCEPT,
>CDNS_MCP_CONTROL_CMD_ACCEPT);
> @@ -980,10 +1009,6 @@ int sdw_cdns_init(struct sdw_cdns *cdns)
>   /* Set cmd mode for Tx and Rx cmds */
>   val &= ~CDNS_MCP_CONFIG_CMD;
>  
> - /* Set operation to normal */
> - val &= ~CDNS_MCP_CONFIG_OP;
> - val |= CDNS_MCP_CONFIG_OP_NORMAL;
> -
>   cdns_writel(cdns, CDNS_MCP_CONFIG, val);
>  
>   /* commit changes */
> -- 
> 2.20.1
> 
> ___
> Alsa-devel mailing list
> alsa-de...@alsa-project.org
> https://mailman.alsa-project.org/mailman/listinfo/alsa-devel


Re: [alsa-devel] [RFC PATCH 15/40] soundwire: cadence_master: handle multiple status reports per Slave

2019-07-26 Thread Guennadi Liakhovetski
On Thu, Jul 25, 2019 at 06:40:07PM -0500, Pierre-Louis Bossart wrote:
> When a Slave reports multiple status in the sticky bits, find the
> latest configuration from the mirror of the PING frame status and
> update the status directly.
> 
> Signed-off-by: Pierre-Louis Bossart 
> ---
>  drivers/soundwire/cadence_master.c | 34 --
>  1 file changed, 28 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/soundwire/cadence_master.c 
> b/drivers/soundwire/cadence_master.c
> index 889fa2cd49ae..25d5c7267c15 100644
> --- a/drivers/soundwire/cadence_master.c
> +++ b/drivers/soundwire/cadence_master.c
> @@ -643,13 +643,35 @@ static int cdns_update_slave_status(struct sdw_cdns 
> *cdns,
>  
>   /* first check if Slave reported multiple status */
>   if (set_status > 1) {
> + u32 val;
> +
>   dev_warn_ratelimited(cdns->dev,
> -  "Slave reported multiple Status: 
> %d\n",
> -  mask);
> - /*
> -  * TODO: we need to reread the status here by
> -  * issuing a PING cmd
> -  */
> +  "Slave %d reported multiple 
> Status: %d\n",
> +  i, mask);
> +
> + /* re-check latest status extracted from PING commands 
> */
> + val = cdns_readl(cdns, CDNS_MCP_SLAVE_STAT);
> + val >>= (i * 2);

Superfluous parentheses.

> +
> + switch (val & 0x3) {
> + case 0:
> + status[i] = SDW_SLAVE_UNATTACHED;
> + break;
> + case 1:
> + status[i] = SDW_SLAVE_ATTACHED;
> + break;
> + case 2:
> + status[i] = SDW_SLAVE_ALERT;
> + break;
> + default:

There aren't many values left for the "default" case :-) But I'm not sure 
whether
any of

+   case 3:

or

+   case 3:
+   default:

would improve readability.

Thanks
Guennadi

> + status[i] = SDW_SLAVE_RESERVED;
> + break;
> + }
> +
> + dev_warn_ratelimited(cdns->dev,
> +  "Slave %d status updated to %d\n",
> +  i, status[i]);
> +
>   }
>   }
>  
> -- 
> 2.20.1
> 
> ___
> Alsa-devel mailing list
> alsa-de...@alsa-project.org
> https://mailman.alsa-project.org/mailman/listinfo/alsa-devel


Re: [alsa-devel] [RFC PATCH 09/40] soundwire: cadence_master: fix usage of CONFIG_UPDATE

2019-07-25 Thread Guennadi Liakhovetski
On Thu, Jul 25, 2019 at 06:40:01PM -0500, Pierre-Louis Bossart wrote:
> Per the hardware documentation, all changes to MCP_CONFIG,
> MCP_CONTROL, MCP_CMDCTRL and MCP_PHYCTRL need to be validated with a
> self-clearing write to MCP_CONFIG_UPDATE.
> 
> For some reason, the existing code only does this write to
> CONFIG_UPDATE when enabling interrupts. Add a helper and do the update
> when the CONFIG is changed.
> 
> Signed-off-by: Pierre-Louis Bossart 
> ---
>  drivers/soundwire/cadence_master.c | 29 +
>  1 file changed, 21 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/soundwire/cadence_master.c 
> b/drivers/soundwire/cadence_master.c
> index 9f611a1fff0a..eb46cf651d62 100644
> --- a/drivers/soundwire/cadence_master.c
> +++ b/drivers/soundwire/cadence_master.c
> @@ -224,6 +224,22 @@ static int cdns_clear_bit(struct sdw_cdns *cdns, int 
> offset, u32 value)
>   return -EAGAIN;
>  }
>  
> +/*
> + * all changes to the MCP_CONFIG, MCP_CONTROL, MCP_CMDCTRL and MCP_PHYCTRL
> + * need to be confirmed with a write to MCP_CONFIG_UPDATE
> + */
> +static int cdns_update_config(struct sdw_cdns *cdns)
> +{
> + int ret;
> +
> + ret = cdns_clear_bit(cdns, CDNS_MCP_CONFIG_UPDATE,
> +  CDNS_MCP_CONFIG_UPDATE_BIT);
> + if (ret < 0)
> + dev_err(cdns->dev, "Config update timedout\n");
> +
> + return ret;
> +}
> +
>  /*
>   * debugfs
>   */
> @@ -758,15 +774,9 @@ static int _cdns_enable_interrupt(struct sdw_cdns *cdns)
>   */
>  int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns)
>  {
> - int ret;
> -
>   _cdns_enable_interrupt(cdns);
> - ret = cdns_clear_bit(cdns, CDNS_MCP_CONFIG_UPDATE,
> -  CDNS_MCP_CONFIG_UPDATE_BIT);
> - if (ret < 0)
> - dev_err(cdns->dev, "Config update timedout\n");
>  
> - return ret;
> + return 0;
>  }
>  EXPORT_SYMBOL(sdw_cdns_enable_interrupt);
>  
> @@ -943,7 +953,10 @@ int sdw_cdns_init(struct sdw_cdns *cdns)
>  
>   cdns_writel(cdns, CDNS_MCP_CONFIG, val);
>  
> - return 0;
> + /* commit changes */
> + ret = cdns_update_config(cdns);
> +
> + return ret;

+   return cdns_update_config(cdns);

Thanks
Guennadi

>  }
>  EXPORT_SYMBOL(sdw_cdns_init);
>  
> -- 
> 2.20.1
> 
> ___
> Alsa-devel mailing list
> alsa-de...@alsa-project.org
> https://mailman.alsa-project.org/mailman/listinfo/alsa-devel


Re: [alsa-devel] [RFC PATCH 01/40] soundwire: add debugfs support

2019-07-25 Thread Guennadi Liakhovetski
Hi Pierre,

A couple of nitpicks:

On Thu, Jul 25, 2019 at 06:39:53PM -0500, Pierre-Louis Bossart wrote:
> Add base debugfs mechanism for SoundWire bus by creating soundwire
> root and master-N and slave-x hierarchy.
> 
> Also add SDW Slave SCP, DP0 and DP-N register debug file.
> 
> Registers not implemented will print as "XX"
> 
> Credits: this patch is based on an earlier internal contribution by
> Vinod Koul, Sanyog Kale, Shreyas Nc and Hardik Shah. The main change
> is the use of scnprintf to avoid known issues with snprintf.
> 
> Signed-off-by: Pierre-Louis Bossart 
> ---
>  drivers/soundwire/Makefile|   4 +-
>  drivers/soundwire/bus.c   |   6 ++
>  drivers/soundwire/bus.h   |  24 ++
>  drivers/soundwire/bus_type.c  |   3 +
>  drivers/soundwire/debugfs.c   | 156 ++
>  drivers/soundwire/slave.c |   1 +
>  include/linux/soundwire/sdw.h |   4 +
>  7 files changed, 197 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/soundwire/debugfs.c

[snip]

> diff --git a/drivers/soundwire/bus.h b/drivers/soundwire/bus.h
> index 3048ca153f22..06ac4adb0074 100644
> --- a/drivers/soundwire/bus.h
> +++ b/drivers/soundwire/bus.h
> @@ -18,6 +18,30 @@ static inline int sdw_acpi_find_slaves(struct sdw_bus *bus)
>  void sdw_extract_slave_id(struct sdw_bus *bus,
> u64 addr, struct sdw_slave_id *id);
>  
> +#ifdef CONFIG_DEBUG_FS
> +struct dentry *sdw_bus_debugfs_init(struct sdw_bus *bus);
> +void sdw_bus_debugfs_exit(struct dentry *d);
> +struct dentry *sdw_slave_debugfs_init(struct sdw_slave *slave);
> +void sdw_slave_debugfs_exit(struct dentry *d);
> +void sdw_debugfs_init(void);
> +void sdw_debugfs_exit(void);
> +#else
> +struct dentry *sdw_bus_debugfs_init(struct sdw_bus *bus)
> +{ return NULL; }

static?

> +
> +void sdw_bus_debugfs_exit(struct dentry *d) {}
> +
> +struct dentry *sdw_slave_debugfs_init(struct sdw_slave *slave)
> +{ return NULL; }
> +
> +void sdw_slave_debugfs_exit(struct dentry *d) {}
> +
> +void sdw_debugfs_init(void) {}
> +
> +void sdw_debugfs_exit(void) {}

Same for all the above. You could also declare them inline, but I really hope
the compiler will be smart enough to do that itself.

> +
> +#endif
> +
>  enum {
>   SDW_MSG_FLAG_READ = 0,
>   SDW_MSG_FLAG_WRITE,
> diff --git a/drivers/soundwire/bus_type.c b/drivers/soundwire/bus_type.c
> index 2655602f0cfb..4a465f55039f 100644
> --- a/drivers/soundwire/bus_type.c
> +++ b/drivers/soundwire/bus_type.c
> @@ -6,6 +6,7 @@
>  #include 
>  #include 
>  #include 
> +#include "bus.h"
>  
>  /**
>   * sdw_get_device_id - find the matching SoundWire device id
> @@ -177,11 +178,13 @@ EXPORT_SYMBOL_GPL(sdw_unregister_driver);
>  
>  static int __init sdw_bus_init(void)
>  {
> + sdw_debugfs_init();
>   return bus_register(&sdw_bus_type);
>  }
>  
>  static void __exit sdw_bus_exit(void)
>  {
> + sdw_debugfs_exit();
>   bus_unregister(&sdw_bus_type);
>  }
>  
> diff --git a/drivers/soundwire/debugfs.c b/drivers/soundwire/debugfs.c
> new file mode 100644
> index ..8d86e100516e
> --- /dev/null
> +++ b/drivers/soundwire/debugfs.c
> @@ -0,0 +1,156 @@
> +// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
> +// Copyright(c) 2017-19 Intel Corporation.
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include "bus.h"
> +
> +#ifdef CONFIG_DEBUG_FS
> +struct dentry *sdw_debugfs_root;
> +#endif
> +
> +struct dentry *sdw_bus_debugfs_init(struct sdw_bus *bus)
> +{
> + struct dentry *d;

I would remove the above

> + char name[16];
> +
> + if (!sdw_debugfs_root)
> + return NULL;
> +
> + /* create the debugfs master-N */
> + snprintf(name, sizeof(name), "master-%d", bus->link_id);
> + d = debugfs_create_dir(name, sdw_debugfs_root);
> +
> + return d;

And just do

+   return debugfs_create_dir(name, sdw_debugfs_root);

> +}
> +
> +void sdw_bus_debugfs_exit(struct dentry *d)
> +{
> + debugfs_remove_recursive(d);
> +}
> +
> +#define RD_BUF (3 * PAGE_SIZE)
> +
> +static ssize_t sdw_sprintf(struct sdw_slave *slave,
> +char *buf, size_t pos, unsigned int reg)
> +{
> + int value;
> +
> + value = sdw_read(slave, reg);

I personally would join the two lines above, but that's just a personal
preference.

> +
> + if (value < 0)
> + return scnprintf(buf + pos, RD_BUF - pos, "%3x\tXX\n", reg);
> + else

I think it's advised to not use an else in such cases.

Thanks
Guennadi

> + return scnprintf(buf + pos, RD_BUF - pos,
> + "%3x\t%2x\n", reg, value);
> +}
> +
> +static ssize_t sdw_slave_reg_read(struct file *file, char __user *user_buf,
> +   size_t count, loff_t *ppos)
> +{
> + struct sdw_slave *slave = file->private_data;
> + unsigned int reg;
> + char *buf;
> + ssize_t ret;
> + int i, j;
> +
> + buf = kzalloc(RD_BUF, GFP_KERNEL);
> + if 

[PATCH resend] regulator: fix device unlinking

2019-02-07 Thread Guennadi Liakhovetski
From: Guennadi Liakhovetski 

Device links are refcounted, device_link_remove() has to be called as
many times as device_link_add().

Signed-off-by: Guennadi Liakhovetski 
---

Resending with the "PATCH" subject line modifier.

 drivers/regulator/core.c | 10 +-
 1 file changed, 1 insertion(+), 9 deletions(-)

diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 2c66b528aede..342102e8bc21 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -1837,15 +1837,7 @@ static void _regulator_put(struct regulator *regulator)
debugfs_remove_recursive(regulator->debugfs);
 
if (regulator->dev) {
-   int count = 0;
-   struct regulator *r;
-
-   list_for_each_entry(r, &rdev->consumer_list, list)
-   if (r->dev == regulator->dev)
-   count++;
-
-   if (count == 1)
-   device_link_remove(regulator->dev, &rdev->dev);
+   device_link_remove(regulator->dev, &rdev->dev);
 
/* remove any sysfs entries */
sysfs_remove_link(&rdev->dev.kobj, regulator->supply_name);
-- 
2.17.1



regulator: fix device unlinking

2019-02-06 Thread Guennadi Liakhovetski
From: Guennadi Liakhovetski 

Device links are refcounted, device_link_remove() has to be called as
many times as device_link_add().

Signed-off-by: Guennadi Liakhovetski 
---
 drivers/regulator/core.c | 10 +-
 1 file changed, 1 insertion(+), 9 deletions(-)

diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 2c66b528aede..342102e8bc21 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -1837,15 +1837,7 @@ static void _regulator_put(struct regulator *regulator)
debugfs_remove_recursive(regulator->debugfs);
 
if (regulator->dev) {
-   int count = 0;
-   struct regulator *r;
-
-   list_for_each_entry(r, &rdev->consumer_list, list)
-   if (r->dev == regulator->dev)
-   count++;
-
-   if (count == 1)
-   device_link_remove(regulator->dev, &rdev->dev);
+   device_link_remove(regulator->dev, &rdev->dev);
 
/* remove any sysfs entries */
sysfs_remove_link(&rdev->dev.kobj, regulator->supply_name);
-- 
2.17.1



Re: [PATCH] media: uvcvideo: Prevent setting unavailable flags

2018-04-11 Thread Guennadi Liakhovetski
Hi Kieran,

Thanks for the patch, it fixed a problem I was having with media master, 
working with a Logitech UVC 1.5 camera.

On Wed, 21 Mar 2018, Kieran Bingham wrote:

> The addition of an extra operation to use the GET_INFO command
> overwrites all existing flags from the uvc_ctrls table. This includes
> setting all controls as supporting  GET_MIN, GET_MAX, GET_RES, and
> GET_DEF regardless of whether they do or not.
> 
> Move the initialisation of these control capabilities directly to the
> uvc_ctrl_fill_xu_info() call where they were originally located in that
> use case, and ensure that the new functionality in uvc_ctrl_get_flags()
> will only set flags based on their reported capability from the GET_INFO
> call.
> 
> Fixes: 859086ae3636 ("media: uvcvideo: Apply flags from device to actual
> properties")
> 
> Signed-off-by: Kieran Bingham 

Tested-by: Guennadi Liakhovetski 

Thanks
Guennadi

> ---
>  drivers/media/usb/uvc/uvc_ctrl.c | 17 +
>  1 file changed, 9 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/media/usb/uvc/uvc_ctrl.c 
> b/drivers/media/usb/uvc/uvc_ctrl.c
> index 1daf444371be..4042cbdb721b 100644
> --- a/drivers/media/usb/uvc/uvc_ctrl.c
> +++ b/drivers/media/usb/uvc/uvc_ctrl.c
> @@ -1607,14 +1607,12 @@ static int uvc_ctrl_get_flags(struct uvc_device *dev,
>   ret = uvc_query_ctrl(dev, UVC_GET_INFO, ctrl->entity->id, dev->intfnum,
>info->selector, data, 1);
>   if (!ret)
> - info->flags = UVC_CTRL_FLAG_GET_MIN | UVC_CTRL_FLAG_GET_MAX
> - | UVC_CTRL_FLAG_GET_RES | UVC_CTRL_FLAG_GET_DEF
> - | (data[0] & UVC_CONTROL_CAP_GET ?
> -UVC_CTRL_FLAG_GET_CUR : 0)
> - | (data[0] & UVC_CONTROL_CAP_SET ?
> -UVC_CTRL_FLAG_SET_CUR : 0)
> - | (data[0] & UVC_CONTROL_CAP_AUTOUPDATE ?
> -UVC_CTRL_FLAG_AUTO_UPDATE : 0);
> + info->flags |= (data[0] & UVC_CONTROL_CAP_GET ?
> + UVC_CTRL_FLAG_GET_CUR : 0)
> + |  (data[0] & UVC_CONTROL_CAP_SET ?
> + UVC_CTRL_FLAG_SET_CUR : 0)
> + |  (data[0] & UVC_CONTROL_CAP_AUTOUPDATE ?
> + UVC_CTRL_FLAG_AUTO_UPDATE : 0);
>  
>   kfree(data);
>   return ret;
> @@ -1689,6 +1687,9 @@ static int uvc_ctrl_fill_xu_info(struct uvc_device *dev,
>  
>   info->size = le16_to_cpup((__le16 *)data);
>  
> + info->flags = UVC_CTRL_FLAG_GET_MIN | UVC_CTRL_FLAG_GET_MAX
> + | UVC_CTRL_FLAG_GET_RES | UVC_CTRL_FLAG_GET_DEF;
> +
>   ret = uvc_ctrl_get_flags(dev, ctrl, info);
>   if (ret < 0) {
>   uvc_trace(UVC_TRACE_CONTROL,
> -- 
> 2.7.4
> 


Re: [RFT PATCH v3 6/6] uvcvideo: Move decode processing to process context

2018-01-12 Thread Guennadi Liakhovetski
Hi Kieran,

On Fri, 12 Jan 2018, Kieran Bingham wrote:

> Newer high definition cameras, and cameras with multiple lenses such as
> the range of stereo-vision cameras now available have ever increasing
> data rates.
> 
> The inclusion of a variable length packet header in URB packets mean
> that we must memcpy the frame data out to our destination 'manually'.
> This can result in data rates of up to 2 gigabits per second being
> processed.
> 
> To improve efficiency, and maximise throughput, handle the URB decode
> processing through a work queue to move it from interrupt context, and
> allow multiple processors to work on URBs in parallel.
> 
> Signed-off-by: Kieran Bingham 
> 
> ---
> v2:
>  - Lock full critical section of usb_submit_urb()
> 
> v3:
>  - Fix race on submitting uvc_video_decode_data_work() to work queue.
>  - Rename uvc_decode_op -> uvc_copy_op (Generic to encode/decode)
>  - Rename decodes -> copy_operations
>  - Don't queue work if there is no async task
>  - obtain copy op structure directly in uvc_video_decode_data()
>  - uvc_video_decode_data_work() -> uvc_video_copy_data_work()
> ---
>  drivers/media/usb/uvc/uvc_queue.c |  12 +++-
>  drivers/media/usb/uvc/uvc_video.c | 116 +++
>  drivers/media/usb/uvc/uvcvideo.h  |  24 ++-
>  3 files changed, 138 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/media/usb/uvc/uvc_queue.c 
> b/drivers/media/usb/uvc/uvc_queue.c
> index 5a9987e547d3..598087eeb5c2 100644
> --- a/drivers/media/usb/uvc/uvc_queue.c
> +++ b/drivers/media/usb/uvc/uvc_queue.c
> @@ -179,10 +179,22 @@ static void uvc_stop_streaming(struct vb2_queue *vq)
>   struct uvc_video_queue *queue = vb2_get_drv_priv(vq);
>   struct uvc_streaming *stream = uvc_queue_to_stream(queue);
>  
> + /* Prevent new buffers coming in. */
> + spin_lock_irq(&queue->irqlock);
> + queue->flags |= UVC_QUEUE_STOPPING;
> + spin_unlock_irq(&queue->irqlock);
> +
> + /*
> +  * All pending work should be completed before disabling the stream, as
> +  * all URBs will be free'd during uvc_video_enable(s, 0).
> +  */
> + flush_workqueue(stream->async_wq);

What if we manage to get one last URB here, then...

> +
>   uvc_video_enable(stream, 0);
>  
>   spin_lock_irq(&queue->irqlock);
>   uvc_queue_return_buffers(queue, UVC_BUF_STATE_ERROR);
> + queue->flags &= ~UVC_QUEUE_STOPPING;
>   spin_unlock_irq(&queue->irqlock);
>  }
>  
> diff --git a/drivers/media/usb/uvc/uvc_video.c 
> b/drivers/media/usb/uvc/uvc_video.c
> index 3878bec3276e..fb6b5af17380 100644
> --- a/drivers/media/usb/uvc/uvc_video.c
> +++ b/drivers/media/usb/uvc/uvc_video.c

[snip]

> + /*
> +  * When the stream is stopped, all URBs are freed as part of the call to
> +  * uvc_stop_streaming() and must not be handled asynchronously. In that
> +  * event we can safely complete the packet work directly in this
> +  * context, without resubmitting the URB.
> +  */
> + spin_lock_irqsave(&queue->irqlock, flags);
> + if (!(queue->flags & UVC_QUEUE_STOPPING)) {
> + INIT_WORK(&uvc_urb->work, uvc_video_copy_data_work);
> + queue_work(stream->async_wq, &uvc_urb->work);
> + } else {
> + uvc_video_copy_packets(uvc_urb);

Can it not happen, that if the stream is currently being stopped, the 
queue has been flushed, possibly the previous URB or a couple of them 
don't get decoded, but you do decode this one, creating a corrupted frame? 
Wouldn't it be better to just drop this URB too?

>   }
> + spin_unlock_irqrestore(&queue->irqlock, flags);
>  }
>  
>  /*

Thanks
Guennadi


Re: [RFC/RFT PATCH 6/6] uvcvideo: Move decode processing to process context

2018-01-04 Thread Guennadi Liakhovetski
On Wed, 3 Jan 2018, Kieran Bingham wrote:

> From: Kieran Bingham 
> 
> Newer high definition cameras, and cameras with multiple lenses such as
> the range of stereovision cameras now available have ever increasing
> data rates.
> 
> The inclusion of a variable length packet header in URB packets mean
> that we must memcpy the frame data out to our destination 'manually'.
> This can result in data rates of up to 2 gigabits per second being
> processed.
> 
> To improve efficiency, and maximise throughput, handle the URB decode
> processing through a work queue to move it from interrupt context, and
> allow multiple processors to work on URBs in parallel.
> 
> Signed-off-by: Kieran Bingham 
> ---
>  drivers/media/usb/uvc/uvc_queue.c |  12 +++-
>  drivers/media/usb/uvc/uvc_video.c | 114 ++-
>  drivers/media/usb/uvc/uvcvideo.h  |  24 +++-
>  3 files changed, 132 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/media/usb/uvc/uvc_queue.c 
> b/drivers/media/usb/uvc/uvc_queue.c
> index 204dd91a8526..07fcbfc132c9 100644
> --- a/drivers/media/usb/uvc/uvc_queue.c
> +++ b/drivers/media/usb/uvc/uvc_queue.c
> @@ -179,10 +179,22 @@ static void uvc_stop_streaming(struct vb2_queue *vq)
>   struct uvc_video_queue *queue = vb2_get_drv_priv(vq);
>   struct uvc_streaming *stream = uvc_queue_to_stream(queue);
>  
> + /* Prevent new buffers coming in. */
> + spin_lock_irq(&queue->irqlock);
> + queue->flags |= UVC_QUEUE_STOPPING;
> + spin_unlock_irq(&queue->irqlock);
> +
> + /*
> +  * All pending work should be completed before disabling the stream, as
> +  * all URBs will be free'd during uvc_video_enable(s, 0).
> +  */
> + flush_workqueue(stream->async_wq);
> +
>   uvc_video_enable(stream, 0);
>  
>   spin_lock_irq(&queue->irqlock);
>   uvc_queue_return_buffers(queue, UVC_BUF_STATE_ERROR);
> + queue->flags &= ~UVC_QUEUE_STOPPING;
>   spin_unlock_irq(&queue->irqlock);
>  }
>  
> diff --git a/drivers/media/usb/uvc/uvc_video.c 
> b/drivers/media/usb/uvc/uvc_video.c
> index 045ac655313c..b7b32a6bc2dc 100644
> --- a/drivers/media/usb/uvc/uvc_video.c
> +++ b/drivers/media/usb/uvc/uvc_video.c
> @@ -1058,21 +1058,70 @@ static int uvc_video_decode_start(struct 
> uvc_streaming *stream,
>   return data[0];
>  }
>  
> -static void uvc_video_decode_data(struct uvc_streaming *stream,
> - struct uvc_buffer *buf, const __u8 *data, int len)
> +/*
> + * uvc_video_decode_data_work: Asynchronous memcpy processing
> + *
> + * Perform memcpy tasks in process context, with completion handlers
> + * to return the URB, and buffer handles.
> + *
> + * The work submitter must pre-determine that the work is safe
> + */
> +static void uvc_video_decode_data_work(struct work_struct *work)
>  {
> - unsigned int maxlen, nbytes;
> - void *mem;
> + struct uvc_urb *uvc_urb = container_of(work, struct uvc_urb, work);
> + struct uvc_streaming *stream = uvc_urb->stream;
> + struct uvc_video_queue *queue = &stream->queue;
> + unsigned int i;
> + bool stopping;
> + int ret;
> +
> + for (i = 0; i < uvc_urb->packets; i++) {
> + struct uvc_decode_op *op = &uvc_urb->decodes[i];
> +
> + memcpy(op->dst, op->src, op->len);
> +
> + /* Release reference taken on this buffer */
> + uvc_queue_buffer_release(op->buf);
> + }
> +
> + /*
> +  * Prevent resubmitting URBs when shutting down to ensure that no new
> +  * work item will be scheduled after uvc_stop_streaming() flushes the
> +  * work queue.
> +  */
> + spin_lock_irq(&queue->irqlock);
> + stopping = queue->flags & UVC_QUEUE_STOPPING;
> + spin_unlock_irq(&queue->irqlock);

Are you sure this locking really helps? What if uvc_stop_streaming() runs 
here?

Thanks
Guennadi

> +
> + if (stopping)
> + return;
> +
> + ret = usb_submit_urb(uvc_urb->urb, GFP_ATOMIC);
> + if (ret < 0)
> + uvc_printk(KERN_ERR, "Failed to resubmit video URB (%d).\n",
> +ret);
> +}


Re: [RFC/RFT PATCH 3/6] uvcvideo: Protect queue internals with helper

2018-01-04 Thread Guennadi Liakhovetski
Hi Kieran,

On Wed, 3 Jan 2018, Kieran Bingham wrote:

> From: Kieran Bingham 
> 
> The URB completion operation obtains the current buffer by reading
> directly into the queue internal interface.
> 
> Protect this queue abstraction by providing a helper
> uvc_queue_get_current_buffer() which can be used by both the decode
> task, and the uvc_queue_next_buffer() functions.
> 
> Signed-off-by: Kieran Bingham 
> Reviewed-by: Laurent Pinchart 
> ---
>  drivers/media/usb/uvc/uvc_queue.c | 34 +++-
>  drivers/media/usb/uvc/uvc_video.c |  7 +--
>  drivers/media/usb/uvc/uvcvideo.h  |  2 ++-
>  3 files changed, 32 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/media/usb/uvc/uvc_queue.c 
> b/drivers/media/usb/uvc/uvc_queue.c
> index c8d78b2f3de4..0711e3d9ff76 100644
> --- a/drivers/media/usb/uvc/uvc_queue.c
> +++ b/drivers/media/usb/uvc/uvc_queue.c
> @@ -399,6 +399,34 @@ void uvc_queue_cancel(struct uvc_video_queue *queue, int 
> disconnect)
>   spin_unlock_irqrestore(&queue->irqlock, flags);
>  }
>  
> +/*
> + * uvc_queue_get_current_buffer: Obtain the current working output buffer
> + *
> + * Buffers may span multiple packets, and even URBs, therefore the active 
> buffer
> + * remains on the queue until the EOF marker.
> + */
> +static struct uvc_buffer *
> +__uvc_queue_get_current_buffer(struct uvc_video_queue *queue)
> +{
> + if (!list_empty(&queue->irqqueue))
> + return list_first_entry(&queue->irqqueue, struct uvc_buffer,
> + queue);
> + else
> + return NULL;

I think the preferred style is not to use "else" in such cases. It might 
even be prettier to write

if (list_empty(...))
return NULL;

return list_first_entry(...);

Thanks
Guennadi


Re: [RFC/RFT PATCH 1/6] uvcvideo: Refactor URB descriptors

2018-01-04 Thread Guennadi Liakhovetski
Hi Kieran,

Just minor suggestions below:

On Wed, 3 Jan 2018, Kieran Bingham wrote:

> From: Kieran Bingham 
> 
> We currently store three separate arrays for each URB reference we hold.
> 
> Objectify the data needed to track URBs into a single uvc_urb structure,
> allowing better object management and tracking of the URB.
> 
> All accesses to the data pointers through stream, are converted to use a
> uvc_urb pointer for consistency.
> 
> Signed-off-by: Kieran Bingham 
> Reviewed-by: Laurent Pinchart 
> ---
>  drivers/media/usb/uvc/uvc_video.c | 46 
>  drivers/media/usb/uvc/uvcvideo.h  | 18 ++---
>  2 files changed, 44 insertions(+), 20 deletions(-)

[snip]

> diff --git a/drivers/media/usb/uvc/uvcvideo.h 
> b/drivers/media/usb/uvc/uvcvideo.h
> index 19e725e2bda5..4afa8ce13ea7 100644
> --- a/drivers/media/usb/uvc/uvcvideo.h
> +++ b/drivers/media/usb/uvc/uvcvideo.h
> @@ -479,6 +479,20 @@ struct uvc_stats_stream {
>   unsigned int max_sof;   /* Maximum STC.SOF value */
>  };
>  
> +/**
> + * struct uvc_urb - URB context management structure
> + *
> + * @urb: described URB. Must be allocated with usb_alloc_urb()

Didn't you mean "describes?"

> + * @urb_buffer: memory storage for the URB
> + * @urb_dma: DMA coherent addressing for the urb_buffer

The whole struct describes URBs, so, I wouldn't repeat that in these two 
field names, I'd just call them "buffer" and "dma." OTOH, later you add 
more fields like "stream," which aren't per-URB, so, maybe you want to 
keep these prefixes.

Thanks
Guennadi

> + */
> +struct uvc_urb {
> + struct urb *urb;
> +
> + char *urb_buffer;
> + dma_addr_t urb_dma;
> +};
> +
>  struct uvc_streaming {
>   struct list_head list;
>   struct uvc_device *dev;
> @@ -521,9 +535,7 @@ struct uvc_streaming {
>   __u32 max_payload_size;
>   } bulk;
>  
> - struct urb *urb[UVC_URBS];
> - char *urb_buffer[UVC_URBS];
> - dma_addr_t urb_dma[UVC_URBS];
> + struct uvc_urb uvc_urb[UVC_URBS];
>   unsigned int urb_size;
>  
>   __u32 sequence;
> -- 
> git-series 0.9.1
> 


Re: [PATCH resend] [media] uvcvideo: zero seq number when disabling stream

2017-10-18 Thread Guennadi Liakhovetski
Hi Laurent,

On Mon, 16 Oct 2017, Laurent Pinchart wrote:

> Hi Hans,
> 
> (CC'ing Guennadi Liakhovetski)
> 
> Thank you for the patch.
> 
> On Friday, 15 September 2017 09:27:51 EEST Hans Yang wrote:
> > For bulk-based devices, when disabling the video stream,
> > in addition to issue CLEAR_FEATURE(HALT), it is better to set
> > alternate setting 0 as well or the sequnce number in host
> > side will probably not reset to zero.
> 
> The USB 2.0 specificatin states in the description of the SET_INTERFACE 
> request that "If a device only supports a default setting for the specified 
> interface, then a STALL may be returned in the Status stage of the request".
> 
> The Linux implementation of usb_set_interface() deals with this by handling 
> STALL conditions and manually clearing HALT for all endpoints in the 
> interface, but I'm still concerned that this change could break existing bulk-
> based cameras. Do you know what other operating systems do when disabling the 
> stream on bulk cameras ? According to a comment in the driver Windows calls 
> CLEAR_FEATURE(HALT), but the situation might have changed since that was 
> tested.
> 
> Guennadi, how do your bulk-based cameras handle this ?

I don't know what design decisions are implemented there, but I tested a 
couple of cameras for sending a STREAMOFF after a few captured buffers, 
sleeping for a couple of seconds, requeuing buffers, sending STREAMON and 
capturing a few more - that seems to have worked. "Seems" because I only 
used a modified version of capture-example, I haven't checked buffer 
contents.

BTW, Hans, may I ask - what cameras did you use?

Thanks
Guennadi

> > Then in next time video stream start, the device will expect
> > host starts packet from 0 sequence number but host actually
> > continue the sequence number from last transaction and this
> > causes transaction errors.
> 
> Do you mean the DATA0/DATA1 toggle ? Why does the host continue toggling the 
> PID from the last transation ? The usb_clear_halt() function calls 
> usb_reset_endpoint() which should reset the DATA PID toggle.
> 
> > This commit fixes this by adding set alternate setting 0 back
> > as what isoch-based devices do.
> > 
> > Below error message will also be eliminated for some devices:
> > uvcvideo: Non-zero status (-71) in video completion handler.
> > 
> > Signed-off-by: Hans Yang 
> > ---
> >  drivers/media/usb/uvc/uvc_video.c | 5 ++---
> >  1 file changed, 2 insertions(+), 3 deletions(-)
> > 
> > diff --git a/drivers/media/usb/uvc/uvc_video.c
> > b/drivers/media/usb/uvc/uvc_video.c index fb86d6af398d..ad80c2a6da6a 100644
> > --- a/drivers/media/usb/uvc/uvc_video.c
> > +++ b/drivers/media/usb/uvc/uvc_video.c
> > @@ -1862,10 +1862,9 @@ int uvc_video_enable(struct uvc_streaming *stream,
> > int enable)
> > 
> > if (!enable) {
> > uvc_uninit_video(stream, 1);
> > -   if (stream->intf->num_altsetting > 1) {
> > -   usb_set_interface(stream->dev->udev,
> > +   usb_set_interface(stream->dev->udev,
> >   stream->intfnum, 0);
> > -   } else {
> > +   if (stream->intf->num_altsetting == 1) {
> > /* UVC doesn't specify how to inform a bulk-based device
> >  * when the video stream is stopped. Windows sends a
> >  * CLEAR_FEATURE(HALT) request to the video streaming
> 
> -- 
> Regards,
> 
> Laurent Pinchart
> 


Re: [PATCH 03/15] [media] i2c: make device_type const

2017-08-24 Thread Guennadi Liakhovetski
On Sat, 19 Aug 2017, Bhumika Goyal wrote:

> Make this const as it is only stored in the type field of a device
> structure, which is const.
> Done using Coccinelle.
> 
> Signed-off-by: Bhumika Goyal 

Acked-by: Guennadi Liakhovetski 

Thanks
Guennadi

> ---
>  drivers/media/i2c/soc_camera/mt9t031.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/media/i2c/soc_camera/mt9t031.c 
> b/drivers/media/i2c/soc_camera/mt9t031.c
> index 714fb35..4802d30 100644
> --- a/drivers/media/i2c/soc_camera/mt9t031.c
> +++ b/drivers/media/i2c/soc_camera/mt9t031.c
> @@ -592,7 +592,7 @@ static int mt9t031_runtime_resume(struct device *dev)
>   .runtime_resume = mt9t031_runtime_resume,
>  };
>  
> -static struct device_type mt9t031_dev_type = {
> +static const struct device_type mt9t031_dev_type = {
>   .name   = "MT9T031",
>   .pm = &mt9t031_dev_pm_ops,
>  };
> -- 
> 1.9.1
> 


Re: [PATCH 1/3] [media] soc-camera: ov5642: Add OF device ID table

2017-02-26 Thread Guennadi Liakhovetski
On Wed, 22 Feb 2017, Javier Martinez Canillas wrote:

> The driver doesn't have a struct of_device_id table but supported devices
> are registered via Device Trees. This is working on the assumption that a
> I2C device registered via OF will always match a legacy I2C device ID and
> that the MODALIAS reported will always be of the form i2c:.
> 
> But this could change in the future so the correct approach is to have an
> OF device ID table if the devices are registered via OF.
> 
> Signed-off-by: Javier Martinez Canillas 

Acked-by: Guennadi Liakhovetski 

> ---
> 
>  drivers/media/i2c/soc_camera/ov5642.c | 9 +
>  1 file changed, 9 insertions(+)
> 
> diff --git a/drivers/media/i2c/soc_camera/ov5642.c 
> b/drivers/media/i2c/soc_camera/ov5642.c
> index 3d185bd622a3..1926f382dfce 100644
> --- a/drivers/media/i2c/soc_camera/ov5642.c
> +++ b/drivers/media/i2c/soc_camera/ov5642.c
> @@ -1063,9 +1063,18 @@ static const struct i2c_device_id ov5642_id[] = {
>  };
>  MODULE_DEVICE_TABLE(i2c, ov5642_id);
>  
> +#if IS_ENABLED(CONFIG_OF)
> +static const struct of_device_id ov5642_of_match[] = {
> + { .compatible = "ovti,ov5642" },
> + { },
> +};
> +MODULE_DEVICE_TABLE(of, ov5642_of_match);
> +#endif
> +
>  static struct i2c_driver ov5642_i2c_driver = {
>   .driver = {
>   .name = "ov5642",
> + .of_match_table = of_match_ptr(ov5642_of_match),
>   },
>   .probe  = ov5642_probe,
>   .remove = ov5642_remove,
> -- 
> 2.9.3
> 


Re: [PATCH v5 01/13] media: mt9m111: make a standalone v4l2 subdevice

2016-08-30 Thread Guennadi Liakhovetski
Hi Robert,

On Mon, 29 Aug 2016, Robert Jarzmik wrote:

> Remove the soc_camera adherence. Mostly the change removes the power
> manipulation provided by soc_camera, and instead :
>  - powers on the sensor when the s_power control is activated
>  - powers on the sensor in initial probe
>  - enables and disables the MCLK provided to it in power on/off

Your patch also drops support for inverters on synchronisation and clock 
lines, I guess, your board doesn't use any. I assume, if any board ever 
needs such inverters, support for them can be added in the future. Also, 
as I mentioned in my reply to your other patch, maybe good to join this 
with #3. Otherwise and with that in mind

> Signed-off-by: Robert Jarzmik 

Acked-by: Guennadi Liakhovetski 

Thanks
Guennadi

> ---
>  drivers/media/i2c/soc_camera/mt9m111.c | 51 
> ++
>  1 file changed, 15 insertions(+), 36 deletions(-)
> 
> diff --git a/drivers/media/i2c/soc_camera/mt9m111.c 
> b/drivers/media/i2c/soc_camera/mt9m111.c
> index 6dfaead6aaa8..a7efaa5964d1 100644
> --- a/drivers/media/i2c/soc_camera/mt9m111.c
> +++ b/drivers/media/i2c/soc_camera/mt9m111.c
> @@ -16,10 +16,11 @@
>  #include 
>  #include 
>  
> -#include 
> +#include 
>  #include 
>  #include 
>  #include 
> +#include 
>  
>  /*
>   * MT9M111, MT9M112 and MT9M131:
> @@ -388,7 +389,7 @@ static int mt9m111_s_crop(struct v4l2_subdev *sd, const 
> struct v4l2_crop *a)
>   struct v4l2_rect rect = a->c;
>   struct mt9m111 *mt9m111 = container_of(sd, struct mt9m111, subdev);
>   int width, height;
> - int ret;
> + int ret, align = 0;
>  
>   if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
>   return -EINVAL;
> @@ -396,17 +397,19 @@ static int mt9m111_s_crop(struct v4l2_subdev *sd, const 
> struct v4l2_crop *a)
>   if (mt9m111->fmt->code == MEDIA_BUS_FMT_SBGGR8_1X8 ||
>   mt9m111->fmt->code == MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE) {
>   /* Bayer format - even size lengths */
> - rect.width  = ALIGN(rect.width, 2);
> - rect.height = ALIGN(rect.height, 2);
> + align = 1;
>   /* Let the user play with the starting pixel */
>   }
>  
>   /* FIXME: the datasheet doesn't specify minimum sizes */
> - soc_camera_limit_side(&rect.left, &rect.width,
> -  MT9M111_MIN_DARK_COLS, 2, MT9M111_MAX_WIDTH);
> -
> - soc_camera_limit_side(&rect.top, &rect.height,
> -  MT9M111_MIN_DARK_ROWS, 2, MT9M111_MAX_HEIGHT);
> + v4l_bound_align_image(&rect.width, 2, MT9M111_MAX_WIDTH, align,
> +   &rect.height, 2, MT9M111_MAX_HEIGHT, align, 0);
> + rect.left = clamp(rect.left, MT9M111_MIN_DARK_COLS,
> +   MT9M111_MIN_DARK_COLS + MT9M111_MAX_WIDTH -
> +   (__s32)rect.width);
> + rect.top = clamp(rect.top, MT9M111_MIN_DARK_ROWS,
> +  MT9M111_MIN_DARK_ROWS + MT9M111_MAX_HEIGHT -
> +  (__s32)rect.height);
>  
>   width = min(mt9m111->width, rect.width);
>   height = min(mt9m111->height, rect.height);
> @@ -775,17 +778,16 @@ static int mt9m111_init(struct mt9m111 *mt9m111)
>  static int mt9m111_power_on(struct mt9m111 *mt9m111)
>  {
>   struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev);
> - struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
>   int ret;
>  
> - ret = soc_camera_power_on(&client->dev, ssdd, mt9m111->clk);
> + ret = v4l2_clk_enable(mt9m111->clk);
>   if (ret < 0)
>   return ret;
>  
>   ret = mt9m111_resume(mt9m111);
>   if (ret < 0) {
>   dev_err(&client->dev, "Failed to resume the sensor: %d\n", ret);
> - soc_camera_power_off(&client->dev, ssdd, mt9m111->clk);
> + v4l2_clk_disable(mt9m111->clk);
>   }
>  
>   return ret;
> @@ -793,11 +795,8 @@ static int mt9m111_power_on(struct mt9m111 *mt9m111)
>  
>  static void mt9m111_power_off(struct mt9m111 *mt9m111)
>  {
> - struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev);
> - struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
> -
>   mt9m111_suspend(mt9m111);
> - soc_camera_power_off(&client->dev, ssdd, mt9m111->clk);
> + v4l2_clk_disable(mt9m111->clk);
>  }
>  
>  static int mt9m111_s_power(struct v4l2_subdev *sd, int on)
> @@ -854,14 +853,10 @@ static int mt9m111_enum_mbus_code(struct v4l2_subdev 
> *sd,
>  static int mt9m111_g_mbus_config

Re: [PATCH v5 03/13] media: mt9m111: move mt9m111 out of soc_camera

2016-08-30 Thread Guennadi Liakhovetski
Hi Robert,

You could use "git format-patch -M" to make this patch much smaller and to 
make it simple to verify, what actually changed in mt9m111.c, if anything. 
Actually it might even be good to merge this patch with patch #1.

Thanks
Guennadi

On Mon, 29 Aug 2016, Robert Jarzmik wrote:

> As the mt9m111 is now working as a standalone v4l2 subdevice sensor,
> move it out of soc_camera directory and severe its dependency on
> soc_camera.
> 
> Signed-off-by: Robert Jarzmik 
> ---
>  drivers/media/i2c/Kconfig  |7 +
>  drivers/media/i2c/Makefile |1 +
>  drivers/media/i2c/mt9m111.c| 1033 
> 
>  drivers/media/i2c/soc_camera/Kconfig   |7 +-
>  drivers/media/i2c/soc_camera/Makefile  |1 -
>  drivers/media/i2c/soc_camera/mt9m111.c | 1033 
> 
>  6 files changed, 1046 insertions(+), 1036 deletions(-)
>  create mode 100644 drivers/media/i2c/mt9m111.c
>  delete mode 100644 drivers/media/i2c/soc_camera/mt9m111.c
> 
> diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
> index ce9006e10a30..7f8790507660 100644
> --- a/drivers/media/i2c/Kconfig
> +++ b/drivers/media/i2c/Kconfig
> @@ -571,6 +571,13 @@ config VIDEO_MT9M032
> This driver supports MT9M032 camera sensors from Aptina, monochrome
> models only.
>  
> +config VIDEO_MT9M111
> + tristate "mt9m111, mt9m112 and mt9m131 support"
> + depends on I2C && VIDEO_V4L2
> + help
> +   This driver supports MT9M111, MT9M112 and MT9M131 cameras from
> +   Micron/Aptina
> +
>  config VIDEO_MT9P031
>   tristate "Aptina MT9P031 support"
>   depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
> diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
> index 94f2c99e890d..a1a82331bebc 100644
> --- a/drivers/media/i2c/Makefile
> +++ b/drivers/media/i2c/Makefile
> @@ -59,6 +59,7 @@ obj-$(CONFIG_VIDEO_OV7640) += ov7640.o
>  obj-$(CONFIG_VIDEO_OV7670) += ov7670.o
>  obj-$(CONFIG_VIDEO_OV9650) += ov9650.o
>  obj-$(CONFIG_VIDEO_MT9M032) += mt9m032.o
> +obj-$(CONFIG_VIDEO_MT9M111) += mt9m111.o
>  obj-$(CONFIG_VIDEO_MT9P031) += mt9p031.o
>  obj-$(CONFIG_VIDEO_MT9T001) += mt9t001.o
>  obj-$(CONFIG_VIDEO_MT9V011) += mt9v011.o
> diff --git a/drivers/media/i2c/mt9m111.c b/drivers/media/i2c/mt9m111.c
> new file mode 100644
> index ..b7c4f371bae1
> --- /dev/null
> +++ b/drivers/media/i2c/mt9m111.c
> @@ -0,0 +1,1033 @@
> +/*
> + * Driver for MT9M111/MT9M112/MT9M131 CMOS Image Sensor from Micron/Aptina
> + *
> + * Copyright (C) 2008, Robert Jarzmik 
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +/*
> + * MT9M111, MT9M112 and MT9M131:
> + * i2c address is 0x48 or 0x5d (depending on SADDR pin)
> + * The platform has to define struct i2c_board_info objects and link to them
> + * from struct soc_camera_host_desc
> + */
> +
> +/*
> + * Sensor core register addresses (0x000..0x0ff)
> + */
> +#define MT9M111_CHIP_VERSION 0x000
> +#define MT9M111_ROW_START0x001
> +#define MT9M111_COLUMN_START 0x002
> +#define MT9M111_WINDOW_HEIGHT0x003
> +#define MT9M111_WINDOW_WIDTH 0x004
> +#define MT9M111_HORIZONTAL_BLANKING_B0x005
> +#define MT9M111_VERTICAL_BLANKING_B  0x006
> +#define MT9M111_HORIZONTAL_BLANKING_A0x007
> +#define MT9M111_VERTICAL_BLANKING_A  0x008
> +#define MT9M111_SHUTTER_WIDTH0x009
> +#define MT9M111_ROW_SPEED0x00a
> +#define MT9M111_EXTRA_DELAY  0x00b
> +#define MT9M111_SHUTTER_DELAY0x00c
> +#define MT9M111_RESET0x00d
> +#define MT9M111_READ_MODE_B  0x020
> +#define MT9M111_READ_MODE_A  0x021
> +#define MT9M111_FLASH_CONTROL0x023
> +#define MT9M111_GREEN1_GAIN  0x02b
> +#define MT9M111_BLUE_GAIN0x02c
> +#define MT9M111_RED_GAIN 0x02d
> +#define MT9M111_GREEN2_GAIN  0x02e
> +#define MT9M111_GLOBAL_GAIN  0x02f
> +#define MT9M111_CONTEXT_CONTROL  0x0c8
> +#define MT9M111_PAGE_MAP 0x0f0
> +#define MT9M111_BYTE_WISE_ADDR   0x0f1
> +
> +#define MT9M111_RESET_SYNC_CHANGES   (1 << 15)
> +#define MT9M111_RESET_RESTART_BAD_FRAME  (1 << 9)
> +#define MT9M111_RESET_SHOW_BAD_FRAMES(1 << 8)
> +#define MT9M111_RESET_RESET_SOC  (1 << 5)
> +#define MT9M111_RESET_OUTPUT_DISABLE (1 << 4)
> +#define MT9M111_RESET_CHIP_ENABLE(1 << 3)
> +#define MT9M111_RESET_ANALOG_STANDBY (1 << 2)
> +#define MT9M111_RESET_RESTART_FRAME  (1 << 1)
> +#define MT9M111_RESET_RESET_MODE (1 << 0)
> +
> +#define MT9M111_

Re: [PATCH RFC v2 1/2] media: platform: transfer format translations to soc_mediabus

2016-04-05 Thread Guennadi Liakhovetski
Hi Robert,

Not sure I understand, what should the purpose of this patch be? Why do 
you want to move some function(s) from one file to another? And you aren't 
even calling the new soc_mbus_build_fmts_xlate() function, and you aren't 
replacing the currently used analogous soc_camera_init_user_formats() 
function. Or was this patch not-to-be-reviewed?

Thanks
Guennadi

On Sat, 2 Apr 2016, Robert Jarzmik wrote:

> Transfer the formats translations to soc_mediabus. Even is soc_camera
> was to be deprecated, soc_mediabus will survive, and should describe all
> that happens on the bus connecting the image processing unit of the SoC
> and the sensor.
> 
> The translation engine provides an easy way to compute the formats
> available in the v4l2 device, given any sensors format capabilities
> bound with known image processing transformations.
> 
> Signed-off-by: Robert Jarzmik 
> ---
>  drivers/media/platform/soc_camera/soc_camera.c   |  7 +--
>  drivers/media/platform/soc_camera/soc_mediabus.c | 65 
> 
>  include/media/drv-intf/soc_mediabus.h| 22 
>  include/media/soc_camera.h   | 15 --
>  4 files changed, 88 insertions(+), 21 deletions(-)
> 
> diff --git a/drivers/media/platform/soc_camera/soc_camera.c 
> b/drivers/media/platform/soc_camera/soc_camera.c
> index 46c7186f7867..039524a20056 100644
> --- a/drivers/media/platform/soc_camera/soc_camera.c
> +++ b/drivers/media/platform/soc_camera/soc_camera.c
> @@ -204,12 +204,7 @@ static void soc_camera_clock_stop(struct soc_camera_host 
> *ici)
>  const struct soc_camera_format_xlate *soc_camera_xlate_by_fourcc(
>   struct soc_camera_device *icd, unsigned int fourcc)
>  {
> - unsigned int i;
> -
> - for (i = 0; i < icd->num_user_formats; i++)
> - if (icd->user_formats[i].host_fmt->fourcc == fourcc)
> - return icd->user_formats + i;
> - return NULL;
> + return soc_mbus_xlate_by_fourcc(icd->user_formats, fourcc);
>  }
>  EXPORT_SYMBOL(soc_camera_xlate_by_fourcc);
>  
> diff --git a/drivers/media/platform/soc_camera/soc_mediabus.c 
> b/drivers/media/platform/soc_camera/soc_mediabus.c
> index e3e665e1c503..95c13055f50f 100644
> --- a/drivers/media/platform/soc_camera/soc_mediabus.c
> +++ b/drivers/media/platform/soc_camera/soc_mediabus.c
> @@ -10,6 +10,7 @@
>  
>  #include 
>  #include 
> +#include 
>  
>  #include 
>  #include 
> @@ -512,6 +513,70 @@ unsigned int soc_mbus_config_compatible(const struct 
> v4l2_mbus_config *cfg,
>  }
>  EXPORT_SYMBOL(soc_mbus_config_compatible);
>  
> +struct soc_camera_format_xlate *soc_mbus_build_fmts_xlate(
> + struct v4l2_device *v4l2_dev, struct v4l2_subdev *subdev,
> + int (*get_formats)(struct v4l2_device *, unsigned int,
> +struct soc_camera_format_xlate *xlate))
> +{
> + unsigned int i, fmts = 0, raw_fmts = 0;
> + int ret;
> + struct v4l2_subdev_mbus_code_enum code = {
> + .which = V4L2_SUBDEV_FORMAT_ACTIVE,
> + };
> + struct soc_camera_format_xlate *user_formats;
> +
> + while (!v4l2_subdev_call(subdev, pad, enum_mbus_code, NULL, &code)) {
> + raw_fmts++;
> + code.index++;
> + }
> +
> + /*
> +  * First pass - only count formats this host-sensor
> +  * configuration can provide
> +  */
> + for (i = 0; i < raw_fmts; i++) {
> + ret = get_formats(v4l2_dev, i, NULL);
> + if (ret < 0)
> + return ERR_PTR(ret);
> + fmts += ret;
> + }
> +
> + if (!fmts)
> + return ERR_PTR(-ENXIO);
> +
> + user_formats = kcalloc(fmts + 1, sizeof(*user_formats), GFP_KERNEL);
> + if (!user_formats)
> + return ERR_PTR(-ENOMEM);
> +
> + /* Second pass - actually fill data formats */
> + fmts = 0;
> + for (i = 0; i < raw_fmts; i++) {
> + ret = get_formats(v4l2_dev, i, user_formats + fmts);
> + if (ret < 0)
> + goto egfmt;
> + fmts += ret;
> + }
> + user_formats[fmts].code = 0;
> +
> + return user_formats;
> +egfmt:
> + kfree(user_formats);
> + return ERR_PTR(ret);
> +}
> +EXPORT_SYMBOL(soc_mbus_build_fmts_xlate);
> +
> +const struct soc_camera_format_xlate *soc_mbus_xlate_by_fourcc(
> + struct soc_camera_format_xlate *user_formats, unsigned int fourcc)
> +{
> + unsigned int i;
> +
> + for (i = 0; user_formats[i].code; i++)
> + if (user_formats[i].host_fmt->fourcc == fourcc)
> + return user_formats + i;
> + return NULL;
> +}
> +EXPORT_SYMBOL(soc_mbus_xlate_by_fourcc);
> +
>  static int __init soc_mbus_init(void)
>  {
>   return 0;
> diff --git a/include/media/drv-intf/soc_mediabus.h 
> b/include/media/drv-intf/soc_mediabus.h
> index 2ff773785fb6..08af52f6338c 100644
> --- a/include/media/drv-intf/soc_mediabus.h
> +++ b/include/media/drv-intf/soc_mediabus.h
> @@ -95,6 +95,21 @@ struct soc_mbus_l

Re: [PATCH v5 1/4] media: pxa_camera: fix the buffer free path

2016-02-21 Thread Guennadi Liakhovetski
On Mon, 8 Feb 2016, Robert Jarzmik wrote:

> Guennadi Liakhovetski  writes:
> 
> > Hi Robert,
> >
> > On Tue, 27 Oct 2015, Robert Jarzmik wrote:
> >
> >> Guennadi Liakhovetski  writes:
> >> 
> >> > Hi Robert,
> >> >
> >> > Didn't you tell me, that your dmaengine patch got rejected and therefore 
> >> > these your patches were on hold?
> >> They were reverted, and then revamped into DMA_CTRL_REUSE, upstreamed and
> >> merged, as in the commit 272420214d26 ("dmaengine: Add DMA_CTRL_REUSE"). 
> >> I'd
> >> 
> >> Of course a pending fix is still underway
> >> (http://www.serverphorums.com/read.php?12,1318680). But that shouldn't 
> >> stop us
> >> from reviewing to get ready to merge.
> >> 
> >> I want this serie to be ready, so that as soon as Vinod merges the fix, I 
> >> can
> >> ping you to trigger the merge into your tree, without doing (and waiting)
> >> additional review cycles.
> >
> > Thanks, understand now. As we discussed before, correct me if I am wrong, 
> > this is your hobby project. PXA270 is a legacy platform, nobody except you 
> > is interested in this work. I have nothing against hobby projects and I 
> > want to support them as much as I can, but I hope you'll understand, that 
> > I don't have too much free time, so I cannot handle such projects with a 
> > high priority. I understand your desire to process these patches ASAP, 
> > however, I'd like to try to minimise my work too. So, I can propose the 
> > following: let us wait, until your PXA dmaengine patches are _indeed_ in 
> > the mainline. Then you test your camera patches on top of that tree again, 
> > perform any eventually necessary updates and either let me know, that 
> > either your last version is ok and I can now review it, or submit a new 
> > version, that _works_ on top of then current tree.
> 
> Okay Guennadi, I retested this version on top of v4.5-rc2, still good to
> go. There is a minor conflict in the includes since this submission, and I can
> repost a v6 which solves it.

How did you test it with that patchg #3?? What's a minor conflict? If a 
patch doesn't apply at all or applies with a fuzz, yes, please fix. If 
it's just a few lines off, no need to fix that. But you'll do a v6 anyway, 
I assume.

Thanks
Guennadi

> So please tell me how I should proceed, either repost a rebased v6 or take v5 
> or
> anything else ...
> 
> Cheers.
> 
> --
> Robert
> 


Re: [PATCH v5 3/4] media: pxa_camera: trivial move of dma irq functions

2016-02-21 Thread Guennadi Liakhovetski
Hi Robert,

On Sun, 6 Sep 2015, Robert Jarzmik wrote:

> This moves the dma irq handling functions up in the source file, so that
> they are available before DMA preparation functions. It prepares the
> conversion to DMA engine, where the descriptors are populated with these
> functions as callbacks.
> 
> Signed-off-by: Robert Jarzmik 
> ---
> Since v1: fixed prototypes change
> Since v4: refixed prototypes change
> ---
>  drivers/media/platform/soc_camera/pxa_camera.c | 42 
> +++---
>  1 file changed, 24 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/media/platform/soc_camera/pxa_camera.c 
> b/drivers/media/platform/soc_camera/pxa_camera.c
> index db041a5ed444..bb7054221a86 100644
> --- a/drivers/media/platform/soc_camera/pxa_camera.c
> +++ b/drivers/media/platform/soc_camera/pxa_camera.c
> @@ -311,6 +311,30 @@ static int calculate_dma_sglen(struct scatterlist 
> *sglist, int sglen,
>   return i + 1;
>  }
>  
> +static void pxa_camera_dma_irq(struct pxa_camera_dev *pcdev,
> +enum pxa_camera_active_dma act_dma);

This is v5. You fixed prototypes in v1 and v4. Let's see:

> +
> +static void pxa_camera_dma_irq_y(int channel, void *data)
> +{
> + struct pxa_camera_dev *pcdev = data;
> +
> + pxa_camera_dma_irq(channel, pcdev, DMA_Y);

This doesn't seem fixed to me.

Thanks
Guennadi

> +}
> +
> +static void pxa_camera_dma_irq_u(int channel, void *data)
> +{
> + struct pxa_camera_dev *pcdev = data;
> +
> + pxa_camera_dma_irq(channel, pcdev, DMA_U);
> +}
> +
> +static void pxa_camera_dma_irq_v(int channel, void *data)
> +{
> + struct pxa_camera_dev *pcdev = data;
> +
> + pxa_camera_dma_irq(channel, pcdev, DMA_V);
> +}
> +
>  /**
>   * pxa_init_dma_channel - init dma descriptors
>   * @pcdev: pxa camera device
> @@ -802,24 +826,6 @@ out:
>   spin_unlock_irqrestore(&pcdev->lock, flags);
>  }
>  
> -static void pxa_camera_dma_irq_y(int channel, void *data)
> -{
> - struct pxa_camera_dev *pcdev = data;
> - pxa_camera_dma_irq(channel, pcdev, DMA_Y);
> -}
> -
> -static void pxa_camera_dma_irq_u(int channel, void *data)
> -{
> - struct pxa_camera_dev *pcdev = data;
> - pxa_camera_dma_irq(channel, pcdev, DMA_U);
> -}
> -
> -static void pxa_camera_dma_irq_v(int channel, void *data)
> -{
> - struct pxa_camera_dev *pcdev = data;
> - pxa_camera_dma_irq(channel, pcdev, DMA_V);
> -}
> -
>  static struct videobuf_queue_ops pxa_videobuf_ops = {
>   .buf_setup  = pxa_videobuf_setup,
>   .buf_prepare= pxa_videobuf_prepare,
> -- 
> 2.1.4
> 


Re: [PATCH 4/7] atmel-isi: fix IS_ERR_VALUE usage

2016-02-21 Thread Guennadi Liakhovetski
Hi Andrzej,

On Mon, 15 Feb 2016, Andrzej Hajda wrote:

> IS_ERR_VALUE macro should be used only with unsigned long type.
> For signed types comparison 'ret < 0' should be used.
> 
> The patch follows conclusion from discussion on LKML [1][2].
> 
> [1]: http://permalink.gmane.org/gmane.linux.kernel/2120927
> [2]: http://permalink.gmane.org/gmane.linux.kernel/2150581
> 
> Signed-off-by: Andrzej Hajda 

Thanks for the patch, but this one

https://lkml.org/lkml/2016/2/9/392

came a couple of days earlier. Unless there is an important reason to use 
yours, I'll use that one.

Thanks
Guennadi

> ---
>  drivers/media/platform/soc_camera/atmel-isi.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/media/platform/soc_camera/atmel-isi.c 
> b/drivers/media/platform/soc_camera/atmel-isi.c
> index 1af779e..ab2d9b9 100644
> --- a/drivers/media/platform/soc_camera/atmel-isi.c
> +++ b/drivers/media/platform/soc_camera/atmel-isi.c
> @@ -1026,7 +1026,7 @@ static int atmel_isi_parse_dt(struct atmel_isi *isi,
>  
>  static int atmel_isi_probe(struct platform_device *pdev)
>  {
> - unsigned int irq;
> + int irq;
>   struct atmel_isi *isi;
>   struct resource *regs;
>   int ret, i;
> @@ -1086,7 +1086,7 @@ static int atmel_isi_probe(struct platform_device *pdev)
>   isi->width_flags |= 1 << 9;
>  
>   irq = platform_get_irq(pdev, 0);
> - if (IS_ERR_VALUE(irq)) {
> + if (irq < 0) {
>   ret = irq;
>   goto err_req_irq;
>   }
> -- 
> 1.9.1
> 


Re: [PATCH v5 1/4] media: pxa_camera: fix the buffer free path

2016-02-21 Thread Guennadi Liakhovetski
On Sun, 21 Feb 2016, Robert Jarzmik wrote:

> Guennadi Liakhovetski  writes:
> 
> >> Okay Guennadi, I retested this version on top of v4.5-rc2, still good to
> >> go. There is a minor conflict in the includes since this submission, and I 
> >> can
> >> repost a v6 which solves it.
> >
> > How did you test it with that patchg #3??
> I rebased my patches on top of v4.5-rc2. To be exact, I rebased the tree I had
> with these last patches on top of v4.5-rc2. I'll recheck, it's been some time
> ...
> 
> > What's a minor conflict?
> A conflict on a context line :
> #include 
> #include 
> 
> I think linux/platform_data/media/camera-pxa.h changed from my last submssion,
> hence the conflict.
> 
> > If a patch doesn't apply at all or applies with a fuzz, yes, please fix. If
> > it's just a few lines off, no need to fix that. But you'll do a v6 anyway, I
> > assume.
> But of course, let us have a v6 which cleanly applies on v4.5-rc2, and 
> restested
> once more. I'll try to have it done this evening.

Please, have a look at 
http://git.linuxtv.org/gliakhovetski/v4l-dvb.git/log/?h=for-4.6-2
If all is good there, no need for a v6

Thanks
Guennadi

> 
> Cheers.
> 
> -- 
> Robert
> 


Re: [PATCH v5 3/4] media: pxa_camera: trivial move of dma irq functions

2016-02-21 Thread Guennadi Liakhovetski
On Sun, 21 Feb 2016, Guennadi Liakhovetski wrote:

> Hi Robert,
> 
> On Sun, 6 Sep 2015, Robert Jarzmik wrote:
> 
> > This moves the dma irq handling functions up in the source file, so that
> > they are available before DMA preparation functions. It prepares the
> > conversion to DMA engine, where the descriptors are populated with these
> > functions as callbacks.
> > 
> > Signed-off-by: Robert Jarzmik 
> > ---
> > Since v1: fixed prototypes change
> > Since v4: refixed prototypes change
> > ---
> >  drivers/media/platform/soc_camera/pxa_camera.c | 42 
> > +++---
> >  1 file changed, 24 insertions(+), 18 deletions(-)
> > 
> > diff --git a/drivers/media/platform/soc_camera/pxa_camera.c 
> > b/drivers/media/platform/soc_camera/pxa_camera.c
> > index db041a5ed444..bb7054221a86 100644
> > --- a/drivers/media/platform/soc_camera/pxa_camera.c
> > +++ b/drivers/media/platform/soc_camera/pxa_camera.c
> > @@ -311,6 +311,30 @@ static int calculate_dma_sglen(struct scatterlist 
> > *sglist, int sglen,
> > return i + 1;
> >  }
> >  
> > +static void pxa_camera_dma_irq(struct pxa_camera_dev *pcdev,
> > +  enum pxa_camera_active_dma act_dma);
> 
> This is v5. You fixed prototypes in v1 and v4. Let's see:
> 
> > +
> > +static void pxa_camera_dma_irq_y(int channel, void *data)
> > +{
> > +   struct pxa_camera_dev *pcdev = data;
> > +
> > +   pxa_camera_dma_irq(channel, pcdev, DMA_Y);
> 
> This doesn't seem fixed to me.

Forget about this, I'll fix it locally.

> 
> Thanks
> Guennadi
> 
> > +}
> > +
> > +static void pxa_camera_dma_irq_u(int channel, void *data)
> > +{
> > +   struct pxa_camera_dev *pcdev = data;
> > +
> > +   pxa_camera_dma_irq(channel, pcdev, DMA_U);
> > +}
> > +
> > +static void pxa_camera_dma_irq_v(int channel, void *data)
> > +{
> > +   struct pxa_camera_dev *pcdev = data;
> > +
> > +   pxa_camera_dma_irq(channel, pcdev, DMA_V);
> > +}
> > +
> >  /**
> >   * pxa_init_dma_channel - init dma descriptors
> >   * @pcdev: pxa camera device
> > @@ -802,24 +826,6 @@ out:
> > spin_unlock_irqrestore(&pcdev->lock, flags);
> >  }
> >  
> > -static void pxa_camera_dma_irq_y(int channel, void *data)
> > -{
> > -   struct pxa_camera_dev *pcdev = data;
> > -   pxa_camera_dma_irq(channel, pcdev, DMA_Y);
> > -}
> > -
> > -static void pxa_camera_dma_irq_u(int channel, void *data)
> > -{
> > -   struct pxa_camera_dev *pcdev = data;
> > -   pxa_camera_dma_irq(channel, pcdev, DMA_U);
> > -}
> > -
> > -static void pxa_camera_dma_irq_v(int channel, void *data)
> > -{
> > -   struct pxa_camera_dev *pcdev = data;
> > -   pxa_camera_dma_irq(channel, pcdev, DMA_V);
> > -}
> > -
> >  static struct videobuf_queue_ops pxa_videobuf_ops = {
> > .buf_setup  = pxa_videobuf_setup,
> > .buf_prepare= pxa_videobuf_prepare,
> > -- 
> > 2.1.4
> > 
> 


Re: [PATCH] net: smc911x: convert pxa dma to dmaengine

2016-02-20 Thread Guennadi Liakhovetski
Hi,

On Sat, 20 Feb 2016, Hitoshi Mitake wrote:

> 
> Hi Robert,
> 
> At Sat, 06 Feb 2016 10:05:51 +0100,
> Robert Jarzmik wrote:
> > 
> > David Miller  writes:
> > 
> > > From: Robert Jarzmik 
> > > Date: Fri, 05 Feb 2016 22:44:56 +0100
> > >
> > >> Apart from Alberto who answered he cannot test it by lack of hardware, 
> > >> the
> > >> others didn't answer.
> > >> 
> > >> So how can I move forward ? Would you want me to amend the KConfig to 
> > >> add a "&&
> > >> !ARCH_PXA" on the "depend" line ?
> > >
> > > Please just keep pinging people to properly test this.
> > Okay, let's have another try.
> > 
> > Hi Guennadi, Hitoshi, Fabio,
> > 
> > Could any of you try this patch to ensure your board is not broken please ?
> > I've re-added the patch at the end of this mail for easier handling. 
> > Normally no
> > code path in non-PXA board is changed, so the test should be 
> > straightforward.
> > 
> > It's also available in : https://lkml.org/lkml/2015/11/30/768
> > 
> > You're the maintainers of the following boards using smc911x AFAIK:
> >  - sh2007: Guennadi and Hitoshi
> 
> (I noticed my previous mail was bounced, so sending it again)
> 
> Really sorry, currently I don't have the board :(
> Do you have a working board that can be used for testing, Guennadi?

Don't think I have anything, that I could use for testing with a 
reasonable effort.

Thanks
Guennadi

> 
> Thanks,
> Hitoshi
> 
> >  - armadillo5x0: Alberto
> >  - imx v6 and imx v7: Fabio
> > 
> > Cheers.
> > 
> > -- 
> > Robert
> > 
> > 
> > ---8<---
> > From: Robert Jarzmik 
> > Subject: [PATCH] net: smc911x: convert pxa dma to dmaengine
> > To: "David S. Miller" 
> > Cc: net...@vger.kernel.org, linux-kernel@vger.kernel.org, Robert Jarzmik 
> > 
> > Date: Mon, 30 Nov 2015 22:40:28 +0100 (9 weeks, 4 days, 11 hours ago)
> > Message-Id: <1448919628-13273-1-git-send-email-robert.jarz...@free.fr>
> > X-Mailer: git-send-email 2.1.4
> > 
> > Convert the dma transfers to be dmaengine based, now pxa has a dmaengine
> > slave driver. This makes this driver a bit more PXA agnostic.
> > 
> > The driver was only compile tested. The risk is quite small as no
> > current PXA platform I'm aware of is using smc911x driver.
> > 
> > Signed-off-by: Robert Jarzmik 
> > ---
> >  drivers/net/ethernet/smsc/smc911x.c | 85 
> > -
> >  drivers/net/ethernet/smsc/smc911x.h | 63 ---
> >  2 files changed, 82 insertions(+), 66 deletions(-)
> > 
> > diff --git a/drivers/net/ethernet/smsc/smc911x.c 
> > b/drivers/net/ethernet/smsc/smc911x.c
> > index bd64eb982e52..3f5711061432 100644
> > --- a/drivers/net/ethernet/smsc/smc911x.c
> > +++ b/drivers/net/ethernet/smsc/smc911x.c
> > @@ -73,6 +73,9 @@ static const char version[] =
> >  #include 
> >  #include 
> >  
> > +#include 
> > +#include 
> > +
> >  #include 
> >  
> >  #include "smc911x.h"
> > @@ -1174,18 +1177,16 @@ static irqreturn_t smc911x_interrupt(int irq, void 
> > *dev_id)
> >  
> >  #ifdef SMC_USE_DMA
> >  static void
> > -smc911x_tx_dma_irq(int dma, void *data)
> > +smc911x_tx_dma_irq(void *data)
> >  {
> > -   struct net_device *dev = (struct net_device *)data;
> > -   struct smc911x_local *lp = netdev_priv(dev);
> > +   struct smc911x_local *lp = data;
> > +   struct net_device *dev = lp->netdev;
> > struct sk_buff *skb = lp->current_tx_skb;
> > unsigned long flags;
> >  
> > DBG(SMC_DEBUG_FUNC, dev, "--> %s\n", __func__);
> >  
> > DBG(SMC_DEBUG_TX | SMC_DEBUG_DMA, dev, "TX DMA irq handler\n");
> > -   /* Clear the DMA interrupt sources */
> > -   SMC_DMA_ACK_IRQ(dev, dma);
> > BUG_ON(skb == NULL);
> > dma_unmap_single(NULL, tx_dmabuf, tx_dmalen, DMA_TO_DEVICE);
> > dev->trans_start = jiffies;
> > @@ -1208,18 +1209,16 @@ smc911x_tx_dma_irq(int dma, void *data)
> > "TX DMA irq completed\n");
> >  }
> >  static void
> > -smc911x_rx_dma_irq(int dma, void *data)
> > +smc911x_rx_dma_irq(void *data)
> >  {
> > -   struct net_device *dev = (struct net_device *)data;
> > -   struct smc911x_local *lp = netdev_priv(dev);
> > +   struct smc911x_local *lp = data;
> > +   struct net_device *dev = lp->netdev;
> > struct sk_buff *skb = lp->current_rx_skb;
> > unsigned long flags;
> > unsigned int pkts;
> >  
> > DBG(SMC_DEBUG_FUNC, dev, "--> %s\n", __func__);
> > DBG(SMC_DEBUG_RX | SMC_DEBUG_DMA, dev, "RX DMA irq handler\n");
> > -   /* Clear the DMA interrupt sources */
> > -   SMC_DMA_ACK_IRQ(dev, dma);
> > dma_unmap_single(NULL, rx_dmabuf, rx_dmalen, DMA_FROM_DEVICE);
> > BUG_ON(skb == NULL);
> > lp->current_rx_skb = NULL;
> > @@ -1792,6 +1791,9 @@ static int smc911x_probe(struct net_device *dev)
> > unsigned int val, chip_id, revision;
> > const char *version_string;
> > unsigned long irq_flags;
> > +   struct dma_slave_config config;
> > +   dma_cap_mask_t mask;
> > +   struct pxad_param param;
> >  
> > DBG(SMC_DEBUG_FUNC, dev, "--> %s\n", __func__);
> >  
> > @@ -1963,11 +1965

Re: [PATCH] [media] mx3_camera: use %pad format string for dma_ddr_t

2016-02-07 Thread Guennadi Liakhovetski
Hi Arnd,

On Mon, 1 Feb 2016, Arnd Bergmann wrote:

> The mx3_camera driver prints DMA addresses using the "%x" format
> string, which is wrong when using a 64-bit dma_addr_t definition:
> 
> media/platform/soc_camera/mx3_camera.c: In function 'mx3_cam_dma_done':
> media/platform/soc_camera/mx3_camera.c:149:125: error: format '%x' expects 
> argument of type 'unsigned int', but argument 5 has type 'dma_addr_t {aka 
> long long unsigned int}' [-Werror=format=]
> media/platform/soc_camera/mx3_camera.c: In function 'mx3_videobuf_queue':
> media/platform/soc_camera/mx3_camera.c:317:119: error: format '%x' expects 
> argument of type 'unsigned int', but argument 5 has type 'dma_addr_t {aka 
> long long unsigned int}' [-Werror=format=]
> media/platform/soc_camera/mx3_camera.c: In function 'mx3_videobuf_release':
> media/platform/soc_camera/mx3_camera.c:346:119: error: format '%x' expects 
> argument of type 'unsigned int', but argument 5 has type 'dma_addr_t {aka 
> long long unsigned int}' [-Werror=format=]
> 
> This changes the code to use the special %pad format string, which
> always does the right thing.
> 
> Signed-off-by: Arnd Bergmann 

Thanks for the patch. I'll queue it for 4.6.

Guennadi

> ---
> Another old bug that only rarely shows up in ARM randconfigs.
> 
> diff --git a/drivers/media/platform/soc_camera/mx3_camera.c 
> b/drivers/media/platform/soc_camera/mx3_camera.c
> index 169ed1150226..aa39e9569b1a 100644
> --- a/drivers/media/platform/soc_camera/mx3_camera.c
> +++ b/drivers/media/platform/soc_camera/mx3_camera.c
> @@ -146,8 +146,8 @@ static void mx3_cam_dma_done(void *arg)
>   struct idmac_channel *ichannel = to_idmac_chan(chan);
>   struct mx3_camera_dev *mx3_cam = ichannel->client;
>  
> - dev_dbg(chan->device->dev, "callback cookie %d, active DMA 0x%08x\n",
> - desc->txd.cookie, mx3_cam->active ? 
> sg_dma_address(&mx3_cam->active->sg) : 0);
> + dev_dbg(chan->device->dev, "callback cookie %d, active DMA %pad\n",
> + desc->txd.cookie, mx3_cam->active ? 
> &sg_dma_address(&mx3_cam->active->sg) : NULL);
>  
>   spin_lock(&mx3_cam->lock);
>   if (mx3_cam->active) {
> @@ -314,8 +314,8 @@ static void mx3_videobuf_queue(struct vb2_buffer *vb)
>   spin_unlock_irq(&mx3_cam->lock);
>  
>   cookie = txd->tx_submit(txd);
> - dev_dbg(icd->parent, "Submitted cookie %d DMA 0x%08x\n",
> - cookie, sg_dma_address(&buf->sg));
> + dev_dbg(icd->parent, "Submitted cookie %d DMA %pad\n",
> + cookie, &sg_dma_address(&buf->sg));
>  
>   if (cookie >= 0)
>   return;
> @@ -344,8 +344,8 @@ static void mx3_videobuf_release(struct vb2_buffer *vb)
>   unsigned long flags;
>  
>   dev_dbg(icd->parent,
> - "Release%s DMA 0x%08x, queue %sempty\n",
> - mx3_cam->active == buf ? " active" : "", 
> sg_dma_address(&buf->sg),
> + "Release%s DMA %pad, queue %sempty\n",
> + mx3_cam->active == buf ? " active" : "", 
> &sg_dma_address(&buf->sg),
>   list_empty(&buf->queue) ? "" : "not ");
>  
>   spin_lock_irqsave(&mx3_cam->lock, flags);
> 


Re: [PATCH v5 1/4] media: pxa_camera: fix the buffer free path

2015-10-29 Thread Guennadi Liakhovetski
Hi Robert,

On Tue, 27 Oct 2015, Robert Jarzmik wrote:

> Guennadi Liakhovetski  writes:
> 
> > Hi Robert,
> >
> > Didn't you tell me, that your dmaengine patch got rejected and therefore 
> > these your patches were on hold?
> They were reverted, and then revamped into DMA_CTRL_REUSE, upstreamed and
> merged, as in the commit 272420214d26 ("dmaengine: Add DMA_CTRL_REUSE"). I'd
> 
> Of course a pending fix is still underway
> (http://www.serverphorums.com/read.php?12,1318680). But that shouldn't stop us
> from reviewing to get ready to merge.
> 
> I want this serie to be ready, so that as soon as Vinod merges the fix, I can
> ping you to trigger the merge into your tree, without doing (and waiting)
> additional review cycles.

Thanks, understand now. As we discussed before, correct me if I am wrong, 
this is your hobby project. PXA270 is a legacy platform, nobody except you 
is interested in this work. I have nothing against hobby projects and I 
want to support them as much as I can, but I hope you'll understand, that 
I don't have too much free time, so I cannot handle such projects with a 
high priority. I understand your desire to process these patches ASAP, 
however, I'd like to try to minimise my work too. So, I can propose the 
following: let us wait, until your PXA dmaengine patches are _indeed_ in 
the mainline. Then you test your camera patches on top of that tree again, 
perform any eventually necessary updates and either let me know, that 
either your last version is ok and I can now review it, or submit a new 
version, that _works_ on top of then current tree.

Thanks
Guennadi

> Cheers.
> 
> --
> Robert
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v5 1/4] media: pxa_camera: fix the buffer free path

2015-10-27 Thread Guennadi Liakhovetski
Hi Robert,

Didn't you tell me, that your dmaengine patch got rejected and therefore 
these your patches were on hold?

Thanks
Guennadi

On Sat, 24 Oct 2015, Robert Jarzmik wrote:

> Robert Jarzmik  writes:
> 
> > Fix the error path where the video buffer wasn't allocated nor
> > mapped. In this case, in the driver free path don't try to unmap memory
> > which was not mapped in the first place.
> >
> > Signed-off-by: Robert Jarzmik 
> > ---
> > Since v3: take into account the 2 paths possibilities to free_buffer()
> Okay Guennadi, it's been enough time.
> Could you you have another look at this serie please ?
> 
> Cheers.
> 
> --
> Robert
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] [media] soc_camera: soc_camera_pdrv_probe: fix potential NULL pointer dereference

2015-09-16 Thread Guennadi Liakhovetski
On Wed, 16 Sep 2015, Wang YanQing wrote:

> Move dereference of sdesc after NULL pointer checker.
> 
> Signed-off-by: Wang YanQing 
> ---
>  drivers/media/platform/soc_camera/soc_camera.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/media/platform/soc_camera/soc_camera.c 
> b/drivers/media/platform/soc_camera/soc_camera.c
> index 9087fed..53b153d 100644
> --- a/drivers/media/platform/soc_camera/soc_camera.c
> +++ b/drivers/media/platform/soc_camera/soc_camera.c
> @@ -2187,13 +2187,14 @@ static int soc_camera_video_start(struct 
> soc_camera_device *icd)
>  static int soc_camera_pdrv_probe(struct platform_device *pdev)
>  {
>   struct soc_camera_desc *sdesc = pdev->dev.platform_data;
> - struct soc_camera_subdev_desc *ssdd = &sdesc->subdev_desc;
> + struct soc_camera_subdev_desc *ssdd;

NAK. This isn't a dereference. This is just an address calculation.

Thanks
Guennadi

>   struct soc_camera_device *icd;
>   int ret;
>  
>   if (!sdesc)
>   return -EINVAL;
>  
> + ssdd = &sdesc->subdev_desc;
>   icd = devm_kzalloc(&pdev->dev, sizeof(*icd), GFP_KERNEL);
>   if (!icd)
>   return -ENOMEM;
> -- 
> 1.8.5.6.2.g3d8a54e.dirty
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] media: soc-camera: increase the length of clk_name on soc_of_bind()

2015-08-30 Thread Guennadi Liakhovetski
Hi Josh,

Sorry, I missed the 4.3 merge cycle, but isn't this patch a fix? Isn't it 
fixing soc-camera / atmel-isi on a specific platform, where the clock name 
is longer, than currently supported? Is this platform in the mainline and 
its current camera support is broken because of this? In such a case we 
could still push it in for 4.3

Thanks
Guennadi

On Tue, 4 Aug 2015, Josh Wu wrote:

> Since in soc_of_bind() it may use the of node's full name as the clk_name,
> and this full name may be longer than 32 characters, take at91 i2c sensor
> as an example, length is 34 bytes:
>/ahb/apb/i2c@f8028000/camera@0x30
> 
> So this patch increase the clk_name[] array size to 64. It seems big
> enough so far.
> 
> Signed-off-by: Josh Wu 
> ---
> 
>  drivers/media/platform/soc_camera/soc_camera.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/media/platform/soc_camera/soc_camera.c 
> b/drivers/media/platform/soc_camera/soc_camera.c
> index d708df4..fcf3e97 100644
> --- a/drivers/media/platform/soc_camera/soc_camera.c
> +++ b/drivers/media/platform/soc_camera/soc_camera.c
> @@ -1621,7 +1621,7 @@ static int soc_of_bind(struct soc_camera_host *ici,
>   struct soc_camera_async_client *sasc;
>   struct soc_of_info *info;
>   struct i2c_client *client;
> - char clk_name[V4L2_SUBDEV_NAME_SIZE];
> + char clk_name[V4L2_SUBDEV_NAME_SIZE + 32];
>   int ret;
>  
>   /* allocate a new subdev and add match info to it */
> -- 
> 1.9.1
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v3 4/4] media: pxa_camera: conversion to dmaengine

2015-08-30 Thread Guennadi Liakhovetski
Hi Robert,

I assume, the next iteration of your patches won't contain a local copy of 
the SG splitting code.

On Wed, 29 Jul 2015, Robert Jarzmik wrote:

> Convert pxa_camera to dmaengine. This removes all DMA registers
> manipulation in favor of the more generic dmaengine API.
> 
> The functional level should be the same as before. The biggest change is
> in the videobuf_sg_splice() function, which splits a videobuf-dma into
> several scatterlists for 3 planes captures (Y, U, V).
> 
> Signed-off-by: Robert Jarzmik 
> ---
> Since v1: Guennadi's fixes
>   dma tasklet functions prototypes change (trivial move)
> Since v2: sglist cut revamped with Guennadi's comments
> ---
>  drivers/media/platform/soc_camera/pxa_camera.c | 492 
> ++---
>  1 file changed, 267 insertions(+), 225 deletions(-)
> 
> diff --git a/drivers/media/platform/soc_camera/pxa_camera.c 
> b/drivers/media/platform/soc_camera/pxa_camera.c
> index cdfb93aaee43..030ed7413bba 100644
> --- a/drivers/media/platform/soc_camera/pxa_camera.c
> +++ b/drivers/media/platform/soc_camera/pxa_camera.c

[snip]

> @@ -806,28 +824,41 @@ static void pxa_camera_dma_irq(int channel, struct 
> pxa_camera_dev *pcdev,
>   buf = container_of(vb, struct pxa_buffer, vb);
>   WARN_ON(buf->inwork || list_empty(&vb->queue));
>  
> - dev_dbg(dev, "%s channel=%d %s%s(vb=0x%p) dma.desc=%x\n",
> - __func__, channel, status & DCSR_STARTINTR ? "SOF " : "",
> - status & DCSR_ENDINTR ? "EOF " : "", vb, DDADR(channel));
> -
> - if (status & DCSR_ENDINTR) {
> - /*
> -  * It's normal if the last frame creates an overrun, as there
> -  * are no more DMA descriptors to fetch from QCI fifos
> -  */
> - if (camera_status & overrun &&
> - !list_is_last(pcdev->capture.next, &pcdev->capture)) {
> - dev_dbg(dev, "FIFO overrun! CISR: %x\n",
> - camera_status);
> - pxa_camera_stop_capture(pcdev);
> - pxa_camera_start_capture(pcdev);
> - goto out;
> - }
> - buf->active_dma &= ~act_dma;
> - if (!buf->active_dma) {
> - pxa_camera_wakeup(pcdev, vb, buf);
> - pxa_camera_check_link_miss(pcdev);
> - }
> + /*
> +  * It's normal if the last frame creates an overrun, as there
> +  * are no more DMA descriptors to fetch from QCI fifos
> +  */
> + switch (act_dma) {
> + case DMA_U:
> + chan = 1;
> + break;
> + case DMA_V:
> + chan = 2;
> + break;
> + default:
> + chan = 0;
> + break;
> + }
> + last_buf = list_entry(pcdev->capture.prev,
> +   struct pxa_buffer, vb.queue);

You can use list_last_entry()

> + last_status = dma_async_is_tx_complete(pcdev->dma_chans[chan],
> +last_buf->cookie[chan],
> +NULL, &last_issued);
> + if (camera_status & overrun &&
> + last_status != DMA_COMPLETE) {
> + dev_dbg(dev, "FIFO overrun! CISR: %x\n",
> + camera_status);
> + pxa_camera_stop_capture(pcdev);
> + list_for_each_entry(buf, &pcdev->capture, vb.queue)
> + pxa_dma_add_tail_buf(pcdev, buf);

Why have you added this loop? Is it a bug in the current implementation or 
is it only needed with the switch to dmaengine?

> + pxa_camera_start_capture(pcdev);
> + goto out;
> + }
> + buf->active_dma &= ~act_dma;
> + if (!buf->active_dma) {
> + pxa_camera_wakeup(pcdev, vb, buf);
> + pxa_camera_check_link_miss(pcdev, last_buf->cookie[chan],
> +last_issued);
>   }
>  
>  out:
> @@ -1014,10 +1045,7 @@ static void pxa_camera_clock_stop(struct 
> soc_camera_host *ici)
>   __raw_writel(0x3ff, pcdev->base + CICR0);
>  
>   /* Stop DMA engine */
> - DCSR(pcdev->dma_chans[0]) = 0;
> - DCSR(pcdev->dma_chans[1]) = 0;
> - DCSR(pcdev->dma_chans[2]) = 0;
> -
> + pxa_dma_stop_channels(pcdev);
>   pxa_camera_deactivate(pcdev);
>  }
>  
> 

Thanks
Guennadi
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v3 3/4] media: pxa_camera: trivial move of dma irq functions

2015-08-30 Thread Guennadi Liakhovetski
On Wed, 29 Jul 2015, Robert Jarzmik wrote:

> From: Robert Jarzmik 
> 
> This moves the dma irq handling functions up in the source file, so that
> they are available before DMA preparation functions. It prepares the
> conversion to DMA engine, where the descriptors are populated with these
> functions as callbacks.
> 
> Signed-off-by: Robert Jarzmik 
> ---
> Since v1: fixed prototypes change
> ---
>  drivers/media/platform/soc_camera/pxa_camera.c | 42 
> +++---
>  1 file changed, 24 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/media/platform/soc_camera/pxa_camera.c 
> b/drivers/media/platform/soc_camera/pxa_camera.c
> index 39c7e7519b3c..cdfb93aaee43 100644
> --- a/drivers/media/platform/soc_camera/pxa_camera.c
> +++ b/drivers/media/platform/soc_camera/pxa_camera.c
> @@ -313,6 +313,30 @@ static int calculate_dma_sglen(struct scatterlist 
> *sglist, int sglen,

[snip]

> + pxa_camera_dma_irq(pcdev, DMA_Y);

[snip]

> - pxa_camera_dma_irq(channel, pcdev, DMA_Y);

This still seems to break compilation to me. Could you compile-test after 
each your patch, please?

Thanks
Guennadi
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 2/2] media: atmel-isi: move configure_geometry() to start_streaming()

2015-08-30 Thread Guennadi Liakhovetski
Yep, I see the thread and updates to this patch now, please, ignore this 
mail, sorry.

Thanks
Guennadi

On Sun, 30 Aug 2015, Guennadi Liakhovetski wrote:

> Hi Josh,
> 
> On Wed, 17 Jun 2015, Josh Wu wrote:
> 
> > As in set_fmt() function we only need to know which format is been set,
> > we don't need to access the ISI hardware in this moment.
> > 
> > So move the configure_geometry(), which access the ISI hardware, to
> > start_streaming() will make code more consistent and simpler.
> > 
> > Signed-off-by: Josh Wu 
> > ---
> > 
> >  drivers/media/platform/soc_camera/atmel-isi.c | 17 +
> >  1 file changed, 5 insertions(+), 12 deletions(-)
> > 
> > diff --git a/drivers/media/platform/soc_camera/atmel-isi.c 
> > b/drivers/media/platform/soc_camera/atmel-isi.c
> > index 8bc40ca..b01086d 100644
> > --- a/drivers/media/platform/soc_camera/atmel-isi.c
> > +++ b/drivers/media/platform/soc_camera/atmel-isi.c
> > @@ -390,6 +390,11 @@ static int start_streaming(struct vb2_queue *vq, 
> > unsigned int count)
> > /* Disable all interrupts */
> > isi_writel(isi, ISI_INTDIS, (u32)~0UL);
> >  
> > +   ret = configure_geometry(isi, icd->user_width, icd->user_height,
> > +   icd->current_fmt->code);
> > +   if (ret < 0)
> > +   return ret;
> 
> No. Firstly, you'd have to pm_runtime_put() here if you fail. Secondly I 
> think it's better to fail earlier - at S_FMT, than here. Not accessing the 
> hardware in S_FMT is a good idea, but I'd at least do all the checking 
> there. So, maybe add a "u32 cfg2_cr" field to struct atmel_isi, calculate 
> it in S_FMT but only write to the hardware in start_streaming()?
> 
> Thanks
> Guennadi
> 
> > +
> > spin_lock_irq(&isi->lock);
> > /* Clear any pending interrupt */
> > isi_readl(isi, ISI_STATUS);
> > @@ -477,8 +482,6 @@ static int isi_camera_init_videobuf(struct vb2_queue *q,
> >  static int isi_camera_set_fmt(struct soc_camera_device *icd,
> >   struct v4l2_format *f)
> >  {
> > -   struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
> > -   struct atmel_isi *isi = ici->priv;
> > struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
> > const struct soc_camera_format_xlate *xlate;
> > struct v4l2_pix_format *pix = &f->fmt.pix;
> > @@ -511,16 +514,6 @@ static int isi_camera_set_fmt(struct soc_camera_device 
> > *icd,
> > if (mf->code != xlate->code)
> > return -EINVAL;
> >  
> > -   /* Enable PM and peripheral clock before operate isi registers */
> > -   pm_runtime_get_sync(ici->v4l2_dev.dev);
> > -
> > -   ret = configure_geometry(isi, pix->width, pix->height, xlate->code);
> > -
> > -   pm_runtime_put(ici->v4l2_dev.dev);
> > -
> > -   if (ret < 0)
> > -   return ret;
> > -
> > pix->width  = mf->width;
> > pix->height = mf->height;
> > pix->field  = mf->field;
> > -- 
> > 1.9.1
> > 
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 2/2] media: atmel-isi: move configure_geometry() to start_streaming()

2015-08-30 Thread Guennadi Liakhovetski
Hi Josh,

On Wed, 17 Jun 2015, Josh Wu wrote:

> As in set_fmt() function we only need to know which format is been set,
> we don't need to access the ISI hardware in this moment.
> 
> So move the configure_geometry(), which access the ISI hardware, to
> start_streaming() will make code more consistent and simpler.
> 
> Signed-off-by: Josh Wu 
> ---
> 
>  drivers/media/platform/soc_camera/atmel-isi.c | 17 +
>  1 file changed, 5 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/media/platform/soc_camera/atmel-isi.c 
> b/drivers/media/platform/soc_camera/atmel-isi.c
> index 8bc40ca..b01086d 100644
> --- a/drivers/media/platform/soc_camera/atmel-isi.c
> +++ b/drivers/media/platform/soc_camera/atmel-isi.c
> @@ -390,6 +390,11 @@ static int start_streaming(struct vb2_queue *vq, 
> unsigned int count)
>   /* Disable all interrupts */
>   isi_writel(isi, ISI_INTDIS, (u32)~0UL);
>  
> + ret = configure_geometry(isi, icd->user_width, icd->user_height,
> + icd->current_fmt->code);
> + if (ret < 0)
> + return ret;

No. Firstly, you'd have to pm_runtime_put() here if you fail. Secondly I 
think it's better to fail earlier - at S_FMT, than here. Not accessing the 
hardware in S_FMT is a good idea, but I'd at least do all the checking 
there. So, maybe add a "u32 cfg2_cr" field to struct atmel_isi, calculate 
it in S_FMT but only write to the hardware in start_streaming()?

Thanks
Guennadi

> +
>   spin_lock_irq(&isi->lock);
>   /* Clear any pending interrupt */
>   isi_readl(isi, ISI_STATUS);
> @@ -477,8 +482,6 @@ static int isi_camera_init_videobuf(struct vb2_queue *q,
>  static int isi_camera_set_fmt(struct soc_camera_device *icd,
> struct v4l2_format *f)
>  {
> - struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
> - struct atmel_isi *isi = ici->priv;
>   struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
>   const struct soc_camera_format_xlate *xlate;
>   struct v4l2_pix_format *pix = &f->fmt.pix;
> @@ -511,16 +514,6 @@ static int isi_camera_set_fmt(struct soc_camera_device 
> *icd,
>   if (mf->code != xlate->code)
>   return -EINVAL;
>  
> - /* Enable PM and peripheral clock before operate isi registers */
> - pm_runtime_get_sync(ici->v4l2_dev.dev);
> -
> - ret = configure_geometry(isi, pix->width, pix->height, xlate->code);
> -
> - pm_runtime_put(ici->v4l2_dev.dev);
> -
> - if (ret < 0)
> - return ret;
> -
>   pix->width  = mf->width;
>   pix->height = mf->height;
>   pix->field  = mf->field;
> -- 
> 1.9.1
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/2] media: atmel-isi: setup the ISI_CFG2 register directly

2015-08-30 Thread Guennadi Liakhovetski
Hi Josh,

On Wed, 17 Jun 2015, Josh Wu wrote:

> In the function configure_geometry(), we will setup the ISI CFG2
> according to the sensor output format.
> 
> It make no sense to just read back the CFG2 register and just set part
> of it.
> 
> So just set up this register directly makes things simpler.

Simpler doesn't necessarily mean better or more correct:) There are other 
fields in that register and currently the driver preserves them, with this 
patch you overwrite them with 0. 0 happens to be the reset value of that 
register. So, you should at least mention that in this patch description, 
just saying "simpler" doesn't convince me. So, at least I'd modify that, I 
can do that myself. But in general I'm not even sure why this patch is 
needed. Yes, currently those fields of that register are unused, so, we 
can assume they stay at their reset values. But firstly the hardware can 
change and at some point the reset value can change, or those other fields 
will get set indirectly by something. Or the driver will change at some 
point to support more fields of that register and then this code will have 
to be changed again. So, I'd ask you again - do you really want this 
patch? If you insist - I'll take it, but I'd add the "reset value" 
reasoning. Otherwise maybe just drop it?

Thanks
Guennadi

> Currently only support YUV format from camera sensor.
> 
> Signed-off-by: Josh Wu 
> ---
> 
>  drivers/media/platform/soc_camera/atmel-isi.c | 20 +++-
>  1 file changed, 7 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/media/platform/soc_camera/atmel-isi.c 
> b/drivers/media/platform/soc_camera/atmel-isi.c
> index 9070172..8bc40ca 100644
> --- a/drivers/media/platform/soc_camera/atmel-isi.c
> +++ b/drivers/media/platform/soc_camera/atmel-isi.c
> @@ -105,24 +105,25 @@ static u32 isi_readl(struct atmel_isi *isi, u32 reg)
>  static int configure_geometry(struct atmel_isi *isi, u32 width,
>   u32 height, u32 code)
>  {
> - u32 cfg2, cr;
> + u32 cfg2;
>  
> + /* According to sensor's output format to set cfg2 */
>   switch (code) {
>   /* YUV, including grey */
>   case MEDIA_BUS_FMT_Y8_1X8:
> - cr = ISI_CFG2_GRAYSCALE;
> + cfg2 = ISI_CFG2_GRAYSCALE;
>   break;
>   case MEDIA_BUS_FMT_VYUY8_2X8:
> - cr = ISI_CFG2_YCC_SWAP_MODE_3;
> + cfg2 = ISI_CFG2_YCC_SWAP_MODE_3;
>   break;
>   case MEDIA_BUS_FMT_UYVY8_2X8:
> - cr = ISI_CFG2_YCC_SWAP_MODE_2;
> + cfg2 = ISI_CFG2_YCC_SWAP_MODE_2;
>   break;
>   case MEDIA_BUS_FMT_YVYU8_2X8:
> - cr = ISI_CFG2_YCC_SWAP_MODE_1;
> + cfg2 = ISI_CFG2_YCC_SWAP_MODE_1;
>   break;
>   case MEDIA_BUS_FMT_YUYV8_2X8:
> - cr = ISI_CFG2_YCC_SWAP_DEFAULT;
> + cfg2 = ISI_CFG2_YCC_SWAP_DEFAULT;
>   break;
>   /* RGB, TODO */
>   default:
> @@ -130,17 +131,10 @@ static int configure_geometry(struct atmel_isi *isi, 
> u32 width,
>   }
>  
>   isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS);
> -
> - cfg2 = isi_readl(isi, ISI_CFG2);
> - /* Set YCC swap mode */
> - cfg2 &= ~ISI_CFG2_YCC_SWAP_MODE_MASK;
> - cfg2 |= cr;
>   /* Set width */
> - cfg2 &= ~(ISI_CFG2_IM_HSIZE_MASK);
>   cfg2 |= ((width - 1) << ISI_CFG2_IM_HSIZE_OFFSET) &
>   ISI_CFG2_IM_HSIZE_MASK;
>   /* Set height */
> - cfg2 &= ~(ISI_CFG2_IM_VSIZE_MASK);
>   cfg2 |= ((height - 1) << ISI_CFG2_IM_VSIZE_OFFSET)
>   & ISI_CFG2_IM_VSIZE_MASK;
>   isi_writel(isi, ISI_CFG2, cfg2);
> -- 
> 1.9.1
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 4/4] media: pxa_camera: conversion to dmaengine

2015-07-26 Thread Guennadi Liakhovetski
Hi Robert,

On Sun, 19 Jul 2015, Robert Jarzmik wrote:

> Robert Jarzmik  writes:
> 
> > Guennadi Liakhovetski  writes:
> >
> >>>   /* init DMA for Y channel */
> >>
> >> How about taking the loop over the sg list out of pxa_init_dma_channel() 
> >> to avoid having to iterate it from the beginning each time? Then you would 
> >> be able to split it into channels inside that global loop? Would that 
> >> work? Of course you might need to rearrange functions to avoid too deep 
> >> code nesting.
> >
> > Ok, will try that.
> > The more I think of it, the more it looks to me like a generic thing : take 
> > an
> > sglist, and an array of sizes, and split the sglist into several sglists, 
> > each
> > of the defined size in the array.
> >
> > Or more code-like speaking :
> >   - sglist_split(struct scatterlist *sg_int, size_t *sizes, int nb_sizes,
> >  struct scatterlist **sg_out)
> >   - and sg_out is an array of nb_sizes (struct scatterlist *sg)
> >
> > So I will try that out. Maybe if that works out for pxa_camera, Jens or 
> > Russell
> > would accept that into lib/scatterlist.c.
> Ok, I made the code ... and I hate it.
> It's in [1], which is an incremental patch over patch 4/4.

It would've been easier to review, if it were on top of the mainline, 
resp. your patches 1-3 from this series.

> If that's what you had in mind, tell me.

In principle, yes, it doesn't look all that horrible to me. You first 
split the global SG list into up to 3 per-channel ones, then you 
initialise your channels, what's wrong with that? Just have to add some 
polish to it here and there... This is a preliminary review, I'll do a 
proper one, once you fix these and send me anew version, not based on top 
of patch 4/4.

> Cheers.
> 
> --
> Robert
> 
> [1] The despised patch
> ---<8---
> commit 43bbb9a4e3ac
> Author: Robert Jarzmik 
> Date:   Tue Jul 14 20:17:51 2015 +0200
> 
> tmp: pxa_camera: working on sg_split
> 
> Signed-off-by: Robert Jarzmik 
> 
> diff --git a/drivers/media/platform/soc_camera/pxa_camera.c 
> b/drivers/media/platform/soc_camera/pxa_camera.c
> index 26a66b9ff570..83efd284e976 100644
> --- a/drivers/media/platform/soc_camera/pxa_camera.c
> +++ b/drivers/media/platform/soc_camera/pxa_camera.c
> @@ -287,64 +287,110 @@ static void free_buffer(struct videobuf_queue *vq, 
> struct pxa_buffer *buf)
>   &buf->vb, buf->vb.baddr, buf->vb.bsize);
>  }
>  
> -static struct scatterlist *videobuf_sg_cut(struct scatterlist *sglist,
> -int sglen, int offset, int size,
> -int *new_sg_len)
> +
> +struct sg_splitter {
> + struct scatterlist *in_sg0;
> + int nents;
> + off_t skip_sg0;
> + size_t len_last_sg;
> + struct scatterlist *out_sg;
> +};
> +
> +static struct sg_splitter *
> +sg_calculate_split(struct scatterlist *in, off_t skip,

You don't need "skip," you only call this function once with skip == 0. 
Besides I usually prefer all the keywords before the function name, the 
function name, the opening parenthesis and at least the first argument on 
the same line. So far pxa_camera.c follows this, let's keep it this way. 
It makes grepping for functions easier. And no, I don't care about 80 
chars...

> +const size_t *sizes, int nb_splits, gfp_t gfp_mask)
>  {
> - struct scatterlist *sg0, *sg, *sg_first = NULL;
> - int i, dma_len, dropped_xfer_len, dropped_remain, remain;
> - int nfirst = -1, nfirst_offset = 0, xfer_len;
> -
> - *new_sg_len = 0;
> - dropped_remain = offset;
> - remain = size;
> - for_each_sg(sglist, sg, sglen, i) {
> - dma_len = sg_dma_len(sg);
> - /* PXA27x Developer's Manual 27.4.4.1: round up to 8 bytes */
> - dropped_xfer_len = roundup(min(dma_len, dropped_remain), 8);
> - if (dropped_remain)
> - dropped_remain -= dropped_xfer_len;
> - xfer_len = dma_len - dropped_xfer_len;
> -
> - if (nfirst < 0 && xfer_len > 0) {
> - sg_first = sg;
> - nfirst = i;
> - nfirst_offset = dropped_xfer_len;
> + int i, nents;
> + size_t size, len;
> + struct sg_splitter *splitters, *curr;
> + struct scatterlist *sg;
> +
> + splitters = kcalloc(nb_splits, sizeof(*splitters), gfp_mask);

This is an array of at most 3 elements, 20 bytes each. I'd just allocate 
it on stack in the 

Re: [PATCH v2 4/4] media: pxa_camera: conversion to dmaengine

2015-07-12 Thread Guennadi Liakhovetski
Hi Robert,

On Sun, 5 Jul 2015, Robert Jarzmik wrote:

> Convert pxa_camera to dmaengine. This removes all DMA registers
> manipulation in favor of the more generic dmaengine API.
> 
> The functional level should be the same as before. The biggest change is
> in the videobuf_sg_splice() function, which splits a videobuf-dma into
> several scatterlists for 3 planes captures (Y, U, V).
> 
> Signed-off-by: Robert Jarzmik 
> ---
> Since v1: Guennadi's fixes
>   dma tasklet functions prototypes change (trivial move)
> ---
>  drivers/media/platform/soc_camera/pxa_camera.c | 438 
> -
>  1 file changed, 215 insertions(+), 223 deletions(-)
> 
> diff --git a/drivers/media/platform/soc_camera/pxa_camera.c 
> b/drivers/media/platform/soc_camera/pxa_camera.c
> index 1ab4f9d..76b2b7b 100644
> --- a/drivers/media/platform/soc_camera/pxa_camera.c
> +++ b/drivers/media/platform/soc_camera/pxa_camera.c

[snip]

> @@ -498,9 +499,7 @@ static int pxa_videobuf_prepare(struct videobuf_queue *vq,
>  
>   if (vb->state == VIDEOBUF_NEEDS_INIT) {
>   int size = vb->size;
> - int next_ofs = 0;
>   struct videobuf_dmabuf *dma = videobuf_to_dma(vb);
> - struct scatterlist *sg;
>  
>   ret = videobuf_iolock(vq, vb, NULL);
>   if (ret)
> @@ -513,11 +512,9 @@ static int pxa_videobuf_prepare(struct videobuf_queue 
> *vq,
>   size_y = size;
>   }
>  
> - sg = dma->sglist;
> -
>   /* init DMA for Y channel */

How about taking the loop over the sg list out of pxa_init_dma_channel() 
to avoid having to iterate it from the beginning each time? Then you would 
be able to split it into channels inside that global loop? Would that 
work? Of course you might need to rearrange functions to avoid too deep 
code nesting.

Thanks
Guennadi

> - ret = pxa_init_dma_channel(pcdev, buf, dma, 0, CIBR0, size_y,
> -&sg, &next_ofs);
> + ret = pxa_init_dma_channel(pcdev, buf, dma, 0, CIBR0,
> +size_y, 0);
>   if (ret) {
>   dev_err(dev, "DMA initialization for Y/RGB failed\n");
>   goto fail;
> @@ -526,19 +523,19 @@ static int pxa_videobuf_prepare(struct videobuf_queue 
> *vq,
>   /* init DMA for U channel */
>   if (size_u)
>   ret = pxa_init_dma_channel(pcdev, buf, dma, 1, CIBR1,
> -size_u, &sg, &next_ofs);
> +size_u, size_y);
>   if (ret) {
>   dev_err(dev, "DMA initialization for U failed\n");
> - goto fail_u;
> + goto fail;
>   }
>  
>   /* init DMA for V channel */
>   if (size_v)
>   ret = pxa_init_dma_channel(pcdev, buf, dma, 2, CIBR2,
> -size_v, &sg, &next_ofs);
> +size_v, size_y + size_u);
>   if (ret) {
>   dev_err(dev, "DMA initialization for V failed\n");
> - goto fail_v;
> + goto fail;
>   }
>  
>   vb->state = VIDEOBUF_PREPARED;
> @@ -549,12 +546,6 @@ static int pxa_videobuf_prepare(struct videobuf_queue 
> *vq,
>  
>   return 0;
>  
> -fail_v:
> - dma_free_coherent(dev, buf->dmas[1].sg_size,
> -   buf->dmas[1].sg_cpu, buf->dmas[1].sg_dma);
> -fail_u:
> - dma_free_coherent(dev, buf->dmas[0].sg_size,
> -   buf->dmas[0].sg_cpu, buf->dmas[0].sg_dma);
>  fail:
>   free_buffer(vq, buf);
>  out:
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/4] media: pxa_camera: fix the buffer free path (fwd)

2015-07-12 Thread Guennadi Liakhovetski
Hi Robert,

No idea why this mail hasn't been delivered... Sorry, resending.

Thanks
Guennadi

-- Forwarded message --
Date: Sun, 31 May 2015 21:34:50 +0200 (CEST)
From: Guennadi Liakhovetski 
Subject: Re: [PATCH 1/4] media: pxa_camera: fix the buffer free path

Hi Robert,

Thanks for the patch.

On Sun, 22 Mar 2015, Robert Jarzmik wrote:

> From: Robert Jarzmik 

free_buffer() is called from two locations: from the .buf_release() 
callback and on the error path in .buf_prepare(). In the first case it 
does the complete freeing of the buffers and DMA channels, in the latter 
case the error path, including buffer freeing can _only_ be entered if 
buffer allocation has been attempted, i.e. buffer state is 
VIDEOBUF_NEEDS_INIT. Which is exactly the case you're catching below. 
Following your patch, in this case free_buffer() shouldn't be called at 
all, because videobuf_waiton() isn't needed either. That can be achieved 
easier:

 fail_u:
dma_free_coherent(dev, buf->dmas[0].sg_size,
  buf->dmas[0].sg_cpu, buf->dmas[0].sg_dma);
-fail:
-   free_buffer(vq, buf);
 out:
buf->inwork = 0;
return ret;

But tbh I don't understand why videobuf_dma_free() and 
videobuf_dma_unmap() shouldn't be called if videobuf_iolock() was 
successful, are you sure about that?

Thanks
Guennadi

> Fix the error path where the video buffer wasn't allocated nor
> mapped. In this case, in the driver free path don't try to unmap memory
> which was not mapped in the first place.
> 
> Signed-off-by: Robert Jarzmik 
> ---
>  drivers/media/platform/soc_camera/pxa_camera.c | 6 --
>  1 file changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/media/platform/soc_camera/pxa_camera.c 
> b/drivers/media/platform/soc_camera/pxa_camera.c
> index 8d6e343..3ca33f0 100644
> --- a/drivers/media/platform/soc_camera/pxa_camera.c
> +++ b/drivers/media/platform/soc_camera/pxa_camera.c
> @@ -272,8 +272,8 @@ static void free_buffer(struct videobuf_queue *vq, struct 
> pxa_buffer *buf)
>* longer in STATE_QUEUED or STATE_ACTIVE
>*/
>   videobuf_waiton(vq, &buf->vb, 0, 0);
> - videobuf_dma_unmap(vq->dev, dma);
> - videobuf_dma_free(dma);
> + if (buf->vb.state == VIDEOBUF_NEEDS_INIT)
> + return;
>  
>   for (i = 0; i < ARRAY_SIZE(buf->dmas); i++) {
>   if (buf->dmas[i].sg_cpu)
> @@ -283,6 +283,8 @@ static void free_buffer(struct videobuf_queue *vq, struct 
> pxa_buffer *buf)
> buf->dmas[i].sg_dma);
>   buf->dmas[i].sg_cpu = NULL;
>   }
> + videobuf_dma_unmap(vq->dev, dma);
> + videobuf_dma_free(dma);
>  
>   buf->vb.state = VIDEOBUF_NEEDS_INIT;
>  }
> -- 
> 2.1.4
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 3/4] media: pxa_camera: trivial move of dma irq functions

2015-07-12 Thread Guennadi Liakhovetski
On Sun, 5 Jul 2015, Robert Jarzmik wrote:

> From: Robert Jarzmik 
> 
> This moves the dma irq handling functions up in the source file, so that
> they are available before DMA preparation functions. It prepares the
> conversion to DMA engine, where the descriptors are populated with these
> functions as callbacks.
> 
> Signed-off-by: Robert Jarzmik 
> ---
> Since v1: fixed prototypes change
> ---
>  drivers/media/platform/soc_camera/pxa_camera.c | 40 
> ++
>  1 file changed, 22 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/media/platform/soc_camera/pxa_camera.c 
> b/drivers/media/platform/soc_camera/pxa_camera.c
> index c0c0f0f..1ab4f9d 100644
> --- a/drivers/media/platform/soc_camera/pxa_camera.c
> +++ b/drivers/media/platform/soc_camera/pxa_camera.c
> @@ -311,6 +311,28 @@ static int calculate_dma_sglen(struct scatterlist 
> *sglist, int sglen,
>  
>   BUG_ON(size != 0);
>   return i + 1;
> +static void pxa_camera_dma_irq(struct pxa_camera_dev *pcdev,
> +enum pxa_camera_active_dma act_dma);

Yes, functions look ok now as the sense - they are just moved up with no 
modifications, but the patch itself looks as broken to me as it originally 
was... Please, look 2 lines up - where you add your lines.

Thanks
Guennadi

> +
> +static void pxa_camera_dma_irq_y(int channel, void *data)
> +{
> + struct pxa_camera_dev *pcdev = data;
> +
> + pxa_camera_dma_irq(pcdev, DMA_Y);
> +}
> +
> +static void pxa_camera_dma_irq_u(int channel, void *data)
> +{
> + struct pxa_camera_dev *pcdev = data;
> +
> + pxa_camera_dma_irq(pcdev, DMA_U);
> +}
> +
> +static void pxa_camera_dma_irq_v(int channel, void *data)
> +{
> + struct pxa_camera_dev *pcdev = data;
> +
> + pxa_camera_dma_irq(pcdev, DMA_V);
>  }
>  
>  /**
> @@ -810,24 +832,6 @@ out:
>   spin_unlock_irqrestore(&pcdev->lock, flags);
>  }
>  
> -static void pxa_camera_dma_irq_y(int channel, void *data)
> -{
> - struct pxa_camera_dev *pcdev = data;
> - pxa_camera_dma_irq(channel, pcdev, DMA_Y);
> -}
> -
> -static void pxa_camera_dma_irq_u(int channel, void *data)
> -{
> - struct pxa_camera_dev *pcdev = data;
> - pxa_camera_dma_irq(channel, pcdev, DMA_U);
> -}
> -
> -static void pxa_camera_dma_irq_v(int channel, void *data)
> -{
> - struct pxa_camera_dev *pcdev = data;
> - pxa_camera_dma_irq(channel, pcdev, DMA_V);
> -}
> -
>  static struct videobuf_queue_ops pxa_videobuf_ops = {
>   .buf_setup  = pxa_videobuf_setup,
>   .buf_prepare= pxa_videobuf_prepare,
> -- 
> 2.1.4
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 1/4] media: pxa_camera: fix the buffer free path

2015-07-12 Thread Guennadi Liakhovetski
Hi Robert,

On Sun, 5 Jul 2015, Robert Jarzmik wrote:

> From: Robert Jarzmik 
> 
> Fix the error path where the video buffer wasn't allocated nor
> mapped. In this case, in the driver free path don't try to unmap memory
> which was not mapped in the first place.

Have I missed your reply to my comments to v1 of this patch? This one 
seems to be its exact copy?

Thanks
Guennadi

> 
> Signed-off-by: Robert Jarzmik 
> ---
>  drivers/media/platform/soc_camera/pxa_camera.c | 6 --
>  1 file changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/media/platform/soc_camera/pxa_camera.c 
> b/drivers/media/platform/soc_camera/pxa_camera.c
> index 8d6e343..3ca33f0 100644
> --- a/drivers/media/platform/soc_camera/pxa_camera.c
> +++ b/drivers/media/platform/soc_camera/pxa_camera.c
> @@ -272,8 +272,8 @@ static void free_buffer(struct videobuf_queue *vq, struct 
> pxa_buffer *buf)
>* longer in STATE_QUEUED or STATE_ACTIVE
>*/
>   videobuf_waiton(vq, &buf->vb, 0, 0);
> - videobuf_dma_unmap(vq->dev, dma);
> - videobuf_dma_free(dma);
> + if (buf->vb.state == VIDEOBUF_NEEDS_INIT)
> + return;
>  
>   for (i = 0; i < ARRAY_SIZE(buf->dmas); i++) {
>   if (buf->dmas[i].sg_cpu)
> @@ -283,6 +283,8 @@ static void free_buffer(struct videobuf_queue *vq, struct 
> pxa_buffer *buf)
> buf->dmas[i].sg_dma);
>   buf->dmas[i].sg_cpu = NULL;
>   }
> + videobuf_dma_unmap(vq->dev, dma);
> + videobuf_dma_free(dma);
>  
>   buf->vb.state = VIDEOBUF_NEEDS_INIT;
>  }
> -- 
> 2.1.4
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 3/4] media: pxa_camera: trivial move of dma irq functions

2015-06-21 Thread Guennadi Liakhovetski
On Sat, 20 Jun 2015, Robert Jarzmik wrote:

> Guennadi Liakhovetski  writes:
> 
> >> +static void pxa_camera_dma_irq(struct pxa_camera_dev *pcdev,
> >> + enum pxa_camera_active_dma act_dma);
> >> +
> >> +static void pxa_camera_dma_irq_y(void *data)
> >
> > Wait, how is this patch trivial? You change pxa_camera_dma_irq_?() 
> > prototypes, which are used as PXA DMA callbacks. Does this mean, that 
> > either before or after this patch compilation is broken?
> 
> Jeez you're right.
> So I can either fold that with patch 4, or try to rework it somehow ...

How about letting that patch do exactly what it says it does? Just move 
functions up in the file if you need them there, without changing them, 
and only change them when it's needed?

Thanks
Guennadi
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 4/4] media: pxa_camera: conversion to dmaengine

2015-06-21 Thread Guennadi Liakhovetski
Hi Robert,

On Sun, 22 Mar 2015, Robert Jarzmik wrote:

> From: Robert Jarzmik 
> 
> Convert pxa_camera to dmaengine. This removes all DMA registers
> manipulation in favor of the more generic dmaengine API.
> 
> The functional level should be the same as before. The biggest change is
> in the videobuf_sg_splice() function, which splits a videobuf-dma into

As also commented below, I'm not sure "splice" is a good word for 
splitting.

> several scatterlists for 3 planes captures (Y, U, V).

"Several" is actually exactly 3, isn't it?

> 
> Signed-off-by: Robert Jarzmik 
> ---
>  drivers/media/platform/soc_camera/pxa_camera.c | 428 
> -
>  1 file changed, 211 insertions(+), 217 deletions(-)
> 
> diff --git a/drivers/media/platform/soc_camera/pxa_camera.c 
> b/drivers/media/platform/soc_camera/pxa_camera.c
> index 8b39f44..8644022 100644
> --- a/drivers/media/platform/soc_camera/pxa_camera.c
> +++ b/drivers/media/platform/soc_camera/pxa_camera.c
> @@ -28,6 +28,9 @@
>  #include 
>  #include 
>  #include 
> +#include 
> +#include 
> +#include 
>  
>  #include 
>  #include 
> @@ -38,7 +41,6 @@
>  
>  #include 
>  
> -#include 
>  #include 
>  
>  #define PXA_CAM_VERSION "0.0.6"
> @@ -175,21 +177,16 @@ enum pxa_camera_active_dma {
>   DMA_V = 0x4,
>  };
>  
> -/* descriptor needed for the PXA DMA engine */
> -struct pxa_cam_dma {
> - dma_addr_t  sg_dma;
> - struct pxa_dma_desc *sg_cpu;
> - size_t  sg_size;
> - int sglen;
> -};
> -
>  /* buffer for one video frame */
>  struct pxa_buffer {
>   /* common v4l buffer stuff -- must be first */
>   struct videobuf_buffer  vb;
>   u32 code;
>   /* our descriptor lists for Y, U and V channels */
> - struct pxa_cam_dma  dmas[3];
> + struct dma_async_tx_descriptor  *descs[3];
> + dma_cookie_tcookie[3];
> + struct scatterlist  *sg[3];
> + int sg_len[3];
>   int inwork;
>   enum pxa_camera_active_dma  active_dma;
>  };
> @@ -207,7 +204,7 @@ struct pxa_camera_dev {
>   void __iomem*base;
>  
>   int channels;
> - unsigned intdma_chans[3];
> + struct dma_chan *dma_chans[3];
>  
>   struct pxacamera_platform_data *pdata;
>   struct resource *res;
> @@ -222,7 +219,6 @@ struct pxa_camera_dev {
>   spinlock_t  lock;
>  
>   struct pxa_buffer   *active;
> - struct pxa_dma_desc *sg_tail[3];
>   struct tasklet_struct   task_eof;
>  
>   u32 save_cicr[5];
> @@ -259,7 +255,6 @@ static int pxa_videobuf_setup(struct videobuf_queue *vq, 
> unsigned int *count,
>  static void free_buffer(struct videobuf_queue *vq, struct pxa_buffer *buf)
>  {
>   struct soc_camera_device *icd = vq->priv_data;
> - struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
>   struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb);
>   int i;
>  
> @@ -276,41 +271,82 @@ static void free_buffer(struct videobuf_queue *vq, 
> struct pxa_buffer *buf)
>   if (buf->vb.state == VIDEOBUF_NEEDS_INIT)
>   return;
>  
> - for (i = 0; i < ARRAY_SIZE(buf->dmas); i++) {
> - if (buf->dmas[i].sg_cpu)
> - dma_free_coherent(ici->v4l2_dev.dev,
> -   buf->dmas[i].sg_size,
> -   buf->dmas[i].sg_cpu,
> -   buf->dmas[i].sg_dma);
> - buf->dmas[i].sg_cpu = NULL;
> + for (i = 0; i < 3 && buf->descs[i]; i++) {
> + async_tx_ack(buf->descs[i]);
> + dmaengine_tx_release(buf->descs[i]);
> + kfree(buf->sg[i]);
> + buf->descs[i] = NULL;
> + buf->sg[i] = NULL;
> + buf->sg_len[i] = 0;
>   }
>   videobuf_dma_unmap(vq->dev, dma);
>   videobuf_dma_free(dma);
>  
>   buf->vb.state = VIDEOBUF_NEEDS_INIT;
> +
> + dev_dbg(icd->parent, "%s end (vb=0x%p) 0x%08lx %d\n", __func__,
> + &buf->vb, buf->vb.baddr, buf->vb.bsize);
>  }
>  
> -static int calculate_dma_sglen(struct scatterlist *sglist, int sglen,
> -int sg_first_ofs, int size)
> +static struct scatterlist *videobuf_sg_splice(struct scatterlist *sglist,
> +   int sglen, int offset, int size,
> +   int *new_sg_len)
>  {
> - int i, offset, dma_len, xfer_len;
> - struct scatterlist *sg;
> + struct scatterlist *sg0, *sg, *sg_first = NULL;
> + int i, dma_len, dropped_xfer_len, dropped_remain, remain;
> + int nfirst = -1, nfirst_offset = 0, xfer_len;
>  
> - offset = sg_first_ofs;
> + *new_sg_len = 0;
> + dropped_remain = offset;
> + remain = size;
>   for_each_sg(sgli

  1   2   3   4   5   6   >