chardev: fix race conditions for concurrent rd/wr

This is a long-standing bug, when more than one process access
concurrently the char devices. This adds proper locking and solved the
problem.

Also, a new policy for writing control is in place: if you write
control, any partial block (unless empty) is pushed to the pipeline.
This matches the idea that after write(2) accepts data, it cannot be lost.

Signed-off-by: Alessandro Rubini <rubini@gnudd.com>
Acked-by: Federico Vaga <federico.vaga@gmail.com>
core: add support to interleaving

If a cset->flags has ZIO_CSET_INTERLEAVE_ONLY or
ZIO_CSET_CHAN_INTERLEAVE, then ZIO creates an additional channel in
the cset: the interleaved channel.  As for normal channels, the
interleaved channel has 2 char device:

/dev/zio/devname-0-i-ctrl
/dev/zio/devname-0-i-data

If cset flags include ZIO_CSET_INTERLEAVE_ONLY, ZIO creates only
interleaved channel char devices. From the sysfs you can
enable/disable only the interleaved channel; all the other channels
are always disabled.

If cset flags include ZIO_CSET_CHAN_INTERLEAVE, ZIO creates all char
devices for normal channels and also for the interleaved channel. By
default the interleaved channel is disabled. You can enable the
interleaved channel from sysfs; this choice automatically disable all
the other channels.

Interleave support is needed for the fmc-adc-100ms-14b-4cha driver.
Maybe this is not the final approach to interleave, but it is
working and well-tested, so the time is ripe to have it in master.

Maybe we'll change some details about interleave support, in the
future.

Signed-off-by: Federico Vaga <federico.vaga@gmail.com>
Acked-by: Alessandro Rubini <rubini@gnudd.com>
zzero: add support for interleaving

Zero is the testing tool for zio features, and a show case for driver
writers (the "simple" one is zio-mini). So, now that the core supports
interleave, zio-zero should do as well.

Signed-off-by: Federico Vaga <federico.vaga@gmail.com>
Acked-by: Alessandro Rubini <rubini@gnudd.com>
trigger: new trigger operation arm to handle trigger arming

This commit adds a new trigger operation: arm.  The operation is
useful because it allows a trigger to define its own procedure to arm
itself. It is used by the fmc-adc-100Ms-14bit-4cha driver.

At the moment, nobody use the trigger operation data_done() and abort()
because the generic one work in most of the case, and tipically there
is nothing special to do if the arming procedure is always the same.
This patch make sense of these operations because if you need a custom
arm(), probably, you also need a custom data_done() and abort().

Signed-off-by: Federico Vaga <federico.vaga@gmail.com>
Acked-by: Alessandro Rubini <rubini@gnudd.com>
zio-buf-vmalloc: allow size changes, when not mapped

The commits allows the vmalloc buffer to change the allocated size.
If mmap is active, it returns EBUSY, but we need to protect
against new maps to appear during the change. The vm_ops->open
method returns void, so we need to block the mmap() system call
directly, in chardev.c.

Signed-off-by: Alessandro Rubini <rubini@gnudd.com>
Acked-by: Federico Vaga <federico.vaga@gmail.com>